Serving over HTTP: the OpenAI-compatible server & its endpoints¶
Baseline: vLLM 0.26.0 · APIs verified via Context7 (ADR-0004)
Module: Part 8 · Production & System Design · Tests the lesson: Serving vLLM over HTTP: the OpenAI-Compatible Server
Q: How do you serve a vLLM model over HTTP? Walk through vllm serve, its main endpoints, how /v1/chat/completions differs from /v1/completions, what /health does and doesn't guarantee, how auth works, and which flags shape the interface vs the capacity.¶
Direct answer¶
Launch: vllm serve <model> boots the engine and starts a FastAPI/uvicorn frontend speaking the OpenAI API — so any OpenAI client (the openai SDK, LangChain, a chat UI) retargets by changing one line, base_url="http://host:8000/v1".
Endpoints:
/v1/chat/completions— role messages; the server applies the model's chat template. The main endpoint for instruct models./v1/completions— raw text-in/text-out; no template./v1/models— the served id (--served-model-name) + any loaded LoRA adapters./health— liveness: 200 if the engine is alive, 503 if it died. Not readiness, not a load signal./metrics— Prometheus feed (vllm:num_requests_running/num_requests_waiting, KV usage, latency histograms).- Utility:
/ping(SageMaker),/version,/load,/tokenize,/detokenize.
Auth: --api-key KEY (or VLLM_API_KEY); pass it multiple times for key rotation. With no key set, the server is open (any non-empty key passes).
Interface knobs (--host/--port/--uds, --api-key, --served-model-name) shape how clients talk to you; capacity knobs (--max-num-seqs, --max-num-batched-tokens, --max-model-len, --gpu-memory-utilization) shape how much you can serve — the ceiling you go measure.
Deep dive¶
- Frontend vs engine core. The HTTP layer does auth, JSON validation, chat-template rendering, and SSE streaming; the engine core (scheduler + workers) does batching and GPU work. Latency problems live in the engine queue, not FastAPI.
- Chat template.
/v1/chat/completionsapplies the exact special-token formatting the instruct model was tuned on. Sending raw text to/v1/completionsfor an instruct model skips it → out-of-distribution prompt → quiet quality loss. - Streaming.
"stream": trueswitches to Server-Sent Events: the firstdata:chunk lands at ~TTFT, the rest paced by TPOT. This is why streaming makes TTFT user-visible. --served-model-name. Decouples the public id from the checkpoint path; clients must send that id or get model not found.- Liveness ≠ readiness.
/healthsays the process is alive, not that weights are loaded/warm or that there's spare capacity — route readiness and autoscaling off/metrics.
Code¶
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000/v1", api_key="sk-demo-key") # the one line
# chat: server applies the chat template to role messages
r = client.chat.completions.create(model="qwen2.5-7b", # = --served-model-name
messages=[{"role": "user", "content": "hi"}], stream=True) # SSE: first chunk ≈ TTFT
for chunk in r:
print(chunk.choices[0].delta.content or "", end="")
# ops: curl -s localhost:8000/health -> 200 (alive) / 503 (dead)
# curl -s localhost:8000/v1/models -H "Authorization: Bearer sk-demo-key"
Interviewer follow-ups¶
- "Client sends the HF path as
modeland gets not found — why?" →--served-model-nameset the public id to something else; themodelfield must equal the served name. - "Is
/health== ready for traffic?" → No — liveness only (200 alive / 503 dead). Readiness/load come from/metrics(num_requests_waiting). - "
/v1/chat/completionsvs/v1/completions?" → chat applies the template (role messages); completions is raw text. Wrong one for an instruct model quietly hurts quality. - "How do you rotate an API key with no downtime?" → pass
--api-keymultiple times so old and new keys are both valid during the switch. - "No
--api-keyset — is the server secure?" → No, it's open; any non-empty key passes. Bind127.0.0.1or set a key + firewall before exposing0.0.0.0. - "Streaming looks batched, not token-by-token — why?" → an intermediate proxy/LB is buffering the SSE response; disable buffering on that route.
Linked concepts¶
- Lesson: Serving vLLM over HTTP: the OpenAI-Compatible Server
- Related: Trace a request through vLLM's architecture (the engine core behind the frontend), Load-testing & the concurrency knee (measuring the capacity the server exposes), Multi-LoRA serving (the adapters
/v1/modelslists) - Glossary: SLO, Goodput