Skip to main content
A Hivenet Router policy defines how the router filters, ranks, retries, and falls back across agents. Policies use YAML and can apply globally or to specific models.

Complete structure

Top-level fields

The models field is ignored for a global policy loaded through:
  • --policy-file
  • _default.yaml
  • PUT /admin/policy
It is required for named per-model policy documents.

Admission control fields

The admission fields are top-level properties of the policy, not fields inside routing_policy. They apply to POST /v1/chat/completions and POST /v1/messages; the count-tokens, embedding, and reranking paths are exempt.
All numeric limits default to 0, which disables the corresponding check. Negative values are rejected. mode defaults to reserved and accepts only reserved or serverless.

mode

reserved enables the shared B1, B2, and B3 safety gates without serverless per-key caps. serverless enables the same safety gates plus the B4 fields resolved from the authenticated key. An empty value is normalized to reserved; any other value is a load-time error.

max_input_tokens and images_max

These are the B1 hard caps. The token check uses the same learned estimate used by occupancy and token quotas. It includes message text, the Anthropic top-level system prompt, and raw tool-definition JSON. The image check counts OpenAI image_url parts and Anthropic image blocks. Either breach returns HTTP 400 input_too_long.

admit_budget_tokens and max_inflight

Both values are per replica. The router recomputes the number of healthy replicas for every request and floors that count at 1:
Over-budget requests may park for HIVENET_ROUTER_ADMIT_PARK_TIMEOUT before the router returns 429 concurrency_limit_exceeded. Existing reservations are not canceled when the healthy pool shrinks; the smaller limit affects new admissions until work completes. Benchmark-derived values are not loaded automatically from router_limits.yaml. Operators or provisioning tooling must copy the certified per-model values into the policy.

shed_if

The loader accepts only kv_cache_utilization and waiting_requests in shed_if, with exactly one of gt, lt, gte, or lte per field. At admission, the router averages each reported signal across healthy agents serving the requested model. Missing signals pass. If a threshold fails, the router returns 429 concurrency_limit_exceeded with Retry-After: 1 before queueing the request. This is additive to per-agent exclude_if gates. Use exclude_if to remove an unhealthy or overloaded replica from a routing step; use shed_if to stop admitting new work when the serving pool as a whole is under pressure.

Cross-config validation

At startup and on auth or policy reload, the router validates every static and dynamic key against the effective serverless policies. Dynamic admin writes run the same checks. A configured occupancy share must be in (0, 1], and a nonzero input_tokens_per_minute must be at least max_input_tokens for every reachable serverless model. Invalid reloads leave the previous policy active. See Admission control for request-footprint calculation, parking, per-key limits, and error responses.

Primary routing policy

The router rejects a policy whose primary step has no strategy.

Static matching

The match object filters agents using metadata supplied during registration.
All non-empty conditions must match. Comparisons are exact and case-sensitive.

Engine values

Built-in agent engine names are:
For example:
Use llamacpp, not llama.cpp.

Match logic

This policy:
matches only an agent whose region is exactly EU-France and whose engine is exactly vllm. It does not match:
or:

Tag logic

Every tag listed in the policy must be present on the agent.
This matches an agent with:
It does not match an agent with only:
Additional agent tags are allowed.

Match every eligible agent

Use:
or omit match when the policy should not restrict agents by metadata. Model, health, capability, previous failures, and capacity still apply as hard routing constraints.

Dynamic metric gates

The exclude_if object removes agents whose live metrics violate a threshold.
An agent is excluded when it violates any configured rule.

Comparison operators

Each metric accepts exactly one operator. Valid:
Invalid because it has no operator:
Invalid because it has two operators:
Unknown metric names are rejected when the policy loads. For example, this typo causes a validation error:

Missing metrics

When a metric is unavailable for an agent, Hivenet Router skips that gate for the agent. For example:
does not exclude an Ollama agent merely because Ollama does not provide a KV-cache metric.
Missing data passes a metric gate.When a metric is required for the policy to be meaningful, combine the gate with a static engine or metadata filter.
For example:

Metric units

Use:
for 95% GPU utilization. Do not use:
Prometheus may display hardware utilization on a 0 to 100 scale. Hivenet Router normalizes these values to fractions before policy evaluation.

Universal metrics

These gates can apply to any agent once the necessary runtime history exists.

Capacity utilization

This excludes agents above 80% of their declared capacity. Hivenet Router also applies a hard capacity gate. An agent is unavailable when:
even when the policy contains no capacity_utilization rule.

Success rate

A new agent with no request history has no success-rate value, so this rule is skipped until the agent has served requests.

Smoothed latency

The threshold is in milliseconds. SRTT becomes available after Hivenet Router has collected routing latency observations for the agent.

Consecutive failures

The counter increases after forward failures and resets after a successful request.

Engine metrics

These gates depend on metrics exposed by the inference backend. Backend support differs: Preemption and throughput values are available for observability but are not currently valid exclude_if fields.

Cache pressure

Backend queue

Time to first token

Hardware metrics

Hardware gates use the most recent snapshot reported by the agent. When a host has several GPUs, Hivenet Router evaluates the highest reported value for:
  • temperature
  • compute utilization
  • VRAM utilization
For example:
A CPU-only agent has no GPU values, so GPU gates are skipped for that agent.

Ranking strategy

Every policy step requires a ranking strategy. The only implemented strategy is:
It ranks candidates by:
The lowest ratio ranks first. The following names are not currently supported:
A policy using one of these strategies is rejected.

Forward attempts

max_tries is the number of failed forwards allowed in one policy step before Hivenet Router advances to the next fallback step. A value of 0, a negative value, or an omitted field uses the router-wide default:
Examples of failures that consume a try include:
  • backend unavailability
  • backend overload or rate-limit responses
  • retryable backend errors
  • transport failures after connection recovery is exhausted
Request-level failures such as request_invalid, invalid_parameter, context_length_exceeded, and token_limit_exceeded stop immediately. They do not consume additional tries or advance through other local agents. The following do not consume a forward try:
  • no matching agents
  • agents excluded by policy gates
  • all agents already at capacity
  • losing an atomic capacity-slot race
  • the first connection-level recovery attempt for an agent
Each fallback step can define its own budget.

Fallback chain

fallback_chain contains ordered local policy steps.
The primary routing_policy always runs first. Each fallback entry supports: When name is omitted, Hivenet Router generates a name based on the step’s array position. A step advances when it has no viable candidates or exhausts its forward budget. Model and capability remain fixed throughout the fallback chain. A fallback step cannot route a request to another model or workload capability. See Fallback chains for examples and execution behavior.

Provider fallback

fallback_provider defines one external API used after every local step is exhausted.
It is a top-level field. Do not put it inside fallback_chain. Supported engines are:
Configure credentials through environment variables: Credentials do not belong in the policy YAML. The router rejects a policy when:
  • the provider engine is unsupported
  • the corresponding API key is not configured
  • the provider model is empty
Provider fallback is intended for non-streaming Chat Completions requests.Embedding and reranking requests do not use it, and it is not a transparent fallback for Anthropic token counting or every Messages field.
See Provider fallback for request translation and feature limitations.

Global policy file

Load one global policy:
The environment-variable equivalent is:
When no global policy is configured, Hivenet Router uses:
with the router-wide forward-attempt limit. A parse or validation error in the configured global policy prevents the router from starting.

Per-model policy directory

Use a directory when different models need different policies:
The environment-variable equivalent is:
Example:
Only .yaml and .yml files are loaded.

_default.yaml

The special file:
or:
defines the global policy for the directory. Its models field is ignored.
When both are configured:
_default.yaml takes precedence. A parse or validation error in _default.yaml is fatal during router startup.
Avoid configuring both a global file and a policy directory unless you need that exact precedence behavior.When a policy directory is configured, SIGHUP reloads the directory rather than the separate --policy-file.

Named per-model files

