vLLM Explained

Prometheus metrics

Referenceabout 32 min read

Code version: vLLM @ 3e44c0d · 2026-10-22

In one sentence

The API server serves /metrics; the front-end stat logger records the vllm:* values from each batch of engine-core outputs.

Use this page in two ways. To learn the mechanism, read the first four sections. To look up one metric, go to All metrics, or search for its name. The script tools/gen_metrics.py makes the tables from the vLLM source. The text above the tables is written by hand from the code. For what TTFT, ITL and TPOT mean, read Serving metrics: TTFT, TPOT, ITL, throughput, goodput first.

Where /metrics is served#

The API server mounts the endpoint when it registers its routes (vllm/entrypoints/serve/instrumentator/__init__.py:16-18). attach_router does two things:

def attach_router(app: FastAPI):
    """Mount prometheus metrics to a FastAPI app."""
    registry = get_prometheus_registry()

    # `response_class=PrometheusResponse` is needed to return an HTTP response
    # with header "Content-Type: text/plain; version=0.0.4; charset=utf-8"
    # instead of the default "application/json" which is incorrect.
    # See https://github.com/trallnag/prometheus-fastapi-instrumentator/issues/163#issue-1296092364
    Instrumentator(
        excluded_handlers=[
            "/metrics",
            "/health",
            "/load",
            "/ping",
            "/version",
            "/server_info",
        ],
        registry=registry,
    ).add().instrument(app).expose(app, response_class=PrometheusResponse)

    # Add prometheus asgi middleware to route /metrics requests
    metrics_route = Mount("/metrics", make_asgi_app(registry=registry))

    # Workaround for 307 Redirect for /metrics
    metrics_route.path_regex = re.compile("^/metrics(?P<path>.*)$")
    app.routes.append(metrics_route)
  1. Lines 64-74 set up the external library prometheus_fastapi_instrumentator with the registry from get_prometheus_registry(). Its HTTP middleware records http_* metrics for each route, except /metrics, /health and four other routes. Its expose() call also adds a /metrics route of that library.
  2. Line 77 mounts the prometheus_client ASGI app at /metrics, with the same registry. Line 80 lets this mount also match paths below /metrics.

With one API server, the registry is the default prometheus_client registry. With --api-server-count above 1, vllm serve first sets PROMETHEUS_MULTIPROC_DIR to a new temporary folder, if you did not set it (vllm/entrypoints/cli/serve.py:282-283, vllm/v1/metrics/prometheus.py:21-26). Then each API server process writes its values into that folder, and /metrics merges them with a MultiProcessCollector (vllm/v1/metrics/prometheus.py:47-53). For this reason, the gauges declare a multiprocess_mode, for example "mostrecent" (vllm/v1/metrics/loggers.py:526-531).

Which process records the metrics#

The engine core sends its statistics to the front end with its outputs. The front end turns them into Prometheus values:

  1. When stats are on, AsyncLLM makes a StatLoggerManager (vllm/v1/engine/async_llm.py:205-213). The manager always adds a PrometheusStatLogger, unless a custom stat logger is already one (vllm/v1/metrics/loggers.py:1406-1407, vllm/v1/metrics/loggers.py:1416-1419).
  2. The output handler of AsyncLLM gets each batch of EngineCoreOutputs and makes an IterationStats for it (vllm/v1/engine/async_llm.py:880-885). IterationStats takes the front-end clock time.time() when it is made (vllm/v1/metrics/stats.py:477-478).
  3. The output processor fills it. TTFT is that time minus the arrival time of the request (vllm/v1/metrics/stats.py:525-527). ITL is the gap between two engine-core timestamps (vllm/v1/metrics/stats.py:553-558).
  4. The handler calls record() with the scheduler stats of the engine core and the iteration stats (vllm/v1/engine/async_llm.py:929-935). PrometheusStatLogger.record sets the gauges, increments the counters and observes the histograms (vllm/v1/metrics/loggers.py:1138-1166, vllm/v1/metrics/loggers.py:1284-1287).

With more than one API server, the log-line stat logger is off ("to avoid incomplete stats"), but the Prometheus logger stays on (vllm/v1/metrics/loggers.py:1385-1389, vllm/v1/metrics/loggers.py:1416-1419).

Labels: model_name and engine#

Almost every engine metric has two labels (vllm/v1/metrics/loggers.py:499-504):

Some metrics add a third label, for example finished_reason on vllm:request_success. The generated table shows all labels. In the helper classes, for example the speculative decoding and KV connector metrics, a † marks the two labels that the stat logger passes in.

Metrics to put on your dashboard first#

This list is a choice for online serving. The "Exposed as" names are what you query: prometheus_client adds _total to a counter and _bucket, _sum and _count to a histogram.

What you watchMetric (type)Example query
TTFTvllm:time_to_first_token_seconds (histogram, vllm/v1/metrics/loggers.py:931)histogram_quantile(0.99, sum by (le) (rate(vllm:time_to_first_token_seconds_bucket[5m])))
ITLvllm:inter_token_latency_seconds (histogram, vllm/v1/metrics/loggers.py:941)as above, with _bucket of this metric
TPOT per requestvllm:request_time_per_output_token_seconds (histogram, vllm/v1/metrics/loggers.py:951). Decode time / (output tokens − 1), and 0 for one token (vllm/v1/metrics/stats.py:612-616).as above
E2E latencyvllm:e2e_request_latency_seconds (histogram, vllm/v1/metrics/loggers.py:961)as above
Queue timevllm:request_queue_time_seconds (histogram, vllm/v1/metrics/loggers.py:971). First QUEUED to first SCHEDULED event (vllm/v1/metrics/stats.py:596-597).as above
Requests in the batchvllm:num_requests_running (gauge, vllm/v1/metrics/loggers.py:528)vllm:num_requests_running
Requests in the queuevllm:num_requests_waiting (gauge, vllm/v1/metrics/loggers.py:538). It includes the skipped waiting requests (vllm/v1/metrics/loggers.py:1150-1154).vllm:num_requests_waiting
KV cache usagevllm:kv_cache_usage_perc (gauge, vllm/v1/metrics/loggers.py:620). A fraction: 1 means 100 % (vllm/v1/metrics/loggers.py:621).vllm:kv_cache_usage_perc
Prefix cache hit ratevllm:prefix_cache_hits and vllm:prefix_cache_queries (counters, in tokens, vllm/v1/metrics/loggers.py:662-674)rate(vllm:prefix_cache_hits_total[5m]) / rate(vllm:prefix_cache_queries_total[5m])
Preemptionsvllm:num_preemptions (counter, vllm/v1/metrics/loggers.py:739)rate(vllm:num_preemptions_total[5m])
Token throughputvllm:prompt_tokens and vllm:generation_tokens (counters, vllm/v1/metrics/loggers.py:748, vllm/v1/metrics/loggers.py:799)rate(vllm:generation_tokens_total[1m])
Finished requestsvllm:request_success (counter with finished_reason, vllm/v1/metrics/loggers.py:809)sum by (finished_reason) (rate(vllm:request_success_total[5m]))

Known issues#

--show-hidden-metrics-for-version has no effect#

ObservabilityConfig.show_hidden_metrics is True only when --show-hidden-metrics-for-version names the previous minor version (vllm/config/observability.py:31-36). PrometheusStatLogger stores the value (vllm/v1/metrics/loggers.py:494), but no code in vllm/ reads self.show_hidden_metrics after that. So at this commit, the flag does not show or hide any metric.

