Skip to main content
Requests to the same endpoint vary in difficulty. A greeting, a factual lookup, and a request to design a distributed rate limiter can all arrive at one model. If your most capable model serves all of them, you pay top-tier prices for requests a cheaper model could answer. Auto Routing classifies each request as simple, medium, or complex and sends it to the target you configured for that tier. Your application calls one virtual model name, and the AI Gateway picks the model that serves each request. Other routing strategies decide based on weights, priorities, or measured latency. Auto Routing decides based on the content of the request. Benchmark summary. Compared with sending every request to Claude Opus 5.5, over 1,279 prompts in three workloads. See the full benchmark.

Up to 95% lower cost

Most requests go to a smaller, cheaper model.

Opus-level accuracy

Same pass rate as Opus 5.5 on graded tests.

Up to 40% faster

Median response time, including classification.

Requirements and availability

Auto Routing is generally available on all tenants. You do not need to request access. New virtual models still default to weight-based routing, so select Auto Routing when you create or edit one.
Auto Routing is available on virtual models only. The deprecated tenant-level Routing Config YAML (gateway-load-balancing-config) does not support it.
The AI Gateway rejects the virtual model on save unless it meets these conditions:
  • Model types are limited to chat, completion, and responses. Embedding, image, audio, rerank, and moderation are not supported.
  • Each model appears only once. A model can be the target of only one tier, and only once within it.
  • The classifier model is a catalog chat model for LLM classification, or a catalog decision model in a TypeSafe account for decision model classification. A virtual model cannot be a classifier.
See Validation errors for the error messages and fixes.

How a request is routed

1

Filter targets by metadata

If any target defines metadata_match, the AI Gateway drops non-matching targets first. Classification and escalation consider only the remaining targets.
2

Check the conversation pin

For a multi-turn request, the AI Gateway looks up the tier and target that served the conversation’s previous turn. Conversation pinning is automatic and needs no configuration.
3

Classify the request

The heuristic classifier (default), decision model classifier, or LLM classifier assigns the current turn to simple, medium, or complex. If the conversation is pinned to a higher tier, it stays on that tier. A conversation pinned to complex skips classification.
4

Build the target chain

Targets in the selected tier come first. The selected tier is the classified tier, or the higher pinned tier. The escalation chain follows: higher tiers, then lower tiers.
5

Send the request

The AI Gateway tries the first target with that target’s retry settings. If it fails with a fallback status code, the AI Gateway moves to the next target in the chain.
6

Update the conversation pin

After a successful response, the AI Gateway records the tier of the target that served the turn. Classification never moves a conversation down a tier. If a fallback was served by a lower-tier target, the pin records that lower tier.

Complexity tiers

There are three tiers, ordered from cheapest to most capable. The dashboard shows the same descriptions next to each tier.
Configure at least one model in each of simple, medium, and complex. The dashboard requires it. Configs applied through the API or tfy apply are not checked, and a request whose tier has no target goes to the next tier up, then down.

Classification strategies

There are three strategies:
  • Heuristic (default): free and runs in-process.
  • Decision model classifier: calls a TypeSafe decision model, such as Jev, with a built-in tier rubric.
  • LLM classifier: calls a chat model you choose, at the cost of one model call per classified turn.
A turn in a conversation pinned to complex skips classification, because there is no higher tier. In the benchmark, the heuristic saved 78 to 95% of cost and the decision model classifier (Jev) saved 30 to 75%, depending on the workload. Jev passed more medium and hard prompts.

What text gets classified

All three strategies read the same two pieces of text from the request body:
  • The last user message: the current turn.
  • The last system or developer message: used as context. This includes the top-level system field on Anthropic /messages requests and the top-level instructions field on /responses requests.
The classifier ignores earlier turns, assistant replies, and tool messages. Conversation pinning keeps multi-turn conversations consistent.
Classification reads up to 8,000 characters of user text and 2,000 characters of system text. Longer prompts still count as long prompts.

Heuristic classification (default)

The heuristic classifier checks the prompt for a fixed set of signals and picks a tier. It needs no configuration and applies when classification_strategy is not set.
These signals push a request toward a higher tier, from most to least influential:These signals push a request toward a lower tier:Reasoning override. Two or more distinct reasoning phrases in the user text always route to complex, regardless of other signals.Empty prompts. A request with no classifiable text routes to simple.The signals and keyword lists are fixed. If they do not reflect how difficulty shows up in your traffic, use the decision model classifier.

Decision model classification

