# How OmniRoute's 4-Tier Fallback System Prioritizes LLM Providers

> Discover OmniRoute's 4-tier fallback system. Prioritize LLM providers from Subscription to Free, ensuring reliable API access and cost optimization.

- Repository: [Diego Rodrigues de Sa e Souza/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- Tags: how-to-guide
- Published: 2026-08-19

---

**OmniRoute routes requests through a four-tier hierarchy—Subscription, API Key, Cheap, then Free—to ensure high-priority traffic uses paid, high-quota backends while automatically degrading to cost-optimized alternatives when providers fail.**

The open-source routing engine **diegosouzapw/OmniRoute** classifies every large language model (LLM) provider connection into one of four distinct tiers based on business relationship and cost model. This classification drives a deterministic prioritization algorithm that keeps enterprise traffic on subscription contracts while maintaining availability through lower-cost fallbacks.

## Understanding the Four Provider Tiers

In [`src/shared/constants/providers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers.ts), each provider definition includes a `tier` field that maps to one of four categories. These tiers determine both scoring weights and the order of automatic failover.

### Tier 1 – Subscription (Highest Priority)

**Subscription** tier providers rely on paid enterprise contracts or higher-quota plans. The routing engine treats these as the primary target for all requests because they typically offer the highest rate limits and most reliable service. According to the source code in [`open-sse/services/autoCombo/scoring.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/services/autoCombo/scoring.ts), these connections receive the maximum `tierPriority` boost during candidate selection.

### Tier 2 – API Key (Standard Credentials)

**API Key** tier covers individual API credentials that are not part of a formal subscription contract. While still paid, these lack the enterprise guarantees of Tier 1. The scoring engine places them after Subscription providers but before any cost-optimized routes, ensuring paid traffic stays ahead of budget-conscious fallbacks.

### Tier 3 – Cheap (Cost-Optimized)

The **Cheap** tier identifies providers with inexpensive per-token pricing, often "floor" or "budget" pricing models. OmniRoute selects these when higher tiers are unavailable or when the request explicitly specifies a cost-optimized route via the `auto/cheap` selector.

### Tier 4 – Free (Last Resort)

**Free** tier providers operate on limited or zero-cost quotas. The system only considers these after exhausting all other tiers or when a request explicitly targets `auto/free`. This ensures that paid customers never consume free-tier capacity unless absolutely necessary.

## How the Fallback Mechanism Works at Runtime

The fallback system operates through a multi-layer pipeline implemented across [`open-sse/services/autoCombo/virtualFactory.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/services/autoCombo/virtualFactory.ts) and [`src/sse/handlers/chat.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/sse/handlers/chat.ts).

### Step 1: Candidate Pool Construction

When a request arrives (e.g., `model: "auto"`), the system queries all active connections:

```typescript
// From open-sse/services/autoCombo/virtualFactory.ts
const candidates = await getProviderConnections({ isActive: true });

```

Each connection object carries the `tier` classification from the provider constants. The `buildVirtualAutoCombo()` function assembles these into an in-memory pool of potential candidates.

### Step 2: Tier-Aware Scoring

The scoring engine in [`open-sse/services/autoCombo/scoring.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/services/autoCombo/scoring.ts) applies two tier-specific factors:

- **`tierPriority`**: Adds a positive weight to higher-tier providers (Subscription > API Key > Cheap > Free)
- **`tierAffinity`**: Matches the requested tier when using `auto/<category>:<tier>` suffixes

```typescript
// Score the pool with tier weighting
const scored = scorePool(candidates, taskType, undefined, getTaskFitness);
const best = scored[0]; // e.g., provider "anthropic-sub" (Subscription tier)

```

### Step 3: Layered Failure Detection

Before final selection, the system filters candidates through three exclusion layers defined in [`src/sse/services/auth.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/sse/services/auth.ts):

1. **Circuit Breaker Check**: Providers with an **OPEN** circuit status (from `getCircuitBreaker(provider).getStatus()`) are removed from the pool
2. **Rate Limit Cooldown**: Connections with active `rateLimitedUntil` timestamps are temporarily excluded
3. **Model Lockout**: Specific model failures trigger `isModelLocked()` checks, allowing the connection to remain available for other models while blocking the failed one

### Step 4: Global Tier Fallback

If all candidates from the current tier are exhausted, [`src/sse/handlers/chat.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/sse/handlers/chat.ts) (lines 1134–1150) orchestrates the cross-tier fallback:

```typescript
// Fallback triggered in src/sse/handlers/chat.ts
if (!response.ok) {
  const fallbackProvider = getNextTier(currentTier); // Subscription → API Key → Cheap → Free
  const fallbackModelStr = `${fallbackProvider}/${fallbackModel}`;
  
  return handleSingleModelChat(
    { ...body, model: fallbackModelStr },
    fallbackProviderModelStr,
    null // no combo strategy for emergency fallback
  );
}

```

The `globalFallbackModel` configuration setting allows administrators to define a specific endpoint of last resort when the entire provider chain fails.

## Request-Level Controls and Headers

OmniRoute exposes granular control through HTTP headers processed in the chat handler:

- **`X-OmniRoute-Mode`**: Forces a specific tier classification (e.g., `fast`, `cheap`, `free`)
- **`X-OmniRoute-Budget`**: Caps the per-request cost; if no candidate satisfies the cap, the system references `X-OmniRoute-Budget-Fallback` to determine whether to select the cheapest viable provider or return HTTP 402 (Payment Required)

These headers interact directly with the scoring engine's cost factors, overriding default tier priorities when business constraints require specific economic controls.

## Summary

- **OmniRoute's 4-tier fallback system** categorizes providers as Subscription, API Key, Cheap, or Free to enforce business-priority routing
- The **Subscription** tier receives first preference through `tierPriority` scoring boosts in [`open-sse/services/autoCombo/scoring.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/services/autoCombo/scoring.ts)
- **Four exclusion layers** protect against cascading failures: circuit breakers, connection cooldowns, model lockouts, and global tier fallback
- When high-tier providers fail, the engine automatically degrades to **API Key**, then **Cheap**, and finally **Free** providers via `handleSingleModelChat()` in [`src/sse/handlers/chat.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/sse/handlers/chat.ts)
- Request headers allow dynamic override of tier selection and budget constraints without modifying provider configurations

## Frequently Asked Questions

### How does OmniRoute determine which tier a provider belongs to?

The tier classification is static metadata defined in [`src/shared/constants/providers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/constants/providers.ts). Each provider entry includes a `tier` field that maps to one of the four categories. This metadata propagates to active connection objects via `getProviderConnections()`, making it available to the scoring engine during candidate evaluation.

### What happens if all providers in the Subscription tier are unavailable?

If the circuit breaker, rate limit, or quota filters exclude all Subscription candidates, the engine automatically falls back to the API Key tier, then Cheap, and finally Free. This progression is hardcoded into the fallback logic in [`src/sse/handlers/chat.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/sse/handlers/chat.ts), which rebuilds the request body with `fallbackModelStr` pointing to the next available tier.

### Can I force OmniRoute to use only Free-tier providers for testing?

Yes. Send the `X-OmniRoute-Mode: free` header with your request. This triggers `tierAffinity` scoring in [`open-sse/services/autoCombo/scoring.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/services/autoCombo/scoring.ts), effectively filtering the candidate pool to only Free-tier providers. Note that if Free providers are rate-limited or exhausted, the request may fail unless `globalFallbackModel` is configured to allow cross-tier escalation.

### What is the difference between the Cheap tier and cost-based routing?

The **Cheap** tier is a static provider classification based on the provider's base pricing model, while cost-based routing is a dynamic strategy that compares real-time token prices. A provider in the Subscription tier might still be cheaper per token than a Cheap-tier provider during a promotion, but the 4-tier system prioritizes contractual relationships (Subscription > API Key) before evaluating per-request economics unless explicitly overridden by `X-OmniRoute-Mode` or `X-OmniRoute-Budget` headers.