- the router host
- the network path between router and agents
- the number of agents serving each model
- routing-policy complexity
- inference-engine behavior
- prompt and output sizes
- streaming behavior
- authentication, quotas, logging, metrics, and tracing
Request timing model
A client request passes through several independently measurable phases. The path can include:- network and reverse-proxy time between the client and router
- request parsing, authentication, quota admission, and token estimation
- time in the router’s global request channel
- time waiting for a router forwarding slot
- policy lookup, candidate filtering, and ranking
- time waiting for model capacity
- libp2p communication between router and agent
- agent request parsing and backend proxying
- backend queueing and inference
- response transfer through agent, router, proxy, and client
Latency signals
These values are not interchangeable.
For example:
- TTFT measures the start of model output.
- A non-streaming client sees no output until the full completion is ready.
- SRTT measures from the router to an agent and backend, not from the original client.
- Audit latency includes router handling and stream delivery.
Streaming changes the measurement boundary
Hivenet Router observes streaming and non-streaming requests differently.
A streaming request can therefore have:
- low router SRTT
- low TTFT
- a long total stream duration
- substantial ongoing backend work
Current streaming-capacity behavior
For a non-streaming response, Hivenet Router holds the selected agent’s declared capacity slot until the complete response has been received and parsed. For a streaming response, the current implementation releases:- the selected agent’s declared capacity slot
- the router’s
--max-concurrentforwarding slot
- use a conservative agent
--capacity - monitor engine-level running and waiting requests
- monitor KV-cache pressure, TTFT, ITL, GPU use, and preemptions
- test sustained streams rather than only short request bursts
- do not treat Hivenet Router’s active-request counter as the backend’s authoritative concurrency count
Routing-selection cost
Hivenet Router keeps a model-keyed agent index, so a request does not scan agents serving unrelated models. A per-model policy is also resolved through a model-keyed map. The main selection work happens after those lookups. Let:- the number of tags
- the number of dynamic gates
- how many agents survive each stage
- engine and hardware snapshot reads
- slot-acquisition races
- capacity waits
- failed forwards and redials
Stable tie behavior
Theleast-loaded strategy compares:
Throughput boundaries
For non-streaming local inference, the number of simultaneous forwards is bounded approximately by:
These are separate controls.
Increasing one does not automatically increase throughput when another layer is already the bottleneck.
Approximate throughput relationship
For a stable non-streaming workload:- the GPU is already saturated
- the inference engine queues the additional requests
- TTFT or ITL deteriorates
- prompts become larger
- memory pressure causes preemption
- the router or network path becomes the bottleneck
Backpressure layers
Hivenet Router has several backpressure mechanisms.Global request channel
The HTTP handler submits a pending request to a buffered channel. The default channel capacity is:queue_length field returned by:
- requests waiting for the forwarding semaphore
- per-model capacity waiters
- requests already forwarded to agents
- ongoing backend streams
Global forwarding semaphore
Per-model capacity queue
When eligible agents exist but all declared slots are full, a request can wait in a model-specific FIFO queue. The default depth is:- an agent frees a slot
- a new agent registers for the model
Agent capacity
Each agent advertises:- GPU count
- VRAM
- KV-cache size
- model parameters
- engine scheduler limits
Request and response buffering
Request bodies
Inference request bodies are read and retained in memory before forwarding. The router caches the complete JSON body so it can:- read the top-level model
- estimate tokens
- preserve the original payload
- forward the same bytes to the agent
- long conversations
- large tool schemas
- document-heavy prompts
- base64 images
- base64 audio
- large embedding batches
- large reranking document arrays
Request-body limit
Hivenet Router limits request bodies for/v1/* endpoints to 10 MiB by default:
0 to disable the built-in limit.
A reverse proxy can still enforce a smaller limit before the request reaches Hivenet Router. For example:
Non-streaming responses
A native non-streaming Chat Completions response is buffered:- by the agent after reading the backend response
- by the router after reading the agent response
- before the client receives the completed body
Streaming responses
An SSE response is copied progressively through:Memory characteristics
There is no reliable fixed memory figure per agent or per request. Router memory can grow with:- registered agents
- active and waiting requests
- request-body size
- buffered non-streaming responses
- dynamic API keys
- per-tenant and per-model quota state
- policy documents
- model-specific wait queues
- Prometheus time series
- tracing exports awaiting delivery
- Go goroutines and transport connections
- request-body size
- backend-response buffering
- streaming state
- hardware and engine snapshots
- libp2p connections
- the inference backend itself
Storage and write-path behavior
Hivenet Router avoids a persistent database write for every hot-path counter update. Per-agent universal counters and latency history are updated in process and flushed to persistent BadgerDB:- periodically
- when an agent disconnects
- during graceful shutdown
Audit logging
The router writes one structured audit line after each audited HTTP request. Writes are serialized to prevent concurrent lines from being interleaved. A slow or blocked audit filesystem can therefore contribute to request-tail latency and delay connection reuse. Benchmark the intended audit destination rather than assuming local SSD behavior.Storage inspection
Inspect the current Badger state through:Operational-data freshness
Routing decisions can use live values, sampled values, or values that are temporarily stale.
Engine-scrape failures preserve the last successful engine snapshot.
A value can therefore remain present after it has stopped updating.
Missing dynamic metrics pass policy gates rather than excluding the agent.
Performance-sensitive policies should account for:
- sampling delay
- transport delay
- stale snapshots
- missing-value behavior
- threshold headroom
Observability overhead
Production observability adds work to the request and agent paths.Prometheus
Hivenet Router updates several counters, gauges, and histograms per request. The router also exports Go runtime and process metrics, including series such as:- tenant IDs
- key IDs
- peer IDs
- model IDs
- deployment IDs
- organizations
- machines
- regions
- GPU devices
OpenTelemetry
A traced request can include spans for:- the router HTTP handler
- dispatch
- capacity waiting
- forwarding to the agent
- agent request handling
- forwarding to the backend
Audit logs
Audit logging performs one structured write for every audited request. Load tests that redirect the audit path to a different filesystem from production do not measure the same write behavior.Engine and hardware collection
Agent polling also adds background work:- engine metrics every
500ms - hardware metrics every
2s - routing-signal pushes every
500ms - heartbeats every
5s
Scaling boundaries
One router process
The current router is one coordination and forwarding process. It owns:- the live agent registry
- request and capacity queues
- routing-policy state
- active agent sessions
- the dynamic client-key registry
- in-memory quota state
- transport connections
- observability aggregation
- agent registration
- dynamic keys
- queue state
- request history
- rate-limit buckets
- policy changes made through the administration API
Agents per model
Routing examines only agents registered for the requested model, but it currently copies and sorts that bucket for each selection attempt. A model with many replicas has a different routing cost from a fleet with the same total agent count spread across many models. Benchmark both:Model and policy count
Per-model policy lookup is indexed. However:- policy reload rebuilds the model-to-policy map
- model discovery aggregates registered agents
- administration routing-table responses serialize complete fleet state
- Prometheus series grow with models and agents
Connections and shared NAT
Every agent maintains router transport relationships. Agents behind one egress address also share the router’s:No published fleet ceiling
The current repository does not establish one supported maximum such as:Benchmark tools
The repository contains four performance-related scripts.
These tools are starting points rather than a complete independent load-testing framework.
Run the operational benchmark
The main operational benchmark checks:- public and administration health
- registered and healthy agents
- model discovery
- error handling
- a trivial concurrent workload
- a larger-prompt concurrent workload
- request distribution
- administrator endpoint latency
- slot release after request batches
- trace-derived timing when Tempo is available
OPS_CONCURRENCY controls the number of requests in each concurrent batch.
It does not run that concurrency continuously for a fixed duration.
Include trace timing
Strict CI mode
STRICT=1 makes the script exit with a nonzero status when one of its checks fails.
TEMPO_REQUIRED=1 also fails when Tempo or trace data is unavailable.
Benchmark-harness thresholds
The operational script contains these default evaluation thresholds:
These are script defaults, not Hivenet Router service guarantees.
Override them for the deployment:
Interpret the trace-derived benchmark phases
The benchmark produces several derived measurements.Backend processing
Theforward_to_backend span covers the agent’s backend request.
For a stream, it lasts until the backend stream ends.
Dispatch and policy
The benchmark approximates policy work as:Routing overhead
The script labels this calculation:- client-facing middleware
- authentication and quota checks
- request parsing
- global and per-model waiting
- libp2p transport
- agent request handling
- response transit
- stream proxying outside the backend span
Queue wait
The script’s derivedqueue_wait value measures from the root HTTP span’s start until the dispatch span begins.
That interval can include:
- HTTP middleware
- authentication
- quota admission
- token estimation
- request parsing
- global request-channel delay
- waiting for the forwarding semaphore
queue_wait trace span or:
Run the direct-backend benchmark
Use the model benchmark to create a backend baseline without the Hivenet Router router and agent path:- discovers vLLM pods through Kubernetes
- calls vLLM on localhost through
kubectl exec - tests several prompt and output sizes
- reports total latency
- reports completion tokens divided by total wall-clock time
kubectl execoverhead- request setup
- prompt prefill
- generation
- response serialization
Run sustained traffic
The current sustained-load script contains deployment-specific constants. At the time of this reference, it is configured for:Compare benchmark runs
Compare two operational result files:- hardware
- model
- backend configuration
- agent count
- policy
- keys and quotas
- load generator
- network path
- observability settings
Recommended benchmark method
1
Record the complete environment
Record:
- Hivenet Router commit or release
- router and agent flags
- routing policy
- authentication and quotas
- router CPU and memory
- network topology
- agent count and capacity
- model and quantization
- inference-engine version and flags
- GPU model and count
- tracing and audit configuration
2
Measure the backend directly
Establish direct backend latency and throughput without Hivenet Router.This separates model and engine behavior from router, agent, and network overhead.
3
Warm the deployment
Warm:
- model weights
- CUDA kernels
- caches
- libp2p connections
- authentication sessions
- Prometheus and tracing pipelines
4
Use representative request shapes
Test the prompt, output, tools, modalities, and streaming modes used in production.One ten-token completion does not predict a coding agent, RAG application, or long streamed response.
5
Increase load gradually
Increase:
- request rate
- concurrent requests
- active streams
- agents per model
- policy steps
- prompt and output size
6
Test failure paths
Include:
- one unhealthy agent
- one full agent
- backend HTTP errors
- agent disconnection
- policy fallback
- provider fallback
- router queue saturation
- quota rejection
7
Repeat each run
Run several repetitions and report the distribution across runs.One result can be affected by transient network, scheduler, filesystem, or backend behavior.
8
Publish distributions
Report:
- request count
- success rate
- throughput
- p50, p95, and p99
- minimum and maximum
- queue depth and wait
- router CPU and memory
- backend TTFT and ITL
- errors by code
Suggested test matrix
For streaming, also vary:
- number of simultaneous active streams
- stream duration
- client read speed
- generated tokens
- backend running and waiting requests
Capacity-planning workflow
A practical tuning order is:- Benchmark one backend directly.
- Set a conservative agent capacity.
- Run one Hivenet Router agent with concurrency below that value.
- Increase concurrency until engine queueing or latency deteriorates.
- Reduce capacity to leave operational headroom.
- Add more agents and test routing distribution.
- Tune
--max-concurrent. - Tune per-model
--queue-depth. - Tune
--queue-sizeonly after understanding where requests wait. - Repeat with failure and fallback conditions.
Useful performance queries
Router CPU
Router resident memory
Go heap
Goroutine count
- the global forwarding semaphore
- model capacity
- response completion
- blocked stream writes
Active HTTP requests
P95 router request duration
P95 model-capacity wait
Backend queue depth
Routing failures
Policy fallback rate
Diagnose performance problems
Report benchmark results responsibly
A benchmark result should include enough context to be reproduced. At minimum, publish:- which percentile
- which request type
- which fleet shape
- which backend baseline
- how that overhead was calculated
Next steps
Detailed architecture
Review the request, queue, policy, transport, and storage paths behind these characteristics.
Configuration reference
Tune concurrency, queueing, timeouts, sampling, storage, and agent capacity.
Prometheus metrics
Query router, process, queue, agent, engine, hardware, and tenant performance.
Engine metrics
Measure backend queueing, cache pressure, TTFT, ITL, and throughput.
Latency tracking
Understand SRTT, RTTVAR, and the different streaming and non-streaming boundaries.
Error codes
Diagnose capacity, queue, backend, connection, and timeout failures during load.