The AI Gateway classifies the request by calling a TypeSafe decision model, such as Jev, with a built-in tier rubric. In the dashboard, this is Decision Model. To set it up, add a native TypeSafe model account and a model with Model Types set to Decision. Reference the model by its catalog FQN, such as my-typesafe-account/jev.
The AI Gateway calls /v1/systemone with the user text in state.request and the system context, if any, in state.context. It sends one choice question named tier with the options simple, medium, and complex, and reads the tier from answers.tier.choice. You do not write question JSON or classifier instructions. The tier rubric is fixed. timeout_ms must be a positive integer. On a timeout, error, non-2xx response, or unusable tier, the configured fallback strategy applies. Conversation pinning and escalation work the same as with the other classifiers.
The classifier must belong to a TypeSafe account and support decision. A decision model such as Jev, accessed through OpenRouter or Custom Endpoints, cannot be the classifier. The virtual model that serves your application still declares chat, completion, or responses. decision applies only to the classifier model.
Each decision model classifier call is a billable gateway request, with its own tokens, cost, and request log under the caller’s tenant and identity. Set the TypeSafe model’s cost to track this usage. Turns pinned to complex skip the classifier call.

LLM classification

The AI Gateway classifies the request by calling a chat model you choose. In the dashboard, this is LLM Based, and the optional Classifier Prompt field sets instructions. LLM Based is listed only if a virtual model in your tenant already uses it.
fallback_strategy is required when classification_strategy.type is llm-classifier. The dashboard pre-fills the heuristic fallback, so this affects only configs written by hand or sent through the API. A config without it is rejected with must have required property 'fallback_strategy'.{"type": "heuristic"} matches the previous implicit behavior. Add it to existing configs to keep them working. classification_strategy itself is still optional and defaults to the heuristic strategy.
Each classifier call is a billable gateway request. It appears in your request logs, and its tokens and cost are attributed to the same tenant and subject as the original request. Use a small, fast model and a short timeout_ms.
  • The classifier receives the request’s system context and user text, plus a short instruction block that describes the three tiers (or your instructions override).
  • The reply is constrained to a JSON schema ({"tier": "simple" | "medium" | "complex"}) and capped at 256 output tokens. If a model ignores the schema and answers in prose, the AI Gateway uses the first tier name it finds.
  • After timeout_ms (default 2000), the call is abandoned and the fallback strategy applies.

Fallback when the classifier fails

If the classifier times out, errors, returns a non-2xx status, or returns nothing usable, the configured fallback strategy picks the tier and the request continues. Invalid classifier configuration, such as an unresolved model or the wrong provider account, is a separate case. See Validation errors.
llm-classifier uses the same fallback_strategy options. The field is required for both model-based strategies, and the dashboard pre-fills Heuristic Fallback. For static, default_tier is required, and the dashboard pre-fills medium. Use heuristic to keep classifying by content during a classifier outage. Use static to send all requests to one tier: default_tier: complex keeps quality at higher cost, and default_tier: simple keeps cost low at lower quality.

Escalation and fallback

Auto Routing builds an ordered chain of targets, so a request is still served when its tier has no usable target. For a request classified into tier T, the order is:
  1. Targets in tier T, in the order you declared them.
  2. Targets in higher tiers, one tier at a time.
  3. Targets in lower tiers, one tier at a time.
A request classified as simple tries simple, then medium, then complex. A request classified as complex tries complex, then medium, then simple. The request fails only after every target fails. Each target uses its own retry_config, fallback_status_codes, and fallback_candidate settings, the same as in the other routing strategies.
Unhealthy-target cooldown does not apply. Other strategies move a failing target to the end of the list. Auto Routing always orders targets by tier. Per-target rate limits and budgets still apply, and a rate-limited or over-budget target is skipped.

Conversation pinning

Auto Routing keeps a multi-turn conversation on the same tier and target. You do not need to configure sticky_routing, add a conversation header, or set a TTL.
  1. The first turn is classified as usual. After a successful response, the AI Gateway records the tier and target.
  2. Each later user turn is classified again.
  3. If the new turn is harder, the conversation moves up to the higher tier. The pin updates after a successful response.
  4. If the new turn is easier, the conversation stays on its current tier. A short follow-up such as “thanks” does not move it to a cheaper model.
  5. Once a conversation reaches complex, later turns skip classification.
Classification can move a conversation to a more capable model when the task gets harder, but never to a less capable one. The only way down is a fallback: if a lower-tier target serves a turn, the pin records that tier. Your application needs no changes. Send the conversation history as the API already expects. A pin expires after 10 minutes of inactivity and resets on every turn.
Single-turn requests, such as legacy /completions and /responses with a string input, have no conversation, so each one is classified on its own.
A target that failed is never recorded as the conversation’s next target.