The docs describe a different behaviour: a metric deprecated in X.Y is hidden in X.Y+1 and comes back with --show-hidden-metrics-for-version=X.Y (docs/usage/metrics.md:132-136). The code has no hidden metric now. This is a difference between docs and code.

Three deprecated KV offload metrics#

The offloading connector still declares vllm:kv_offload_total_bytes, vllm:kv_offload_total_time and vllm:kv_offload_size as "deprecated legacy transfer metrics" with a transfer_type label (vllm/distributed/kv_transfer/kv_connector/v1/offloading/metrics.py:149-167). It registers them with every offloading connector (vllm/distributed/kv_transfer/kv_connector/v1/offloading/metrics.py:409-433), but observes them only when the offloading spec is a CPUOffloadingSpec (vllm/distributed/kv_transfer/kv_connector/v1/offloading/metrics.py:402, vllm/distributed/kv_transfer/kv_connector/v1/offloading/metrics.py:505-508). Use the new flat metrics of the same connector in the table.

Four KVCR metrics come from outside the repository#

The KVCR tier of the KV offload code names four metrics with constants from the package kvcr, which is not in the repository (vllm/v1/kv_offload/tiering/kvcr/manager.py:15-21). The code adds the prefix vllm: (vllm/v1/kv_offload/tiering/kvcr/manager.py:120-121, vllm/v1/kv_offload/tiering/kvcr/manager.py:124-142). The scan cannot resolve the names, so the table lists only the four source lines.

HTTP and process metrics are not in the table#

The http_* metrics come from prometheus_fastapi_instrumentator (see above). The docs show an example: http_requests_total, http_request_size_bytes, http_response_size_bytes, http_request_duration_highr_seconds and http_request_duration_seconds (docs/design/metrics.md:89-96). The process_* and python_* metrics, if present, come from prometheus_client. Its default registry has these collectors; the multiprocess registry that vllm serve uses with more than one API server does not (vllm/v1/metrics/prometheus.py:47-53). vLLM code does not declare these metrics, so the generated table does not list them.

How to read the tables#

  • Groups follow the file that declares the metric, for example "Engine core (PrometheusStatLogger)" for vllm/v1/metrics/loggers.py. The groups are the tool's choice.
  • Type and labels: counter, gauge or histogram, the label names, and the buckets and bucket family of a histogram. In the tables of the helper classes, a † marks the labels that come from the labelnames parameter. The PrometheusStatLogger metrics have the same two labels without a †.
  • Documentation string is the documentation= text of the metric, quoted as it is. Created only if gives the if conditions around the declaration. Such a metric exists only when the condition is true, for example vllm:lora_requests_info needs a LoRA config.
  • Declared links the line of the name and the constructor call.

All metrics#

128 metric names that start with vllm:, declared in vLLM code: 62 counters, 25 gauges, 41 histograms. The stat loggers use the labels model_name and engine (v1/metrics/loggers.py:499). A † marks these two labels only where a helper class (speculative decoding, performance, KV connectors) gets them through its labelnames parameter. Most PrometheusStatLogger metrics have the same two labels, without a †. 3 metrics are marked deprecated; no metric checks show_hidden_metrics at this commit.

Not in the table: 4 names this scan cannot resolve (they come from code outside the repo): _vllm_metric_name(DURATION_METRIC) (v1/kv_offload/tiering/kvcr/manager.py:126); _vllm_metric_name(TRANSFER_BYTES_METRIC) (v1/kv_offload/tiering/kvcr/manager.py:130); _vllm_metric_name(TRANSFER_BLOCKS_METRIC) (v1/kv_offload/tiering/kvcr/manager.py:134); _vllm_metric_name(STATE_METRIC) (v1/kv_offload/tiering/kvcr/manager.py:138).

Engine core (PrometheusStatLogger) (43)#

