Skip to content
openrouter-load-balancing logo

OpenRouter Load Balancing

openrouter-load-balancing

Distribute OpenRouter requests across multiple keys and models for high

SKILL.md

Full skill instructions

OpenRouter Load Balancing

Overview

A single OpenRouter API key has rate limits (requests/​minute and tokens/​minute). To scale beyond those limits, distribute requests across multiple keys. OpenRouter also provides server-side load balancing via provider routing and the :nitro variant for low-latency inference. This skill covers multi-key rotation, health-based routing, circuit breakers, and concurrent request patterns.

Multi-Key Round Robin

import os, itertools, time, logging
from openai import OpenAI, RateLimitError
from dataclasses import dataclass, field

log = logging.getLogger("openrouter.lb")

@dataclass
class KeyPool:
    """Round-robin API key pool with health tracking."""
    keys: list[str]
    _cycle: itertools.cycle = field(init=False, repr=False)
    _health: dict[str, dict] = field(init=False, default_factory=dict)

    def __post_init__(self):
        self._cycle = itertools.cycle(self.keys)
        self._health = {k: {"errors": 0, "last_error": 0, "healthy": True} for k in self.keys}

    def next_key(self) -> str:
        """Get next healthy key."""
        attempts = 0
        while attempts < len(self.keys):
            key = next(self._cycle)
            h = self._health[key]
            # Recover after 60s cooldown
            if not h["healthy"] and time.time() - h["last_error"] > 60:
                h["healthy"] = True
                h["errors"] = 0
            if h["healthy"]:
                return key
            attempts += 1
        # All keys unhealthy -- return any and hope for the best
        return next(self._cycle)

    def mark_error(self, key: str):
        h = self._health[key]
        h["errors"] += 1
        h["last_error"] = time.time()
        if h["errors"] >= 3:  # Circuit breaker: 3 errors → unhealthy
            h["healthy"] = False
            log.warning(f"Key {key[:12]}... marked unhealthy after {h['errors']} errors")

    def mark_success(self, key: str):
        self._health[key]["errors"] = 0
        self._health[key]["healthy"] = True

pool = KeyPool(keys=[
    os.environ.get("OPENROUTER_KEY_1", ""),
    os.environ.get("OPENROUTER_KEY_2", ""),
    os.environ.get("OPENROUTER_KEY_3", ""),
])

def balanced_completion(messages, model="anthropic/​claude-3.5-sonnet", **kwargs):
    """Send request using next healthy key from the pool."""
    key = pool.next_key()
    client = OpenAI(
        base_url="https://openrouter.ai/​api/​v1",
        api_key=key,
        default_headers={"HTTP-Referer": "https://my-app.com", "X-Title": "my-app"},
    )
    try:
        response = client.chat.completions.create(
            model=model, messages=messages, **kwargs
        )
        pool.mark_success(key)
        return response
    except RateLimitError:
        pool.mark_error(key)
        # Retry with next key
        return balanced_completion(messages, model, **kwargs)

Concurrent Request Processing

import asyncio
from openai import AsyncOpenAI

async def parallel_completions(prompts: list[str], model="openai/​gpt-4o-mini",
                                max_concurrent=5, **kwargs):
    """Process multiple prompts concurrently with rate limiting."""
    semaphore = asyncio.Semaphore(max_concurrent)
    client = AsyncOpenAI(
        base_url="https://openrouter.ai/​api/​v1",
        api_key=os.environ["OPENROUTER_API_KEY"],
        default_headers={"HTTP-Referer": "https://my-app.com", "X-Title": "my-app"},
    )

    async def process_one(prompt: str):
        async with semaphore:
            response = await client.chat.completions.create(
                model=model,
                messages=[{"role": "user", "content": prompt}],
                **kwargs,
            )
            return response.choices[0].message.content

    return await asyncio.gather(*[process_one(p) for p in prompts])

# Usage
results = asyncio.run(parallel_completions(
    ["Summarize X", "Translate Y", "Analyze Z"],
    max_concurrent=3,
    max_tokens=500,
))

Provider-Level Load Balancing

