Skip to main content

vLLM — Shutdown & Cleanup

4.1 Signal Handling

SignalHandlerLocationBehavior
SIGTERMsignal_handler()api_server.py:setup_server() (line ~567)Raises KeyboardInterrupt to interrupt uvicorn during initialization
SIGTERMInternal shutdownEngineCoreProc._perform_handshakes()Triggers graceful shutdown of engine core process
KeyboardInterruptUvicorn defaultStops 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)

  1. Cancel stats logging task (server_utils.py:lifespan() finally block)
  2. Delete app.state to release engine references — triggers Python GC and AsyncLLM.__del__()

AsyncLLM Shutdown (async_llm.py:shutdown(), line 259)

  1. Call shutdown_prometheus() — cleanup Prometheus multiprocess directory
  2. Call renderer.shutdown() — stop any active renderers
  3. Call engine_core.shutdown(timeout=timeout) — graceful engine core termination

Engine Core Shutdown (core.py:shutdown(), line 571)

  1. Set shutdown_state = EngineShutdownState.REQUESTED
  2. Call model_executor.shutdown() — stop all worker processes
  3. 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:

  1. Check shutdown_state — if RUNNING, continue
  2. If REQUESTED:
    • Read shutdown_timeout from vllm_config
    • If timeout == 0: immediate termination
    • Otherwise: reject new requests (_reject_add_in_shutdown())
    • Set state to SHUTTING_DOWN
  3. Wait for in-flight requests to complete (up to timeout)
  4. Proceed with full shutdown

CoreEngineProcManager Shutdown (utils.py:shutdown(), line 193)

  1. Send shutdown signal to engine core process
  2. Join process with timeout
  3. Force-kill if process doesn't exit within timeout

MultiprocExecutor Worker Shutdown

  1. Send shutdown message via control queue
  2. Each worker:
    • Destroys NCCL process groups (destroy_distributed_environment())
    • Destroys model parallel state (destroy_model_parallel())
    • Releases GPU memory (PyTorch CUDA cache clear)
  3. Join worker processes with timeout

4.3 Resource Cleanup Inventory

ResourceCleanup MethodLocation
GPU KV cacheFreed with model executor shutdowncore.py:574model_executor.shutdown()
NCCL process groupsdestroy_distributed_environment()multiproc_executor.py
Model parallel groupsdestroy_model_parallel()multiproc_executor.py
ZMQ socketsClosed on process exitcore_client.pyclose_sockets()
Multiprocessing queuesq.close()async_llm.py:630, 850
Prometheus temp dirAuto-cleaned by TemporaryDirectoryprometheus.py:setup_multiprocess_prometheus()
CUDA graphsReleased with model executorgpu_model_runner.py
Server socketClosed by uvicorn on exitapi_server.py
AsyncIO tasksCancelled in lifespan finally blockserver_utils.py:lifespan()
App state (engine refs)del app.state in lifespan finallyserver_utils.py:lifespan()
CUDA memoryPyTorch CUDA cache clearing on process exitWorker process cleanup