MetricType and labelsDocumentation stringDeclared
vllm:num_requests_runninggauge
labels: model_name, engine
Number of requests in model execution batches.name
v1/metrics/loggers.py:527
vllm:num_requests_waitinggauge
labels: model_name, engine
Number of requests waiting to be processed.name
v1/metrics/loggers.py:537
vllm:num_requests_waiting_by_reasongauge
labels: model_name, engine, reason
Number of waiting requests by reason. Reason labels: 'capacity' = waiting for scheduling capacity; 'deferred' = deferred by transient constraints (LoRA budget, KV transfer, blocked status). Sum of all reasons equals vllm:num_requests_waiting.name
v1/metrics/loggers.py:547
vllm:num_requests_kv_fetch_by_stagegauge
labels: model_name, engine, stage
Number of waiting requests by async KV load stage. Stage labels: 'waiting_to_start' = needs an async KV load that has not started; 'in_progress' = load started and not yet reported finished; 'completed_waiting' = load finished, request not running yet.
Created only if kv_transfer_config is not None and kv_transfer_config.is_kv_consumer.
name
v1/metrics/loggers.py:572
vllm:engine_sleep_stategauge
labels: model_name, engine, sleep_state
Engine sleep state; awake = 0 means engine is sleeping; awake = 1 means engine is awake; weights_offloaded = 1 means sleep level 1; discard_all = 1 means sleep level 2.name
v1/metrics/loggers.py:593
vllm:kv_cache_usage_percgauge
labels: model_name, engine
KV-cache usage. 1 means 100 percent usage.name
v1/metrics/loggers.py:619
vllm:corrupted_requests
exposed as vllm:corrupted_requests_total
counter
labels: model_name, engine
Corrupted requests, in terms of total number of requests with NaNs in logits.
Created only if envs.VLLM_COMPUTE_NANS_IN_LOGITS.
name
v1/metrics/loggers.py:630
vllm:watermark_requests
exposed as vllm:watermark_requests_total
counter
labels: model_name, engine, status
Finished requests by watermark status (only with watermark_config).
Created only if vllm_config.watermark_config is not None.
name
v1/metrics/loggers.py:643
vllm:prefix_cache_queries
exposed as vllm:prefix_cache_queries_total
counter
labels: model_name, engine
Prefix cache queries, in terms of number of queried tokens.name
v1/metrics/loggers.py:661
vllm:prefix_cache_hits
exposed as vllm:prefix_cache_hits_total
counter
labels: model_name, engine
Prefix cache hits, in terms of number of cached tokens.name
v1/metrics/loggers.py:672
vllm:external_prefix_cache_queries
exposed as vllm:external_prefix_cache_queries_total
counter
labels: model_name, engine
External prefix cache queries from KV connector cross-instance cache sharing, in terms of number of queried tokens.name
v1/metrics/loggers.py:685
vllm:external_prefix_cache_hits
exposed as vllm:external_prefix_cache_hits_total
counter
labels: model_name, engine
External prefix cache hits from KV connector cross-instance cache sharing, in terms of number of cached tokens.name
v1/metrics/loggers.py:697
vllm:mm_cache_queries
exposed as vllm:mm_cache_queries_total
counter
labels: model_name, engine
Multi-modal cache queries, in terms of number of queried items.name
v1/metrics/loggers.py:713
vllm:mm_cache_hits
exposed as vllm:mm_cache_hits_total
counter
labels: model_name, engine
Multi-modal cache hits, in terms of number of cached items.name
v1/metrics/loggers.py:724
vllm:num_preemptions
exposed as vllm:num_preemptions_total
counter
labels: model_name, engine
Cumulative number of preemption from the engine.name
v1/metrics/loggers.py:738
vllm:prompt_tokens
exposed as vllm:prompt_tokens_total
counter
labels: model_name, engine
Number of prefill tokens processed.name
v1/metrics/loggers.py:747
vllm:prompt_tokens_by_source
exposed as vllm:prompt_tokens_by_source_total
counter
labels: model_name, engine, source
Number of prompt tokens by source.name
v1/metrics/loggers.py:757
vllm:prompt_tokens_cached
exposed as vllm:prompt_tokens_cached_total
counter
labels: model_name, engine
Number of cached prompt tokens (local + external).name
v1/metrics/loggers.py:772
vllm:prompt_tokens_cached_by_source
exposed as vllm:prompt_tokens_cached_by_source_total
counter
labels: model_name, engine, source
Prefix-cache hit tokens by the cache tier that supplied them: device (local HBM), host (offloaded to DRAM), disk, p2p (transferred from another vLLM instance) or external_unspecified. Counted at admission; sums to vllm:prefix_cache_hits + vllm:external_prefix_cache_hits.name
v1/metrics/loggers.py:781
vllm:generation_tokens
exposed as vllm:generation_tokens_total
counter
labels: model_name, engine
Number of generation tokens processed.name
v1/metrics/loggers.py:798
vllm:request_success
exposed as vllm:request_success_total
counter
labels: model_name, engine, finished_reason
Count of successfully processed requests.name
v1/metrics/loggers.py:808
vllm:admission_rejections
exposed as vllm:admission_rejections_total
counter
labels: model_name, reason
Number of admission attempts rejected by a queue limit, by reason.name
v1/metrics/loggers.py:847
vllm:request_prompt_tokens
exposed as vllm:request_prompt_tokens_bucket, vllm:request_prompt_tokens_sum, vllm:request_prompt_tokens_count
histogram
labels: model_name, engine
family "request_tokens": 1-2-5 series up to max_model_len (build_1_2_5_buckets); --custom-histogram-buckets can replace it
Number of prefill tokens processed.name
v1/metrics/loggers.py:864
vllm:request_generation_tokens
exposed as vllm:request_generation_tokens_bucket, vllm:request_generation_tokens_sum, vllm:request_generation_tokens_count
histogram
labels: model_name, engine
family "request_tokens": 1-2-5 series up to max_model_len (build_1_2_5_buckets); --custom-histogram-buckets can replace it
Number of generation tokens processed.name
v1/metrics/loggers.py:874
vllm:iteration_tokens_total
exposed as vllm:iteration_tokens_total_bucket, vllm:iteration_tokens_total_sum, vllm:iteration_tokens_total_count
histogram
labels: model_name, engine
buckets: 1, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384
family "iteration_tokens" (ITERATION_TOKENS_BUCKETS); --custom-histogram-buckets can replace it
Histogram of number of tokens per engine_step.name
v1/metrics/loggers.py:887
vllm:request_max_num_generation_tokens
exposed as vllm:request_max_num_generation_tokens_bucket, vllm:request_max_num_generation_tokens_sum, vllm:request_max_num_generation_tokens_count
histogram
labels: model_name, engine
family "request_tokens": 1-2-5 series up to max_model_len (build_1_2_5_buckets); --custom-histogram-buckets can replace it
Histogram of maximum number of requested generation tokens.name
v1/metrics/loggers.py:897
vllm:request_params_n
exposed as vllm:request_params_n_bucket, vllm:request_params_n_sum, vllm:request_params_n_count
histogram
labels: model_name, engine
buckets: 1, 2, 5, 10, 20
family "request_params_n" (REQUEST_PARAMS_N_BUCKETS); --custom-histogram-buckets can replace it
Histogram of the n request parameter.name
v1/metrics/loggers.py:907
vllm:request_params_max_tokens
exposed as vllm:request_params_max_tokens_bucket, vllm:request_params_max_tokens_sum, vllm:request_params_max_tokens_count
histogram
labels: model_name, engine
family "request_tokens": 1-2-5 series up to max_model_len (build_1_2_5_buckets); --custom-histogram-buckets can replace it
Histogram of the max_tokens request parameter.name
v1/metrics/loggers.py:917
vllm:time_to_first_token_seconds
exposed as vllm:time_to_first_token_seconds_bucket, vllm:time_to_first_token_seconds_sum, vllm:time_to_first_token_seconds_count
histogram
labels: model_name, engine
buckets: 0.001, 0.005, 0.01, 0.02, 0.04, 0.06, 0.08, 0.1, 0.25, 0.5, 0.75, 1.0, 2.5, 5.0, 7.5, 10.0, 20.0, 40.0, 80.0, 160.0, 640.0, 2560.0
family "time_to_first_token" (TIME_TO_FIRST_TOKEN_BUCKETS); --custom-histogram-buckets can replace it
Histogram of time to first token in seconds.name
v1/metrics/loggers.py:930
vllm:inter_token_latency_seconds
exposed as vllm:inter_token_latency_seconds_bucket, vllm:inter_token_latency_seconds_sum, vllm:inter_token_latency_seconds_count
histogram
labels: model_name, engine
buckets: 0.01, 0.025, 0.05, 0.075, 0.1, 0.15, 0.2, 0.3, 0.4, 0.5, 0.75, 1.0, 2.5, 5.0, 7.5, 10.0, 20.0, 40.0, 80.0
family "inter_token_latency" (INTER_TOKEN_LATENCY_BUCKETS); --custom-histogram-buckets can replace it
Histogram of inter-token latency in seconds.name
v1/metrics/loggers.py:940
vllm:request_time_per_output_token_seconds
exposed as vllm:request_time_per_output_token_seconds_bucket, vllm:request_time_per_output_token_seconds_sum, vllm:request_time_per_output_token_seconds_count
histogram
labels: model_name, engine
buckets: 0.01, 0.025, 0.05, 0.075, 0.1, 0.15, 0.2, 0.3, 0.4, 0.5, 0.75, 1.0, 2.5, 5.0, 7.5, 10.0, 20.0, 40.0, 80.0
family "inter_token_latency" (INTER_TOKEN_LATENCY_BUCKETS); --custom-histogram-buckets can replace it
Histogram of time_per_output_token_seconds per request.name
v1/metrics/loggers.py:950
vllm:e2e_request_latency_seconds
exposed as vllm:e2e_request_latency_seconds_bucket, vllm:e2e_request_latency_seconds_sum, vllm:e2e_request_latency_seconds_count
histogram
labels: model_name, engine
buckets: 0.3, 0.5, 0.8, 1.0, 1.5, 2.0, 2.5, 5.0, 10.0, 15.0, 20.0, 30.0, 40.0, 50.0, 60.0, 120.0, 240.0, 480.0, 960.0, 1920.0, 7680.0
family "request_latency" (REQUEST_LATENCY_BUCKETS); --custom-histogram-buckets can replace it
Histogram of e2e request latency in seconds.name
v1/metrics/loggers.py:960
vllm:request_queue_time_seconds
exposed as vllm:request_queue_time_seconds_bucket, vllm:request_queue_time_seconds_sum, vllm:request_queue_time_seconds_count
histogram
labels: model_name, engine
buckets: 0.3, 0.5, 0.8, 1.0, 1.5, 2.0, 2.5, 5.0, 10.0, 15.0, 20.0, 30.0, 40.0, 50.0, 60.0, 120.0, 240.0, 480.0, 960.0, 1920.0, 7680.0
family "request_latency" (REQUEST_LATENCY_BUCKETS); --custom-histogram-buckets can replace it
Histogram of time spent in WAITING phase for request.name
v1/metrics/loggers.py:970
vllm:request_inference_time_seconds
exposed as vllm:request_inference_time_seconds_bucket, vllm:request_inference_time_seconds_sum, vllm:request_inference_time_seconds_count
histogram
labels: model_name, engine
buckets: 0.3, 0.5, 0.8, 1.0, 1.5, 2.0, 2.5, 5.0, 10.0, 15.0, 20.0, 30.0, 40.0, 50.0, 60.0, 120.0, 240.0, 480.0, 960.0, 1920.0, 7680.0
family "request_latency" (REQUEST_LATENCY_BUCKETS); --custom-histogram-buckets can replace it
Histogram of time spent in RUNNING phase for request.name
v1/metrics/loggers.py:980
vllm:request_prefill_time_seconds
exposed as vllm:request_prefill_time_seconds_bucket, vllm:request_prefill_time_seconds_sum, vllm:request_prefill_time_seconds_count
histogram
labels: model_name, engine
buckets: 0.3, 0.5, 0.8, 1.0, 1.5, 2.0, 2.5, 5.0, 10.0, 15.0, 20.0, 30.0, 40.0, 50.0, 60.0, 120.0, 240.0, 480.0, 960.0, 1920.0, 7680.0
family "request_latency" (REQUEST_LATENCY_BUCKETS); --custom-histogram-buckets can replace it
Histogram of time spent in PREFILL phase for request.name
v1/metrics/loggers.py:990
vllm:request_decode_time_seconds
exposed as vllm:request_decode_time_seconds_bucket, vllm:request_decode_time_seconds_sum, vllm:request_decode_time_seconds_count
histogram
labels: model_name, engine
buckets: 0.3, 0.5, 0.8, 1.0, 1.5, 2.0, 2.5, 5.0, 10.0, 15.0, 20.0, 30.0, 40.0, 50.0, 60.0, 120.0, 240.0, 480.0, 960.0, 1920.0, 7680.0
family "request_latency" (REQUEST_LATENCY_BUCKETS); --custom-histogram-buckets can replace it
Histogram of time spent in DECODE phase for request.name
v1/metrics/loggers.py:1000
vllm:request_num_preemptions
exposed as vllm:request_num_preemptions_bucket, vllm:request_num_preemptions_sum, vllm:request_num_preemptions_count
histogram
labels: model_name, engine
buckets: 1, 2, 3, 4, 5, 10, 20
family "request_num_preemptions" (REQUEST_NUM_PREEMPTIONS_BUCKETS); --custom-histogram-buckets can replace it
Histogram of the number of times a request was preempted.name
v1/metrics/loggers.py:1010
vllm:request_prefill_kv_computed_tokens
exposed as vllm:request_prefill_kv_computed_tokens_bucket, vllm:request_prefill_kv_computed_tokens_sum, vllm:request_prefill_kv_computed_tokens_count
histogram
labels: model_name, engine
family "request_tokens": 1-2-5 series up to max_model_len (build_1_2_5_buckets); --custom-histogram-buckets can replace it
Histogram of new KV tokens computed during prefill (excluding cached tokens).name
v1/metrics/loggers.py:1020
vllm:kv_block_lifetime_seconds
exposed as vllm:kv_block_lifetime_seconds_bucket, vllm:kv_block_lifetime_seconds_sum, vllm:kv_block_lifetime_seconds_count
histogram
labels: model_name, engine
buckets: 0.001, 0.002, 0.005, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 30, 60, 120, 300, 600, 1200, 1800
family "kv_cache_residency" (KV_CACHE_RESIDENCY_BUCKETS); --custom-histogram-buckets can replace it
Histogram of KV cache block lifetime from allocation to eviction. Sampled metrics (controlled by --kv-cache-metrics-sample).
Created only if self.kv_cache_metrics_enabled.
name
v1/metrics/loggers.py:1041
vllm:kv_block_idle_before_evict_seconds
exposed as vllm:kv_block_idle_before_evict_seconds_bucket, vllm:kv_block_idle_before_evict_seconds_sum, vllm:kv_block_idle_before_evict_seconds_count
histogram
labels: model_name, engine
buckets: 0.001, 0.002, 0.005, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 30, 60, 120, 300, 600, 1200, 1800
family "kv_cache_residency" (KV_CACHE_RESIDENCY_BUCKETS); --custom-histogram-buckets can replace it
Histogram of idle time before KV cache block eviction. Sampled metrics (controlled by --kv-cache-metrics-sample).
Created only if self.kv_cache_metrics_enabled.
name
v1/metrics/loggers.py:1054
vllm:kv_block_reuse_gap_seconds
exposed as vllm:kv_block_reuse_gap_seconds_bucket, vllm:kv_block_reuse_gap_seconds_sum, vllm:kv_block_reuse_gap_seconds_count
histogram
labels: model_name, engine
buckets: 0.001, 0.002, 0.005, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 30, 60, 120, 300, 600, 1200, 1800
family "kv_cache_residency" (KV_CACHE_RESIDENCY_BUCKETS); --custom-histogram-buckets can replace it
Histogram of time gaps between consecutive KV cache block accesses. Only the most recent accesses are recorded (ring buffer). Sampled metrics (controlled by --kv-cache-metrics-sample).
Created only if self.kv_cache_metrics_enabled.
name
v1/metrics/loggers.py:1067
vllm:lora_requests_infogauge
labels: max_lora, waiting_lora_adapters, running_lora_adapters
Running stats on lora requests.
Created only if vllm_config.lora_config is not None.
name
v1/metrics/loggers.py:1103
vllm:cache_config_infogauge
labels: set at run time: metrics_info.keys()
Information of the LLMEngine CacheConfigname
v1/metrics/loggers.py:1127