Benchmark results

We ran the heuristic and the decision model classifier with Jev on the same prompts and compared each one with sending every request to Claude Opus 5.5. Answers are graded automatically. Generated code runs against unit tests, and math and multiple-choice answers are checked against answer keys.
Bar chart of cost saved compared with Opus 5.5 on every request. Graded benchmarks: heuristic 90%, Jev 57%. RouterArena: heuristic 95%, Jev 75%. Production-style traffic: heuristic 78%, Jev 30%.Bar chart of cost saved compared with Opus 5.5 on every request. Graded benchmarks: heuristic 90%, Jev 57%. RouterArena: heuristic 95%, Jev 75%. Production-style traffic: heuristic 78%, Jev 30%.

Cost saved on each workload. Pass rates are in the tables below.

Results by workload

550 prompts from 11 datasets: ARC-Challenge, BBH, CommonsenseQA, GSM8K, HumanEval, MATH-500, MBPP, MMLU, MMLU-Pro, OpenBookQA, and SVAMP.
50 prompts per dataset.

Jev classifier overhead

We sent each benchmark prompt to Jev three times, outside of routing, for 3,924 calls.

Quality on hard prompts

The two classifiers differ most as prompts get harder. On RouterArena’s easy prompts, both pass about as often as Opus 5.5. On medium and hard prompts, the heuristic still sends almost everything to Haiku 5.5, while Jev sends more of them to Sonnet and Opus. On medium prompts, Jev passes 84% and the heuristic 79%, against 88% for Opus 5.5. Hard prompts are hard for every model: Opus 5.5 passes 57%, Jev 35%, and the heuristic 29%. The hard set has only 49 prompts, so treat the gap there as a direction, not a precise figure.
Grouped bar chart of RouterArena pass rate by difficulty. Easy (345 prompts): Opus 5.5 96%, heuristic 97%, Jev 96%. Medium (176): Opus 5.5 88%, heuristic 79%, Jev 84%. Hard (49): Opus 5.5 57%, heuristic 29%, Jev 35%.Grouped bar chart of RouterArena pass rate by difficulty. Easy (345 prompts): Opus 5.5 96%, heuristic 97%, Jev 96%. Medium (176): Opus 5.5 88%, heuristic 79%, Jev 84%. Hard (49): Opus 5.5 57%, heuristic 29%, Jev 35%.

RouterArena pass rate by difficulty label, with Opus 5.5 on every request for reference.

Which classifier to choose

If you are not sure, start with the heuristic (the default). Before you roll out, compare it with a single cheaper model on your own traffic. To track savings on your own traffic, see Cost Savings and Observability.

Configure in the dashboard

You configure Auto Routing on a virtual model. See Create a virtual model for the full setup.
1

Create the virtual model and choose Auto Routing

Go to AI Gateway → Model Gateway → Virtual Models. Click Add Virtual Model Group, or open an existing group, and add or edit a model. Enter a Name, and under Model Types select only Chat, Completion, or Responses.For the routing strategy, select Auto Routing.
Model Types with Chat selected, the Auto Routing tab selected, and the Heuristic and Decision Model strategies

Creating a virtual model with Auto Routing selected

2

Pick a classification strategy

Heuristic is selected by default and needs no other settings.To classify with a decision model, choose Decision Model, select your TypeSafe Classifier Model, such as Jev, and set Timeout (ms) (default 800) and Fallback Strategy. Choosing Static Fallback adds a Default Tier field. If the model is not listed, add it through the TypeSafe integration first.
Auto Routing with the Decision Model classifier set to TypeSafe Jev, Timeout 800 ms, Heuristic Fallback, and Haiku, Sonnet, and Opus targets for Simple, Medium, and Complex

Decision Model classifier set to TypeSafe Jev, with an 800 ms timeout, heuristic fallback, and a target for each complexity tier

LLM Based appears only if a virtual model in your tenant already uses it. Otherwise, set llm-classifier through the API or tfy apply. See LLM classification.
3

Add targets and assign tiers

Targets form a numbered list, each with a Tier dropdown. The first three are fixed to Simple, Medium, and Complex. Click + Add Target to add more targets to any tier.Each target has its own Fallback status codes, plus optional Retries, Override Params, Override Headers, and Metadata Filters. These work the same as in the other routing strategies.
Four targets: claude-haiku-5-5 as Simple, claude-sonnet-5-5 as Medium, claude-opus-5-5 as Complex, and claude-fable-5 as a second Complex target

A target for each tier, plus a second Complex target added with + Add Target

