Cache-Aware Routing¶
Cache-aware routing is SMG's most sophisticated load balancing policy. It maintains a multi-tenant radix tree that mirrors backend KV cache state, enabling perfect cache prediction and optimal worker selection.
Overview¶
Radix Tree Mirroring¶
SMG maintains an exact replica of each backend's KV cache structure, enabling 100% accurate prefix match calculations.
Backend Synchronization¶
Uses the same tokens, page sizes, and eviction policies as backend schedulers (SGLang, vLLM, TensorRT-LLM).
Intelligent Load Balancing¶
Automatically switches between cache affinity and load-based routing based on real-time worker state.
Dramatic TTFT Reduction¶
Achieves 70-75% reduction in Time to First Token through optimal KV cache reuse.
Why Cache-Aware Routing?¶
LLM inference workers maintain a KV cache of previously computed attention states. When a new request shares a prefix with a previous request, the worker can skip recomputing that portion—dramatically reducing latency.
Multi-Turn Conversations¶
Same system prompt across turns. Growing context benefits from cached prefixes.
RAG Applications¶
Common document snippets. Shared retrieval prefixes across queries.
Batch Processing¶
Similar prompts in sequence. Template-based generation with variable suffixes.
Shared System Prompts¶
Multiple users with same instructions. Amortized prefill cost across sessions.
The Challenge: If requests with shared prefixes go to different workers, each worker must recompute the same prefix independently—wasting GPU cycles.
Cache-Aware Solution: Route requests to workers that already have the relevant prefix cached, maximizing KV cache hits and minimizing redundant computation.
Multi-Tenant Radix Tree Architecture¶
SMG maintains a multi-tenant radix tree that mirrors the KV cache state on each backend worker. This enables true cache-aware routing with 100% prefix match accuracy.
100% Backend Synchronization¶
The gateway's radix tree uses the exact same parameters as backend schedulers:
- Same tokens: Pre-tokenized input matches backend representation
- Same page size: Aligned to kernel page boundaries (e.g., 16 tokens for FlashInfer)
- Same eviction policy: LRU, LFU, FIFO, MRU, FILO, or Priority
Two Tree Implementations¶
| Tree Type | Mode | Input | Use Case |
|---|---|---|---|
| StringTree | HTTP | Raw text | OpenAI-compatible endpoints |
| TokenTree | gRPC | Token IDs | Direct worker communication |
Why This Matters:
- Perfect Cache Prediction: Since the gateway tree mirrors backend behavior exactly, prefix match calculations are 100% accurate
- Kernel-Aware: Honors page boundaries used by inference kernels (FlashInfer, Mamba, etc.)
- Eviction Parity: Tracks the same eviction policy as SGLang/vLLM/TensorRT-LLM schedulers
Routing Algorithm¶
Two-State Decision Model¶
Cache-aware routing operates in two states based on system load:
Balanced State (Cache-Affinity Mode)¶
When workers are evenly loaded:
- Search radix tree for longest matching prefix
- If match ratio >
cache-threshold→ route to matched worker - If match ratio ≤ threshold → route to least-loaded healthy worker
Goal: Maximize KV cache hit rate
Imbalanced State (Load-Balance Mode)¶
When load difference exceeds thresholds:
- Calculate load difference:
max_load - min_load - Calculate load ratio:
max_load / min_load - If both exceed thresholds → route to least loaded worker
Goal: Prevent worker overload
Imbalance Detection¶
The system is considered imbalanced when both conditions are met:
| Parameter | Default | Description |
|---|---|---|
balance_abs_threshold | 64 | Absolute load difference threshold |
balance_rel_threshold | 1.5 | Relative load ratio threshold (1.5 = 50% difference) |
Selection Flow¶
Performance Impact¶
Benchmarks¶
In typical conversational workloads:
| Metric | Without Cache-Aware | With Cache-Aware | Improvement |
|---|---|---|---|
| TTFT (p50) | 150ms | 45ms | 70% |
| TTFT (p99) | 800ms | 200ms | 75% |
| Cache hit rate | 0% | 65% | - |
| GPU utilization | 85% | 70% | 18% reduction |
Results vary based on workload
Workloads with diverse, unique prompts will see smaller improvements. Workloads with repeated prefixes (chatbots, RAG) see the largest gains.
When Cache-Aware Helps Most¶
High Impact¶
- Multi-turn conversations with shared system prompts
- RAG applications with common document prefixes
- Batch processing with template-based prompts
- Multiple users with identical instructions
Lower Impact¶
- Completely random, unique prompts
- Single-turn diverse queries
- Very short prompts (< 50 tokens)
- Highly variable system prompts
Tuning Guidelines¶
Cache Threshold¶
The cache-threshold parameter controls how aggressively routing favors cache affinity:
| Value | Behavior | Use Case |
|---|---|---|
| Low (0.1-0.2) | More cache hits, potential hot spots | Conversational workloads |
| Default (0.3) | Balanced approach | Most deployments |
| High (0.5-0.8) | Fewer cache hits, better load balance | Diverse workloads |
Recommendation
Start with the default (0.3) and increase if you observe hot spots or uneven load distribution.
Balance Thresholds¶
| Scenario | Recommendation |
|---|---|
| Homogeneous workers | Higher thresholds (favor caching) |
| Heterogeneous workers | Lower thresholds (favor load balance) |
| Bursty traffic | Lower thresholds (prevent queuing) |
| Steady traffic | Higher thresholds (maximize cache hits) |
Memory Management¶
The radix tree grows with unique prefixes. Configure based on your memory budget:
| Memory Budget | max-tree-size | Unique Prefixes |
|---|---|---|
| 1 GB | 16,777,216 | ~16M nodes |
| 4 GB | 67,108,864 | ~64M nodes (default) |
| 16 GB | 268,435,456 | ~256M nodes |
Eviction: SMG periodically evicts stale entries using LRU policy. Configure with --eviction-interval (default: 120 seconds).
Monitoring¶
Key Metrics¶
| Metric | Description | Alert Threshold |
|---|---|---|
smg_worker_requests_active | Active requests per worker | Imbalance >50% |
smg_worker_selection_total | Worker selection count | - |
smg_router_request_duration_seconds | End-to-end request latency | - |
smg_router_ttft_seconds | Time to first token (gRPC only) | - |
Useful PromQL Queries¶
Alert Thresholds¶
| Metric | Warning | Critical | Action |
|---|---|---|---|
| Load imbalance | >30% | >50% | Lower balance thresholds |
| TTFT p99 | >500ms | >1s | Review workload patterns and cache policy |
Multi-Gateway Considerations¶
When running multiple SMG instances behind a load balancer:
- Each instance maintains its own radix tree
- Cache efficiency drops by 10-20% compared to single instance
- Consider session affinity at the load balancer to improve cache hits
Load Balancer Configuration¶
Event-Driven Block Size¶
By default, SMG uses the --block-size CLI flag (default: 16) to align the radix tree with backend KV cache page boundaries. However, when workers report KV cache events, the cache-aware policy can learn the actual block size directly from those events.
This is especially useful when different backends use different page sizes—rather than requiring a single global flag, each worker's block size is discovered automatically from its event stream. The learned block size takes precedence over the CLI default, ensuring routing accuracy without manual configuration per backend.
| Source | Priority | Use Case |
|---|---|---|
| Worker KV events | Highest | Automatically learned per worker |
--block-size flag | Fallback | Global default when events are unavailable |
Note
Event-driven block size detection requires backends that emit KV cache events (e.g., SGLang with event reporting enabled). If a worker does not report events, the --block-size CLI value is used as the fallback.
Mesh State Synchronization¶
When running in mesh HA mode (--enable-mesh), cache-aware routing state is synchronized across all router nodes. Each node's radix tree receives updates from the mesh, ensuring that every gateway instance has a consistent view of backend KV cache state. This eliminates the cache efficiency penalty described in Multi-Gateway Considerations and enables accurate cache-aware decisions across the entire cluster.
For mesh setup and configuration details, see High Availability.
Tip
When using cache-aware routing with mesh HA, KV cache state is automatically synchronized across all nodes. No additional configuration is needed beyond enabling mesh.
Comparison with Other Policies¶
| Aspect | cache_aware | prefix_hash | consistent_hashing |
|---|---|---|---|
| Memory | O(tokens) | O(workers) | O(workers) |
| Lookup | O(prefix_len) | O(log n) | O(log n) |
| Precision | Exact matching | Prefix grouping | Key-based |
| Cache locality | Excellent | Good | Key-dependent |
| Load balancing | Integrated | Load factor | None |