vLLM — Shutdown & Cleanup
4.1 Signal Handling
| Signal | Handler | Location | Behavior |
|---|---|---|---|
| SIGTERM | signal_handler() | api_server.py:setup_server() (line ~567) | Raises KeyboardInterrupt to interrupt uvicorn during initialization |
| SIGTERM | Internal shutdown | EngineCoreProc._perform_handshakes() | Triggers graceful shutdown of engine core process |
| KeyboardInterrupt | Uvicorn default | — | Stops the ASGI server, triggers FastAPI lifespan shutdown |
Note: There is no explicit SIGINT handler — the default Python behavior (KeyboardInterrupt) is relied upon. SIGTERM handling is primarily for clean termination during the initialization phase.
4.2 Shutdown Sequence
API Server Shutdown (FastAPI lifespan)
- Cancel stats logging task (
server_utils.py:lifespan()finally block) - Delete
app.stateto release engine references — triggers Python GC andAsyncLLM.__del__()
AsyncLLM Shutdown (async_llm.py:shutdown(), line 259)
- Call
shutdown_prometheus()— cleanup Prometheus multiprocess directory - Call
renderer.shutdown()— stop any active renderers - Call
engine_core.shutdown(timeout=timeout)— graceful engine core termination
Engine Core Shutdown (core.py:shutdown(), line 571)
- Set
shutdown_state = EngineShutdownState.REQUESTED - Call
model_executor.shutdown()— stop all worker processes - Call
scheduler.shutdown()— cleanup scheduler state
Engine Core Step-Level Shutdown (core.py:_handle_shutdown(), line 1230)
When shutdown is requested during the step loop:
- Check
shutdown_state— ifRUNNING, continue - If
REQUESTED:- Read
shutdown_timeoutfromvllm_config - If timeout == 0: immediate termination
- Otherwise: reject new requests (
_reject_add_in_shutdown()) - Set state to
SHUTTING_DOWN
- Read
- Wait for in-flight requests to complete (up to timeout)
- Proceed with full shutdown
CoreEngineProcManager Shutdown (utils.py:shutdown(), line 193)
- Send shutdown signal to engine core process
- Join process with timeout
- Force-kill if process doesn't exit within timeout
MultiprocExecutor Worker Shutdown
- Send shutdown message via control queue
- Each worker:
- Destroys NCCL process groups (
destroy_distributed_environment()) - Destroys model parallel state (
destroy_model_parallel()) - Releases GPU memory (PyTorch CUDA cache clear)
- Destroys NCCL process groups (
- Join worker processes with timeout
4.3 Resource Cleanup Inventory
| Resource | Cleanup Method | Location |
|---|---|---|
| GPU KV cache | Freed with model executor shutdown | core.py:574 → model_executor.shutdown() |
| NCCL process groups | destroy_distributed_environment() | multiproc_executor.py |
| Model parallel groups | destroy_model_parallel() | multiproc_executor.py |
| ZMQ sockets | Closed on process exit | core_client.py — close_sockets() |
| Multiprocessing queues | q.close() | async_llm.py:630, 850 |
| Prometheus temp dir | Auto-cleaned by TemporaryDirectory | prometheus.py:setup_multiprocess_prometheus() |
| CUDA graphs | Released with model executor | gpu_model_runner.py |
| Server socket | Closed by uvicorn on exit | api_server.py |
| AsyncIO tasks | Cancelled in lifespan finally block | server_utils.py:lifespan() |
| App state (engine refs) | del app.state in lifespan finally | server_utils.py:lifespan() |
| CUDA memory | PyTorch CUDA cache clearing on process exit | Worker process cleanup |