Configuration reference

Examples

A low-cost model for simple requests, a mid-tier model for everyday work, and a top model for hard requests. No classifier cost or added latency.
A decision model such as Jev classifies requests. If the classifier is unavailable, all requests go to the complex tier, so quality holds and cost rises only during the outage.
Targets in the same tier are tried in declaration order before escalating.
Pair each tier with a prompt version written for that model, using per-target overrides.

Observability

Which tier served the request

Every response includes an x-tfy-applied-rules header. For Auto Routing, it contains a complexity block with the served tier and how it was chosen, and the full target chain in routing_model_order:
cause shows how the tier was chosen: reason shows why each target in routing_model_order is in its position: The x-tfy-resolved-model response header also returns the model that served the request. The Cost savings column in Metrics Overview estimates how much Auto Routing saved compared with sending every request to the complex tier. See Cost Savings.

Metrics

Each routing decision increments a counter that shows your tier mix and how often requests escalate.
  • decided_tier: the tier assigned to the current turn, before target fallback. For a complex pin that skips classification, this is complex.
  • resolved_tier: the tier after the conversation pin is applied. It differs from decided_tier only when cause is session_pin.
Escalation does not change resolved_tier or the complexity.tier value in the response header. When a target is rate-limited, over budget, or fails and the request moves to another tier, only resolved_model in the header and x-tfy-resolved-model show the model that served it. See Prometheus and Grafana integration for scraping setup.

Traces and logs

  • Each LLM classifier call creates a ComplexityBasedRouting: LLMClassifier span, with the classifier’s chat completion span nested under it. This separates classifier latency from the served model’s latency.
  • Each decision model classifier call creates a ComplexityBasedRouting: DecisionClassifier span, with the System One request nested under it. The span records tfy.complexity.tier and, when returned, tfy.complexity.confidence.
  • The request span includes tfy.complexity.tier, tfy.complexity.cause, and, for heuristic decisions, tfy.complexity.score.
  • The AI Gateway logs each decision with the tier, cause, matched signals, and resolved model. Use these logs to see why a request landed on its tier.

Validation errors

The AI Gateway rejects these configurations with a 400 when you save the virtual model: The AI Gateway also checks the classifier model at request time. If the classifier model is deleted or changed after you save, requests return the same error instead of routing to the wrong tier.

FAQ

In our benchmark, savings ranged from 30% to 95% depending on the classifier and workload. Your savings depend on your traffic mix. The Cost savings column in Metrics Overview estimates savings against the complex tier. See Cost Savings. To see the share of traffic on each tier, break down ai_gateway_complexity_routing_decisions_total by resolved_tier, and compare per-model cost in Model Metrics.
No. Auto Routing is available on virtual models only. Create a virtual model and point your clients at it.
No. A virtual model that declares those model types with Auto Routing is rejected on save. Use weight-, priority-, or latency-based routing instead.
No. Its signals are fixed. If the heuristic misclassifies your traffic, switch to the decision model classifier.
Yes. Classifier calls appear in request logs, and their tokens and cost are attributed to the same tenant and subject as the original request. Use a small, low-cost model and a short timeout_ms. Conversations pinned to complex make no further classifier calls.
The request still goes through. On a timeout, error, non-2xx response, or unusable reply, the configured fallback_strategy picks the tier: the heuristic, or a fixed default_tier if you chose static.
Not in the dashboard, which requires a target in each of simple, medium, and complex. Configs applied through the API or tfy apply are not checked. A request classified into a tier with no target goes to the next tier up, then down. Give every tier a target so cost and quality stay predictable.
If all targets in the classified tier are ineligible at request time, for example rate-limited, over budget, or filtered out by metadata, the request escalates to the next higher tier, then to lower tiers. resolved_model in the x-tfy-applied-rules header and x-tfy-resolved-model show the model that served it. The tier fields and metric labels still show the classified tier.
Yes, when it needs a more capable model or the current target fails. Conversation pinning stops later turns from moving to a lower tier. A harder follow-up can move the conversation to a higher tier, and a successful fallback can change the target for later turns.
No. Targets are ordered by tier and escalation, not by health. Per-target retries, fallback status codes, rate limits, and budgets still apply.
Yes. Classification finishes before the upstream request starts, so streaming works as usual.
Yes. A chat virtual model serves /chat/completions, /messages, and /responses, and a responses virtual model serves /responses. The top-level system prompt (system or instructions) is used as classification context, and multi-turn conversations are pinned the same way. A /responses follow-up with previous_response_id goes to the backend that served the original response, but the classifier still runs and is billed.

Next steps