Performance estimates (MFU) (3)#

MetricType and labelsDocumentation stringDeclared
vllm:estimated_flops_per_gpu_totalcounter
labels: model_name†, engine†
Estimated number of floating point operations per GPU (for Model Flops Utilization calculations).name
v1/metrics/perf.py:1763
vllm:estimated_read_bytes_per_gpu_totalcounter
labels: model_name†, engine†
Estimated number of bytes read from memory per GPU (for Model Flops Utilization calculations).name
v1/metrics/perf.py:1775
vllm:estimated_write_bytes_per_gpu_totalcounter
labels: model_name†, engine†
Estimated number of bytes written to memory per GPU (for Model Flops Utilization calculations).name
v1/metrics/perf.py:1787

Speculative decoding and diffusion (7)#

MetricType and labelsDocumentation stringDeclared
vllm:diffusion_num_denoising_steps
exposed as vllm:diffusion_num_denoising_steps_total
counter
labels: model_name†, engine†
Number of denoising steps.name
v1/spec_decode/metrics.py:236
vllm:diffusion_num_canvas_positions
exposed as vllm:diffusion_num_canvas_positions_total
counter
labels: model_name†, engine†
Number of canvas positions evaluated.name
v1/spec_decode/metrics.py:236
vllm:diffusion_num_committed_tokens
exposed as vllm:diffusion_num_committed_tokens_total
counter
labels: model_name†, engine†
Number of committed (finalized) tokens.name
v1/spec_decode/metrics.py:236
vllm:spec_decode_num_drafts
exposed as vllm:spec_decode_num_drafts_total
counter
labels: model_name†, engine†
Number of spec decoding drafts.name
v1/spec_decode/metrics.py:236
vllm:spec_decode_num_draft_tokens
exposed as vllm:spec_decode_num_draft_tokens_total
counter
labels: model_name†, engine†
Number of draft tokens.name
v1/spec_decode/metrics.py:236
vllm:spec_decode_num_accepted_tokens
exposed as vllm:spec_decode_num_accepted_tokens_total
counter
labels: model_name†, engine†
Number of accepted tokens.name
v1/spec_decode/metrics.py:236
vllm:spec_decode_num_accepted_tokens_per_pos
exposed as vllm:spec_decode_num_accepted_tokens_per_pos_total
counter
labels: model_name†, engine†, position
Accepted tokens per draft position.
Created only if not is_diffusion.
name
v1/spec_decode/metrics.py:254