Every other policy file must contain at least one model:
The filename stem becomes the policy-document name. For:
the name is:
That name appears in the administration API and operational logs. A file without models is skipped with a warning. A model can belong to only one named policy document.

Model ownership conflicts

At initial startup, policy files are processed by modification time, oldest first. When two files claim the same model:
  1. the older file claims the model
  2. the later conflicting file is skipped entirely
When modification times are equal, filenames provide a deterministic tie-break. For example:
and:
cannot both load.
Do not rely on file modification times as an intentional priority system.Keep model ownership unique and explicit across the directory.
A conflict in one model causes the entire later file to be skipped, including any other models it contains.

Per-model file errors

During initial loading:
  • invalid _default.yaml stops router startup
  • an invalid named policy file is logged and skipped
  • a named file without models is logged and skipped
  • other valid named policies still load
This partial-failure behavior prevents one broken model policy from blocking unrelated models.

Policy selection

For each request, Hivenet Router:
  1. looks for a named policy assigned to the requested model
  2. uses that policy when one exists
  3. otherwise uses the active global policy
A per-model policy replaces the entire global policy for that model. It does not inherit or merge:
  • global match values
  • global gates
  • global fallback steps
  • global provider fallback
Repeat any global behavior that the per-model policy still needs.

Reload policies with SIGHUP

Reload policies without restarting the router:
For a single global file:
  • Hivenet Router parses and validates the file
  • valid changes replace the active policy
  • invalid changes are rejected
  • the previous active policy remains in use
For a policy directory:
  • unchanged files are not reapplied
  • valid changed files replace their named policies
  • deleted named files lose their policies
  • invalid existing files keep their previous active policy
  • conflicting changed files are skipped
  • unrelated valid policies remain active
This conservative reload behavior avoids removing a working policy merely because an edited file temporarily contains an error.
If _default.yaml is deleted during a directory reload, the current implementation reverts the global policy to Hivenet Router’s built-in least-loaded default.
Reload events are exposed through policy reload metrics and router logs.

Manage policies through the admin API

Global policy

Update the global policy with a YAML body:
The models field is ignored for this endpoint.

Named policies

Create or replace a named policy:
The YAML body must contain at least one model. API-created policies are ephemeral and disappear when the router restarts. Use files and --policy-model-dir for persistent configuration. See Admin endpoints for the complete API behavior.

Global example

Per-model example

Because BAAI/bge-m3 is an embedding model, a configured fallback_provider would not be used for its requests.

Validation checklist

Before loading a policy, check that:
  • routing_policy.strategy is present
  • every fallback step has a supported strategy
  • the strategy is least-loaded
  • every exclude_if field is spelled correctly
  • every metric has exactly one comparison operator
  • percentage thresholds use fractions
  • SRTT uses milliseconds
  • TTFT and ITL use seconds
  • provider credentials are set when provider fallback is configured
  • every named file declares at least one model
  • no two named files claim the same model
  • YAML indentation is valid

Troubleshooting

The router rejects the policy

Check its logs for the first validation error. Common causes include:
  • missing strategy
  • unsupported strategy
  • unknown metric field
  • missing comparison operator
  • several operators on one metric
  • missing provider engine or model
  • provider API key not configured
  • invalid YAML indentation

A policy file is ignored

For a named file, check that:
  • its extension is .yaml or .yml
  • it contains a non-empty models array
  • another file does not already claim one of its models
  • it passed YAML and policy validation

A model uses the global policy

Confirm that the model name in the file exactly matches the model registered by the agent:
Model names are case-sensitive.

A gate does not exclude an agent

Inspect the live value:
The metric may be unavailable, use another unit, or remain unset until the agent has served requests.

A changed policy does not take effect

File changes are not watched continuously. Send SIGHUP:
Then inspect the router logs for the reload result.

Next steps

Fallback chains

Build ordered local alternatives with independent filters and retry budgets.

Provider fallback

Configure OpenAI or Anthropic as a final fallback for chat requests.

Policy gates

Review practical gate patterns for health, latency, cache, and hardware pressure.