# OpenRouter can distribute across providers for the same model
response = client.chat.completions.create(
    model="anthropic/​claude-3.5-sonnet",
    messages=[{"role": "user", "content": "Hello"}],
    max_tokens=200,
    extra_body={
        "provider": {
            # Let OpenRouter pick the best available provider
            "order": ["Anthropic", "AWS Bedrock", "GCP Vertex"],
            "allow_fallbacks": True,
        },
    },
)

Rate Limit Awareness

import requests

def check_rate_limits(api_key: str) -> dict:
    """Check current rate limit status for a key."""
    resp = requests.get(
        "https://openrouter.ai/​api/​v1/​auth/​key",
        headers={"Authorization": f"Bearer {api_key}"},
    )
    data = resp.json()["data"]
    return {
        "requests_limit": data["rate_limit"]["requests"],
        "interval": data["rate_limit"]["interval"],
        "credits_used": data["usage"],
        "credits_limit": data.get("limit"),
    }

# Check all keys in pool
for key in pool.keys:
    limits = check_rate_limits(key)
    print(f"Key {key[:12]}...: {limits}")

Error Handling

ErrorCauseFix
429 on all keysAll keys rate-limited simultaneouslyAdd more keys; implement request queuing
Uneven load distributionRound-robin not accounting for in-flight requestsUse weighted distribution based on current load
Key health false positiveTransient error marked key unhealthyUse sliding window (3 errors in 60s) before marking unhealthy
Concurrent request failuresToo many parallel requestsReduce semaphore limit; add backoff

Enterprise Considerations

  • Create separate API keys per service/​team with individual credit limits for cost isolation
  • Use 3+ keys to multiply effective rate limits (each key gets its own quota)
  • Implement circuit breakers: mark keys unhealthy after N consecutive errors, recover after cooldown
  • Use asyncio.Semaphore to control concurrency and prevent overwhelming the API
  • Monitor per-key error rates and latency to detect degraded keys early
  • Combine multi-key rotation with provider routing for maximum resilience

References

More Finance & Trading skills

ponytail-debt logo
Finance & Trading

ponytail-debt

Harvest every `ponytail:` comment in the codebase into a debt ledger, so the deliberate shortcuts and deferrals ponytail leaves behind get tracked instead of rotting into "later means never". One-shot report, changes nothing.

155.5K 27.9K
View
stripe-integration logo
Finance & Trading

stripe-integration

Stripe payment processing with checkout sessions, subscriptions, webhooks, and customer management.

40.2K 12.9K
View

Build comprehensive 3-5 year financial models with revenue projections, cost structures, cash flow analysis, and scenario planning for early-stage startups. Use this skill when creating financial projections, calculating burn rate or runway, modeling fundraising scenarios, or preparing investor-r...

40.2K 12K
View
stock-analysis logo
Finance & Trading

stock-analysis

Stock and cryptocurrency analysis with portfolio management and multi-dimensional scoring.

46 11.9K
View
coinglass logo
Finance & Trading

coinglass

Real-time crypto derivatives positioning, whale tracking, liquidations, and institutional ETF flows across 37 specialized tools.

27 11.5K
View

Master dbt (data build tool) for analytics engineering with model organization, testing, documentation, and incremental strategies. Use when building data transformations, creating data models, or implementing analytics engineering best practices.

40.2K 10.5K
View

Finance AI tools

C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Finalle.ai logo
Finance

Finalle.ai

Stay Ahead with Finalle.ai: The Ultimate Financial News and Tools Platform

Free
View

AI-powered Pine Script code generator for TradingView

Paid
View
TradeUI logo
Finance

TradeUI

Empower your investment strategies with AI signals, option flow data, and advanced chart patterns.

Paid
View
D
Finance

Danelfin

Danelfin review covering its AI stock and ETF scores, rankings, portfolio tools, current pricing, strengths, risks, and alternatives for investors.

Freemium
View
E
Finance

Ellisense

A software for comprehensive market sentiment analysis.

Paid
View

'Stock Correlations' App by Freshly.ai: Reveal Stock Patterns and Trends

Free
View