KV offloading connector (37)#

MetricType and labelsDocumentation stringDeclared
vllm:kv_offload_config_infogauge
labels: model_name†, engine†, set at run time: self._info_keys
Static configuration of the KV offload managers of this engine instance. The configured offloading spec declares the label names, and each manager fills the values, so a series appears from the first scheduler step of its engine. A manager reports one series for each configuration it holds, and a …name
distributed/kv_transfer/kv_connector/v1/offloading/metrics.py:396
vllm:kv_offload_load_bytes
exposed as vllm:kv_offload_load_bytes_total
counter
labels: model_name†, engine†
Total bytes loaded from offload storage to GPU.name
distributed/kv_transfer/kv_connector/v1/offloading/metrics.py:82
vllm:kv_offload_load_time
exposed as vllm:kv_offload_load_time_total
counter
labels: model_name†, engine†
Total load time from offload storage to GPU, in seconds.name
distributed/kv_transfer/kv_connector/v1/offloading/metrics.py:85
vllm:kv_offload_load_size
exposed as vllm:kv_offload_load_size_bucket, vllm:kv_offload_load_size_sum, vllm:kv_offload_load_size_count
histogram
labels: model_name†, engine†
buckets: 1e6, 5e6, 1e7, 2e7, 4e7, 6e7, 8e7, 1e8, 1.5e8, 2e8
Histogram of KV offload load operation size, in bytes.name
distributed/kv_transfer/kv_connector/v1/offloading/metrics.py:88
vllm:kv_offload_store_bytes
exposed as vllm:kv_offload_store_bytes_total
counter
labels: model_name†, engine†
Total bytes stored from GPU to offload storage.name
distributed/kv_transfer/kv_connector/v1/offloading/metrics.py:92
vllm:kv_offload_store_time
exposed as vllm:kv_offload_store_time_total
counter
labels: model_name†, engine†
Total store time from GPU to offload storage, in seconds.name
distributed/kv_transfer/kv_connector/v1/offloading/metrics.py:95
vllm:kv_offload_store_size
exposed as vllm:kv_offload_store_size_bucket, vllm:kv_offload_store_size_sum, vllm:kv_offload_store_size_count
histogram
labels: model_name†, engine†
buckets: 1e6, 5e6, 1e7, 2e7, 4e7, 6e7, 8e7, 1e8, 1.5e8, 2e8
Histogram of KV offload store operation size, in bytes.name
distributed/kv_transfer/kv_connector/v1/offloading/metrics.py:98
vllm:kv_offload_lookup_sync_delay_seconds
exposed as vllm:kv_offload_lookup_sync_delay_seconds_bucket, vllm:kv_offload_lookup_sync_delay_seconds_sum, vllm:kv_offload_lookup_sync_delay_seconds_count
histogram
labels: model_name†, engine†
buckets: 1e-05, 5e-05, 0.0001, 0.0005, 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1
Histogram of the time spent in a single offload lookup call, in seconds.name
distributed/kv_transfer/kv_connector/v1/offloading/metrics.py:102
vllm:kv_offload_lookup_async_delay_seconds
exposed as vllm:kv_offload_lookup_async_delay_seconds_bucket, vllm:kv_offload_lookup_async_delay_seconds_sum, vllm:kv_offload_lookup_async_delay_seconds_count
histogram
labels: model_name†, engine†
buckets: 0.0001, 0.0005, 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5, 10
Histogram of time between a request's offload lookup first deferring and the following lookup resolving, or request finish, in seconds.name
distributed/kv_transfer/kv_connector/v1/offloading/metrics.py:121
vllm:kv_offload_allocation_failure
exposed as vllm:kv_offload_allocation_failure_total
counter
labels: model_name†, engine†
Number of KV offload store allocation attempts that failed.name
distributed/kv_transfer/kv_connector/v1/offloading/metrics.py:141
vllm:kv_offload_total_bytes (deprecated)
exposed as vllm:kv_offload_total_bytes_total
counter
labels: model_name†, engine†, transfer_type
Number of bytes offloaded by KV connectorname
distributed/kv_transfer/kv_connector/v1/offloading/metrics.py:409
distributed/kv_transfer/kv_connector/v1/offloading/metrics.py:158
vllm:kv_offload_total_time (deprecated)
exposed as vllm:kv_offload_total_time_total
counter
labels: model_name†, engine†, transfer_type
Total time measured by all KV offloading operationsname
distributed/kv_transfer/kv_connector/v1/offloading/metrics.py:417
distributed/kv_transfer/kv_connector/v1/offloading/metrics.py:161
vllm:kv_offload_size (deprecated)
exposed as vllm:kv_offload_size_bucket, vllm:kv_offload_size_sum, vllm:kv_offload_size_count
histogram
labels: model_name†, engine†, transfer_type
buckets: 1e6, 5e6, 1e7, 2e7, 4e7, 6e7, 8e7, 1e8, 1.5e8, 2e8
Histogram of KV offload transfer size, in bytes.name
distributed/kv_transfer/kv_connector/v1/offloading/metrics.py:429
distributed/kv_transfer/kv_connector/v1/offloading/metrics.py:164
vllm:kv_offload_cpu_cache_usage_percgauge
labels: model_name†, engine†
Fraction of CPU KV-cache space currently pinned by active transfers (0.0 = idle, 1.0 = saturated). Sustained high values indicate transfers (stores or promotions) may be dropped due to insufficient capacity.name
v1/kv_offload/cpu/spec.py:55
vllm:kv_offload_cpu_cache_write_usage_percgauge
labels: model_name†, engine†
Fraction of CPU KV-cache space currently pinned by in-flight stores that have not yet completed (0.0 = idle, 1.0 = saturated).name
v1/kv_offload/cpu/spec.py:63
vllm:kv_offload_cpu_cache_read_usage_percgauge
labels: model_name†, engine†
Fraction of CPU KV-cache space currently pinned by in-flight loads that have not yet completed (0.0 = idle, 1.0 = saturated).name
v1/kv_offload/cpu/spec.py:70
vllm:kv_offload_cpu_allocation_size
exposed as vllm:kv_offload_cpu_allocation_size_bucket, vllm:kv_offload_cpu_allocation_size_sum, vllm:kv_offload_cpu_allocation_size_count
histogram
labels: model_name†, engine†
buckets: 1, 4, 16, 64, 256, 1024, 4096, 16384, 65536, 262144
Histogram of the number of CPU chunks requested by each KV offload prepare_store call.name
v1/kv_offload/cpu/spec.py:77
vllm:kv_offload_stores_skipped
exposed as vllm:kv_offload_stores_skipped_total
counter
labels: model_name†, engine†
Number of KV offload stores skipped because the reuse threshold was not reached.
Created only if store_threshold >= 2.
name
v1/kv_offload/cpu/spec.py:88
vllm:kv_offload_tiering_lookup_sync_delay_seconds
exposed as vllm:kv_offload_tiering_lookup_sync_delay_seconds_bucket, vllm:kv_offload_tiering_lookup_sync_delay_seconds_sum, vllm:kv_offload_tiering_lookup_sync_delay_seconds_count
histogram
labels: model_name†, engine†, tier
buckets: 1e-05, 5e-05, 0.0001, 0.0005, 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1
Histogram of blocking time spent in a per-chunk tier lookup that resolved as a hit or miss, labeled by tier, in seconds.name
v1/kv_offload/tiering/spec.py:108
vllm:kv_offload_tiering_lookup_async_delay_seconds
exposed as vllm:kv_offload_tiering_lookup_async_delay_seconds_bucket, vllm:kv_offload_tiering_lookup_async_delay_seconds_sum, vllm:kv_offload_tiering_lookup_async_delay_seconds_count
histogram
labels: model_name†, engine†, tier
buckets: 0.0001, 0.0005, 0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1, 5, 10
Histogram of wall-clock time from a per-chunk tier lookup first returning retry until that same tier lookup resolves as a hit or miss, labeled by tier, in seconds.name
v1/kv_offload/tiering/spec.py:130
vllm:kv_offload_tiering_read_bytes
exposed as vllm:kv_offload_tiering_read_bytes_total
counter
labels: model_name†, engine†, tier
Total bytes read from secondary tiers into the primary tier, labeled by tier.name
v1/kv_offload/tiering/spec.py:152
vllm:kv_offload_tiering_read_time
exposed as vllm:kv_offload_tiering_read_time_total
counter
labels: model_name†, engine†, tier
Total time spent reading from secondary tiers into the primary tier, in seconds, labeled by tier. Tiers that do not report per-job transfer time have no series here. Use vllm:kv_offload_tiering_promotion_latency_seconds for tier-independent promotion timing.name
v1/kv_offload/tiering/spec.py:159
vllm:kv_offload_tiering_write_bytes
exposed as vllm:kv_offload_tiering_write_bytes_total
counter
labels: model_name†, engine†, tier
Total bytes written from the primary tier to secondary tiers, labeled by tier.name
v1/kv_offload/tiering/spec.py:169
vllm:kv_offload_tiering_write_time
exposed as vllm:kv_offload_tiering_write_time_total
counter
labels: model_name†, engine†, tier
Total time spent writing from the primary tier to secondary tiers, in seconds, labeled by tier. Tiers that do not report per-job transfer time have no series here.name
v1/kv_offload/tiering/spec.py:176
vllm:kv_offload_tiering_promotion_job_failures
exposed as vllm:kv_offload_tiering_promotion_job_failures_total
counter
labels: model_name†, engine†, tier
Number of failed secondary-tier promotion jobs, labeled by tier.name
v1/kv_offload/tiering/spec.py:185
vllm:kv_offload_tiering_cascade_job_failures
exposed as vllm:kv_offload_tiering_cascade_job_failures_total
counter
labels: model_name†, engine†, tier
Number of failed secondary-tier cascade jobs, labeled by tier.name
v1/kv_offload/tiering/spec.py:193
vllm:kv_offload_tiering_chunk_queries
exposed as vllm:kv_offload_tiering_chunk_queries_total
counter
labels: model_name†, engine†, tier
Number of chunk lookup queries sent to a tier, labeled by tier.name
v1/kv_offload/tiering/spec.py:200
vllm:kv_offload_tiering_chunk_hits
exposed as vllm:kv_offload_tiering_chunk_hits_total
counter
labels: model_name†, engine†, tier
Number of chunk lookup hits in a tier, labeled by tier.name
v1/kv_offload/tiering/spec.py:206
vllm:kv_offload_tiering_promotion_allocation_failures
exposed as vllm:kv_offload_tiering_promotion_allocation_failures_total
counter
labels: model_name†, engine†
Number of promotion attempts that failed because the primary tier could not allocate space.name
v1/kv_offload/tiering/spec.py:211
vllm:kv_offload_tiering_primary_write_usage_percgauge
labels: model_name†, engine†, tier
Current fraction of primary-tier space used by writes from secondary tiers, labeled by tier.name
v1/kv_offload/tiering/spec.py:219
vllm:kv_offload_tiering_primary_read_usage_percgauge
labels: model_name†, engine†, tier
Current fraction of primary-tier space used by reads to secondary tiers, labeled by tier.name
v1/kv_offload/tiering/spec.py:228
vllm:kv_offload_tiering_active_promotion_jobsgauge
labels: model_name†, engine†, tier
Number of active secondary-tier promotion jobs, labeled by tier.name
v1/kv_offload/tiering/spec.py:237
vllm:kv_offload_tiering_active_cascade_jobsgauge
labels: model_name†, engine†, tier
Number of active secondary-tier cascade jobs, labeled by tier.name
v1/kv_offload/tiering/spec.py:244
vllm:kv_offload_tiering_promotion_latency_seconds
exposed as vllm:kv_offload_tiering_promotion_latency_seconds_bucket, vllm:kv_offload_tiering_promotion_latency_seconds_sum, vllm:kv_offload_tiering_promotion_latency_seconds_count
histogram
labels: model_name†, engine†, tier, result
buckets: 0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10, 30, 60
Histogram of per-job latency for secondary-tier promotion attempts, measured from job creation until the tiering manager observes completion so that tier queueing is included, labeled by tier and result, in seconds. Includes failed attempts.name
v1/kv_offload/tiering/spec.py:251
vllm:kv_offload_tiering_backpressure_store_latency_emagauge
labels: model_name†, engine†, tier
Exponential moving average of store latency for back-pressure detection, in s/MiB.name
v1/kv_offload/tiering/spec.py:282
vllm:kv_offload_tiering_backpressure_stores_dropped
exposed as vllm:kv_offload_tiering_backpressure_stores_dropped_total
counter
labels: model_name†, engine†, tier
Number of store operations dropped due to back-pressure on a secondary tier.name
v1/kv_offload/tiering/spec.py:291
vllm:kv_offload_tiering_backpressure_blocks_dropped
exposed as vllm:kv_offload_tiering_backpressure_blocks_dropped_total
counter
labels: model_name†, engine†, tier
Number of blocks dropped due to back-pressure on a secondary tier.name
v1/kv_offload/tiering/spec.py:300

