Average tokens/sec is not an SLO for LLM serving and will not detect the failure users actually report; the two that matter are TTFT and TPOT
Fields
gotchas/obs-serving-slos-ttft-tpot-not-tok-sNotes
The dashboards people actually run are a useful tell for which metrics have proven their worth. vLLM ships examples/observability/prometheus_grafana/grafana.json whose panels query, at p50/p90/p95/p99: e2e_request_latency_seconds, inter_token_latency_seconds, request_time_per_output_token_seconds and time_to_first_token_seconds, plus rate() panels on prompt_tokens_total and generation_tokens_total, gauges on num_requests_running and num_requests_waiting, kv_cache_usage_perc, prompt- and generation-token histograms, request_success by finish_reason, and rate() on request_queue_time_seconds, request_prefill_time_seconds, request_decode_time_seconds and request_max_num_generation_tokens. SGLang's shipped dashboard (examples/monitoring/grafana/dashboards/json/sglang-dashboard.json) is narrower: e2e_request_latency_seconds and time_to_first_token_seconds at p50/p90/p99, plus gauges sglang_num_running_reqs, sglang_gen_throughput, sglang_cache_hit_rate and sglang_num_queue_reqs. LMDeploy's dashboard mirrors vLLM's almost exactly (same p50/p90/p95/p99 panels plus gpu_cache_usage_perc), which is what you would expect from the same code ancestry. The pattern in all three: latency percentiles lead, throughput counters support, and queue/KV gauges explain. Nobody ships a tok/s-only dashboard. Also worth knowing for the queue-time SLO: a request that never gets admitted still increments your queue-time histogram only if the engine records the wait for completed requests - vLLM's `vllm:request_queue_time_seconds` is 'Histogram of time spent in WAITING phase for request' recorded on completion, so a backlog of abandoned or timed-out requests is invisible to it and shows up only in the gauge.
Cross-references
Affects (16)
- Inference enginesvLLM
- Inference enginesSGLang
- Inference enginesTensorRT-LLM
- Inference enginesLMDeploy (TurboMind)
- Inference enginesText Generation Inference
- Inference enginesTriton Inference Server
- Inference enginesllama.cpp
- Inference enginesOllama
- Inference enginesvLLM (observability surface: Prometheus metrics + OpenTelemetry)
- Inference enginesSGLang (observability surface: Prometheus metrics + OpenTelemetry with per-stage slices)
- Inference enginesTensorRT-LLM (observability surface: Prometheus metrics + OpenTelemetry)
- Inference enginesText Generation Inference (observability surface: no TTFT, no KV cache usage, no tracing spans of its own)
- Inference enginesTriton Inference Server (observability surface: request-shaped core metrics, LLM metrics only if a backend registers them)
- Inference enginesllama.cpp server (observability surface: 14 hand-built Prometheus metrics, off by default, no OTel)
- Inference enginesLMDeploy (observability surface: near-copy of vLLM's metric set, no preemption metric, no OTel)
- Inference enginesOllama (observability surface: none - no /metrics endpoint, no tracing, per-response timing only)