> For clean Markdown content of this page, append .md to this URL. For the complete documentation index, see https://docs.nvidia.com/dynamo/latest/llms.txt. For section-specific indexes, append /llms.txt to any section URL.

# Event Plane

The event plane provides Dynamo with a pub/sub layer for near real-time event exchange between components. It delivers KV cache updates, worker load metrics, and sequence tracking events, enabling features like KV-aware routing and disaggregated serving.

## When Is the Event Plane Used?

Key use cases:

- **KV cache events** -- Workers publish cache state so the router can make cache-aware scheduling decisions.
- **Worker load metrics** -- Workers report utilization so the router can balance load.
- **Sequence tracking** -- Coordinates active sequences across router replicas for fault-tolerant routing.

![Event plane architecture showing NATS and ZMQ transport options connecting Frontend, Planner, and Worker](https://fdr-prod-docs-files-public.s3.us-east-1.amazonaws.com/dynamo.docs.buildwithfern.com/712e7d02a897573d522012e7d5a53df187b4af405198970cb526cc0ce89947e0/pages-v1.3.0/assets/img/event-plane-transport.svg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIA6KXJSKKNFOCF7G4B%2F20260726%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20260726T030629Z&X-Amz-Expires=604800&X-Amz-Signature=9622dfb7a4f39875b6d3b0a7e19a33a14c223442db0a752a2dde6bd94a252b4a&X-Amz-SignedHeaders=host&x-amz-checksum-mode=ENABLED&x-id=GetObject)

## Choosing a Transport

The event plane supports two transports:

| | ZMQ (default) | NATS |
|---|---|---|
| **External infrastructure** | None (peer-to-peer) | Requires a NATS server |
| **Setup complexity** | Automatic -- workers bind sockets and register via discovery | Simple -- point at a NATS server |

## Configuration

### Transport Selection

Set the `DYN_EVENT_PLANE` environment variable to choose a transport:

```bash
# Use ZMQ (default -- no need to set explicitly)
export DYN_EVENT_PLANE=zmq

# Use NATS (opt-in)
export DYN_EVENT_PLANE=nats
```

Python components also accept this as a CLI flag:

```bash
# SGLang backend
python3 -m dynamo.sglang --event-plane zmq --model Qwen/Qwen3-0.6B

# vLLM backend
python3 -m dynamo.vllm --event-plane zmq --model Qwen/Qwen3-0.6B
```

### Environment Variables

| Variable | Description | Default |
|----------|-------------|---------|
| `DYN_EVENT_PLANE` | Transport: `nats` or `zmq` | `zmq` (all backends) |
| `NATS_SERVER` | NATS server URL (NATS transport only) | `nats://localhost:4222` |

When `DYN_EVENT_PLANE` is not set, the default is **zmq**. Set `DYN_EVENT_PLANE=nats`
to opt into the NATS transport.

## NATS Transport

When using NATS (`DYN_EVENT_PLANE=nats`):

- Requires a running NATS server. Set `NATS_SERVER` if it is not on `localhost:4222`.
- Events are published to NATS subjects scoped by namespace and component.
- Built-in reconnection and message buffering during brief disconnections.

Example setup:

```bash
export NATS_SERVER=nats://nats-server:4222
export DYN_EVENT_PLANE=nats

# Start workers -- explicitly enable KV event publishing
python3 -m dynamo.vllm --model Qwen/Qwen3-0.6B \
    --kv-events-config '{"publisher":"nats","topic":"kv-events","enable_kv_cache_events":true}'

# Start frontend -- it subscribes to events from NATS automatically
python3 -m dynamo.frontend --router-mode kv
```

## ZMQ Transport

When using ZMQ (`DYN_EVENT_PLANE=zmq`):

- No external server required. Each worker binds a ZMQ PUB socket and advertises its address through the discovery system.
- Subscribers automatically discover and connect to all active publishers.
- When publishers come and go (e.g., workers scaling up/down), subscribers dynamically adjust their connections.

Example setup:

```bash
export DYN_EVENT_PLANE=zmq

# Start workers -- each binds a ZMQ socket, registers with discovery
python3 -m dynamo.vllm --model Qwen/Qwen3-0.6B \
  --kv-events-config '{"publisher":"zmq","endpoint":"tcp://*:20080","enable_kv_cache_events":true}'

# Start frontend -- discovers workers and connects directly
python3 -m dynamo.frontend --router-mode kv
```

## Disabling the Event Plane

If you do not need KV-aware routing, you can disable the event plane entirely:

```bash
python3 -m dynamo.frontend --router-mode kv --no-router-kv-events
```

With `--no-router-kv-events`:

- The router falls back to prediction-based cache-aware routing (estimates cache state from routing decisions).
- No NATS server or ZMQ sockets are needed.
- TTL-based expiration keeps predicted state from growing stale.

## Deployment Modes

### Bare Metal / Local

Both transports work out of the box:

```bash
# NATS (requires nats-server running)
export NATS_SERVER=nats://localhost:4222

# OR ZMQ (no extra infrastructure)
export DYN_EVENT_PLANE=zmq
```

### Kubernetes (with Dynamo Operator)

The operator can inject `DYN_EVENT_PLANE` into pods. The same transport options apply. If using NATS, deploy a NATS server in the cluster and set `NATS_SERVER` accordingly.

## Related Documentation

- [Discovery Plane](/dynamo/design-docs/communication-planes/discovery-plane) -- Service discovery and coordination (etcd, Kubernetes)
- [Distributed Runtime](/dynamo/design-docs/distributed-runtime) -- Runtime architecture
- [Request Plane](/dynamo/design-docs/communication-planes/request-plane) -- Request transport configuration
- [Fault Tolerance](/dynamo/user-guides/fault-tolerance) -- Failure handling