Simple KV offload (5)#

MetricType and labelsDocumentation stringDeclared
vllm:simple_kv_offload_save_outcomes_totalcounter
labels: model_name†, engine†, outcome
Store admission decisions in SimpleCPUOffloadConnector, by outcome. Outcomes classify eager-mode boundary hand-off stores; lazy-mode stores are not classified.name
v1/simple_kv_offload/metrics.py:185
vllm:simple_kv_offload_load_blocks_totalcounter
labels: model_name†, engine†
KV blocks restored to GPU from the offload pool, counted when a load finishes. This is prefill work avoided through offload cache hits.name
v1/simple_kv_offload/metrics.py:194
vllm:simple_kv_offload_used_blocksgauge
labels: model_name†, engine†
Offload-pool blocks currently pinned by in-flight transfers or cache hits (capacity minus free). Evictable cached blocks are not counted; capacity_blocks is on vllm:simple_kv_offload_info.name
v1/simple_kv_offload/metrics.py:203
vllm:simple_kv_offload_pending_store_blocksgauge
labels: model_name†, engine†
Offload blocks in pending stores: queued for dispatch, issued to workers, or awaiting release after a cache reset. A persistently growing value indicates a stuck transfer.name
v1/simple_kv_offload/metrics.py:214
vllm:simple_kv_offload_infogauge
labels: model_name†, engine†, backend, page_cache, lazy_offload, capacity_blocks
SimpleCPUOffloadConnector deployment facts. Value is always 1. backend is cpu or disk; page_cache and lazy_offload are true/false; capacity_blocks is the offload pool size.name
v1/simple_kv_offload/metrics.py:225

KV connector: NIXL (8)#

MetricType and labelsDocumentation stringDeclared
vllm:nixl_xfer_time_seconds
exposed as vllm:nixl_xfer_time_seconds_bucket, vllm:nixl_xfer_time_seconds_sum, vllm:nixl_xfer_time_seconds_count
histogram
labels: model_name†, engine†
buckets: 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.2, 0.3, 0.5, 0.75, 1.0, 5.0
buckets[1:]
Histogram of transfer duration for NIXL KV Cache transfers.name
distributed/kv_transfer/kv_connector/v1/nixl/stats.py:187
vllm:nixl_post_time_seconds
exposed as vllm:nixl_post_time_seconds_bucket, vllm:nixl_post_time_seconds_sum, vllm:nixl_post_time_seconds_count
histogram
labels: model_name†, engine†
buckets: 0.001, 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.2, 0.3, 0.5, 0.75, 1.0, 5.0
Histogram of transfer post time for NIXL KV Cache transfers.name
distributed/kv_transfer/kv_connector/v1/nixl/stats.py:196
vllm:nixl_bytes_transferred
exposed as vllm:nixl_bytes_transferred_bucket, vllm:nixl_bytes_transferred_sum, vllm:nixl_bytes_transferred_count
histogram
labels: model_name†, engine†
buckets: 2048, 8192, 32768, 131072, 524288, 2097152, 8388608, 33554432, 134217728, 536870912, 2147483648, 8589934592
computed: [2 ** (10 + i) for i in range(1, 25, 2)]
Histogram of bytes transferred per NIXL KV Cache transfers.name
distributed/kv_transfer/kv_connector/v1/nixl/stats.py:208
vllm:nixl_num_descriptors
exposed as vllm:nixl_num_descriptors_bucket, vllm:nixl_num_descriptors_sum, vllm:nixl_num_descriptors_count
histogram
labels: model_name†, engine†
buckets: 10, 20, 30, 50, 75, 100, 200, 400, 1000, 2000, 4000, 10000, 20000, 50000
Histogram of number of descriptors per NIXL KV Cache transfers.name
distributed/kv_transfer/kv_connector/v1/nixl/stats.py:233
vllm:nixl_num_failed_transfers
exposed as vllm:nixl_num_failed_transfers_total
counter
labels: model_name†, engine†
Number of failed NIXL KV Cache transfers, including handshake and notification failures. NOTE: KV expiry is tracked separately in vllm:nixl_num_kv_expired_reqs.name
distributed/kv_transfer/kv_connector/v1/nixl/stats.py:243
vllm:nixl_num_failed_notifications
exposed as vllm:nixl_num_failed_notifications_total
counter
labels: model_name†, engine†
Number of failed NIXL KV Cache notifications. Retained for compatibility; these failures are also included in vllm:nixl_num_failed_transfers.name
distributed/kv_transfer/kv_connector/v1/nixl/stats.py:254
vllm:nixl_num_kv_expired_reqs
exposed as vllm:nixl_num_kv_expired_reqs_total
counter
labels: model_name†, engine†
Number of requests that had their KV expire. NOTE: This metric is tracked on the P instance.name
distributed/kv_transfer/kv_connector/v1/nixl/stats.py:265
vllm:nixl_num_notifications_after_expiry
exposed as vllm:nixl_num_notifications_after_expiry_total
counter
labels: model_name†, engine†
Number of completion notifications for requests that were no longer tracked, usually because their KV lease expired. The KV blocks may have been reused before the transfer finished. Counted per notification (one per remote rank), not per request.name
distributed/kv_transfer/kv_connector/v1/nixl/stats.py:275

KV connector: Mooncake store (5)#

MetricType and labelsDocumentation stringDeclared
vllm:mooncake_store_operation_time_seconds
exposed as vllm:mooncake_store_operation_time_seconds_bucket, vllm:mooncake_store_operation_time_seconds_sum, vllm:mooncake_store_operation_time_seconds_count
histogram
labels: model_name†, engine†, operation, status
buckets: 0.001, 0.005, 0.01, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.75, 1.0, 1.5, 2.0, 3.0, 4.0
Histogram of Mooncake store communication time.name
distributed/kv_transfer/kv_connector/v1/mooncake/store/metrics.py:115
vllm:mooncake_store_operation_totalcounter
labels: model_name†, engine†, operation, status
Number of Mooncake store communication operations.name
distributed/kv_transfer/kv_connector/v1/mooncake/store/metrics.py:137
vllm:mooncake_store_operation_keys_totalcounter
labels: model_name†, engine†, operation, status
Number of Mooncake store keys touched by operations.name
distributed/kv_transfer/kv_connector/v1/mooncake/store/metrics.py:142
vllm:mooncake_store_operation_bytes_totalcounter
labels: model_name†, engine†, operation, status
Number of bytes transferred by Mooncake store operations.name
distributed/kv_transfer/kv_connector/v1/mooncake/store/metrics.py:147
vllm:mooncake_store_operation_failed_keys_totalcounter
labels: model_name†, engine†, operation, status
Number of Mooncake store keys that failed in operations.name
distributed/kv_transfer/kv_connector/v1/mooncake/store/metrics.py:152

KV connector: 3FS (4)#

MetricType and labelsDocumentation stringDeclared
vllm:hf3fs_save_duration_seconds
exposed as vllm:hf3fs_save_duration_seconds_bucket, vllm:hf3fs_save_duration_seconds_sum, vllm:hf3fs_save_duration_seconds_count
histogram
labels: model_name†, engine†
buckets: 0.001, 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.2, 0.3, 0.5, 0.75, 1.0, 5.0
Histogram of save duration for HF3FSKVConnector.name
distributed/kv_transfer/kv_connector/v1/hf3fs/hf3fs_connector.py:1135
vllm:hf3fs_load_duration_seconds
exposed as vllm:hf3fs_load_duration_seconds_bucket, vllm:hf3fs_load_duration_seconds_sum, vllm:hf3fs_load_duration_seconds_count
histogram
labels: model_name†, engine†
buckets: 0.001, 0.005, 0.01, 0.025, 0.05, 0.075, 0.1, 0.2, 0.3, 0.5, 0.75, 1.0, 5.0
Histogram of load duration for HF3FSKVConnector.name
distributed/kv_transfer/kv_connector/v1/hf3fs/hf3fs_connector.py:1145
vllm:hf3fs_num_failed_save
exposed as vllm:hf3fs_num_failed_save_total
counter
labels: model_name†, engine†
Number of failed HF3FS KV save.name
distributed/kv_transfer/kv_connector/v1/hf3fs/hf3fs_connector.py:1155
vllm:hf3fs_num_failed_load
exposed as vllm:hf3fs_num_failed_load_total
counter
labels: model_name†, engine†
Number of failed HF3FS KV load.name
distributed/kv_transfer/kv_connector/v1/hf3fs/hf3fs_connector.py:1164

KV connector: HiSparse (8)#

MetricType and labelsDocumentation stringDeclared
vllm:hisparse_cache_hits
exposed as vllm:hisparse_cache_hits_total
counter
labels: model_name†, engine†
Number of HiSparse device hot-buffer hits.name
distributed/kv_transfer/kv_connector/v1/hisparse/stats.py:102
vllm:hisparse_cache_misses
exposed as vllm:hisparse_cache_misses_total
counter
labels: model_name†, engine†
Number of HiSparse device hot-buffer misses.name
distributed/kv_transfer/kv_connector/v1/hisparse/stats.py:107
vllm:hisparse_host_to_device_bytes
exposed as vllm:hisparse_host_to_device_bytes_total
counter
labels: model_name†, engine†
Bytes transferred from host KV storage to HiSparse hot buffers.name
distributed/kv_transfer/kv_connector/v1/hisparse/stats.py:112
vllm:hisparse_host_cache_usage_percgauge
labels: model_name†, engine†
HiSparse host KV-cache usage. 1 means 100 percent usage. Evictable cached blocks count as free.name
distributed/kv_transfer/kv_connector/v1/hisparse/stats.py:131
vllm:hisparse_pending_page_transfersgauge
labels: model_name†, engine†
HiSparse page transfers (write-backs and restores) not yet completed.name
distributed/kv_transfer/kv_connector/v1/hisparse/stats.py:140
vllm:hisparse_host_block_lifetime_seconds
exposed as vllm:hisparse_host_block_lifetime_seconds_bucket, vllm:hisparse_host_block_lifetime_seconds_sum, vllm:hisparse_host_block_lifetime_seconds_count
histogram
labels: model_name†, engine†
buckets: 0.001, 0.002, 0.005, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 30, 60, 120, 300, 600, 1200, 1800
family "kv_cache_residency" (KV_CACHE_RESIDENCY_BUCKETS); --custom-histogram-buckets can replace it
Histogram of HiSparse host KV block lifetime from allocation to eviction. Sampled metrics (controlled by --kv-cache-metrics-sample).
Created only if vllm_config.observability_config.kv_cache_metrics.
name
distributed/kv_transfer/kv_connector/v1/hisparse/stats.py:163
vllm:hisparse_host_block_idle_before_evict_seconds
exposed as vllm:hisparse_host_block_idle_before_evict_seconds_bucket, vllm:hisparse_host_block_idle_before_evict_seconds_sum, vllm:hisparse_host_block_idle_before_evict_seconds_count
histogram
labels: model_name†, engine†
buckets: 0.001, 0.002, 0.005, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 30, 60, 120, 300, 600, 1200, 1800
family "kv_cache_residency" (KV_CACHE_RESIDENCY_BUCKETS); --custom-histogram-buckets can replace it
Histogram of HiSparse host KV block idle time before eviction. Sampled metrics (controlled by --kv-cache-metrics-sample).
Created only if vllm_config.observability_config.kv_cache_metrics.
name
distributed/kv_transfer/kv_connector/v1/hisparse/stats.py:173
vllm:hisparse_host_block_reuse_gap_seconds
exposed as vllm:hisparse_host_block_reuse_gap_seconds_bucket, vllm:hisparse_host_block_reuse_gap_seconds_sum, vllm:hisparse_host_block_reuse_gap_seconds_count
histogram
labels: model_name†, engine†
buckets: 0.001, 0.002, 0.005, 0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 30, 60, 120, 300, 600, 1200, 1800
family "kv_cache_residency" (KV_CACHE_RESIDENCY_BUCKETS); --custom-histogram-buckets can replace it
Histogram of time gaps between consecutive HiSparse host KV block accesses. Sampled metrics (controlled by --kv-cache-metrics-sample).
Created only if vllm_config.observability_config.kv_cache_metrics.
name
distributed/kv_transfer/kv_connector/v1/hisparse/stats.py:182

API server (8)#

MetricType and labelsDocumentation stringDeclared
vllm:rl_weight_update_operation_duration_seconds
exposed as vllm:rl_weight_update_operation_duration_seconds_bucket, vllm:rl_weight_update_operation_duration_seconds_sum, vllm:rl_weight_update_operation_duration_seconds_count
histogram
labels: operation
buckets: 0.01, 0.1, 1, 10, 30, 60, 120, 300, 600
Duration of one weight-transfer operation.name
entrypoints/rl/online/metrics.py:18
vllm:rl_weight_update_operations_in_flightgauge
labels: operation
Weight-transfer operations currently awaited.name
entrypoints/rl/online/metrics.py:25
vllm:sleep_mode_operation_duration_seconds
exposed as vllm:sleep_mode_operation_duration_seconds_bucket, vllm:sleep_mode_operation_duration_seconds_sum, vllm:sleep_mode_operation_duration_seconds_count
histogram
labels: operation
buckets: 0.01, 0.1, 1, 10, 30, 60, 120, 300, 600
Duration of one sleep-mode operation.name
entrypoints/serve/dev/sleep/metrics.py:20
vllm:sleep_mode_operations_in_flightgauge
labels: operation
Sleep-mode operations currently awaited.name
entrypoints/serve/dev/sleep/metrics.py:27
vllm:websocket_connections_activegauge
labels: none
Number of currently active WebSocket connections.name
entrypoints/speech_to_text/realtime/metrics.py:22
vllm:websocket_connections_totalcounter
labels: none
Total number of WebSocket connections.name
entrypoints/speech_to_text/realtime/metrics.py:28
vllm:websocket_connection_duration_seconds
exposed as vllm:websocket_connection_duration_seconds_bucket, vllm:websocket_connection_duration_seconds_sum, vllm:websocket_connection_duration_seconds_count
histogram
labels: none
buckets: 0.5, 1, 2.5, 5, 10, 30, 60, 120, 300, 600, 1800
Duration of WebSocket connections in seconds.name
entrypoints/speech_to_text/realtime/metrics.py:33
vllm:tool_call_parser_invocations_totalcounter
labels: model_name, mode, outcome, request_type
Total number of ToolParser invocations. Non-streaming increments once per choice; streaming increments once per delta.name
parser/metrics.py:37

Check yourself#

  1. 1
    Your dashboard shows vllm:kv_cache_usage_perc = 0.85. How full is the KV cache?
    easy
    Show answer

    85 %. The gauge is a fraction, and "1 means 100 percent usage" (vllm/v1/metrics/loggers.py:621). The value comes from the scheduler stats of the engine core (vllm/v1/metrics/loggers.py:1165).

  2. 2
    You run vllm serve --served-model-name chat-a chat-b -dp 2. Which label values does vllm:num_requests_running have?
    medium
    Show answer

    model_name="chat-a", because the metrics use the first served name (vllm/config/model.py:2332-2333). engine="0" and engine="1", one series per engine core (vllm/v1/metrics/loggers.py:503-505).

  3. 3
    A deprecated metric disappeared after an upgrade. You add --show-hidden-metrics-for-version with the previous minor version, as the docs say. Does the metric come back?
    hard
    Show answer

    No. The flag sets show_hidden_metrics (vllm/config/observability.py:31-36), and PrometheusStatLogger stores it (vllm/v1/metrics/loggers.py:494), but no metric declaration checks it. A metric that was removed from the code cannot come back with a flag. The docs text (docs/usage/metrics.md:134-136) describes a mechanism that the code does not use at this commit.