OP

openrouter-performance-tuning

Provides benchmarking tools to measure TTFT and latency, helping you select the fastest models for your production needs.

Install

mkdir -p .claude/skills/openrouter-performance-tuning && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/4791" && unzip -o skill.zip -d .claude/skills/openrouter-performance-tuning && rm skill.zip

Installs to .claude/skills/openrouter-performance-tuning

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Optimize OpenRouter request latency and throughput. Use when building
69 chars✓ has a “when” trigger
Intermediate

Key capabilities

  • Benchmark model latency using p50 and p95 metrics
  • Stream completions to reduce time-to-first-token
  • Execute parallel requests with concurrency control
  • Optimize connection settings for throughput
  • Quantify performance improvements from tuning

How it works

It provides a benchmarking harness to measure request round-trip times and offers patterns for streaming and asynchronous execution to improve perceived speed.

Inputs & outputs

You give it
A list of models and prompts to test
You get back
Latency statistics including p50, p95, and average response times

When to use openrouter-performance-tuning

  • Measure latency differences between model providers
  • Optimize request throughput for real-time apps
  • Determine p95 latency for production SLAs
  • Validate performance of small models vs large models

About this skill

OpenRouter Performance Tuning

Overview

OpenRouter adds minimal overhead (~50-100ms) to direct provider calls. Most latency comes from the upstream model. Key levers: model selection (smaller = faster), streaming (lower TTFT), parallel requests, prompt size reduction, and provider routing to faster infrastructure. This skill covers benchmarking, streaming optimization, concurrent processing, and connection tuning.

Prerequisites

  • An OpenRouter API key (sk-or-v1-...) exported as OPENROUTER_API_KEY — see the openrouter-install-auth skill for setup
  • Python 3.8+ with the OpenAI SDK (openai package) — the examples use both the sync OpenAI client and AsyncOpenAI for parallel processing
  • Credits on the key if you benchmark paid models like anthropic/claude-3.5-sonnet; a :free model is enough to validate the benchmark harness itself
  • HTTP-Referer / X-Title header values for your app (set in every client constructor here)

Instructions

  1. Establish a baseline: run benchmark_model() from Benchmark Latency against your candidate models (e.g. openai/gpt-4o-mini vs anthropic/claude-3.5-sonnet) and record p50/p95.
  2. Check the results against the Model Speed Tiers table to confirm each candidate sits in the right tier for your latency budget (200-500ms TTFT fastest tier; 5-30s for reasoning models).
  3. Switch user-facing paths to stream_completion() per Streaming for Lower TTFT and verify ttft_ms drops (typically 2-10x).
  4. Move batch workloads to parallel_completions() per Parallel Request Processing, capping concurrency with asyncio.Semaphore (max_concurrent=5-10).
  5. Apply Connection Optimization — one shared client with timeout=30.0 and max_retries=2 instead of a new client per request.
  6. Work through the Performance Optimization Checklist (set max_tokens, shrink prompts, consider :nitro variants and provider routing), then re-run the benchmark to quantify each change.

Benchmark Latency

import os, time, statistics
from openai import OpenAI

client = OpenAI(
    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"},
)

def benchmark_model(model: str, prompt: str = "Say hello", n: int = 5) -> dict:
    """Benchmark a model's latency over N requests."""
    latencies = []
    for _ in range(n):
        start = time.monotonic()
        response = client.chat.completions.create(
            model=model,
            messages=[{"role": "user", "content": prompt}],
            max_tokens=50,
        )
        latencies.append((time.monotonic() - start) * 1000)

    return {
        "model": model,
        "p50_ms": round(statistics.median(latencies)),
        "p95_ms": round(sorted(latencies)[int(len(latencies) * 0.95)]),
        "avg_ms": round(statistics.mean(latencies)),
        "min_ms": round(min(latencies)),
        "max_ms": round(max(latencies)),
    }

# Compare fast vs slow models
for model in ["openai/gpt-4o-mini", "anthropic/claude-3-haiku", "anthropic/claude-3.5-sonnet"]:
    result = benchmark_model(model)
    print(f"{result['model']}: p50={result['p50_ms']}ms p95={result['p95_ms']}ms")

Streaming for Lower TTFT

def stream_completion(messages, model="openai/gpt-4o-mini", **kwargs):
    """Stream response for lower time-to-first-token."""
    start = time.monotonic()
    first_token_time = None
    full_content = []

    stream = client.chat.completions.create(
        model=model, messages=messages, stream=True,
        stream_options={"include_usage": True},  # Get token counts at end
        **kwargs,
    )

    for chunk in stream:
        if chunk.choices and chunk.choices[0].delta.content:
            if first_token_time is None:
                first_token_time = (time.monotonic() - start) * 1000
            full_content.append(chunk.choices[0].delta.content)

    total_time = (time.monotonic() - start) * 1000
    return {
        "content": "".join(full_content),
        "ttft_ms": round(first_token_time or 0),
        "total_ms": round(total_time),
    }

Parallel Request Processing

import asyncio
from openai import AsyncOpenAI

async def parallel_completions(prompts: list[str], model="openai/gpt-4o-mini",
                                max_concurrent=10, **kwargs):
    """Process multiple prompts concurrently."""
    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(prompt):
        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(p) for p in prompts])

# 10 requests in parallel instead of sequential
results = asyncio.run(parallel_completions(
    ["Summarize: " + text for text in documents],
    max_concurrent=5,
    max_tokens=200,
))

Performance Optimization Checklist

OptimizationImpactEffort
Use streamingTTFT drops 2-10xLow
Use smaller models for simple tasks2-5x fasterLow
Reduce prompt sizeProportional to reductionMedium
Set max_tokensCaps response timeLow
Parallel requestsN requests in ~1 request timeMedium
Use :nitro variantFaster inference (where available)Low
Provider routing to fastest10-30% latency reductionLow
Connection keep-aliveSaves TCP/TLS handshakeLow

Model Speed Tiers

SpeedModelsTypical TTFT
Fastestopenai/gpt-4o-mini, anthropic/claude-3-haiku200-500ms
Fastopenai/gpt-4o, google/gemini-2.0-flash-001500ms-1s
Standardanthropic/claude-3.5-sonnet1-3s
Slowopenai/o1, reasoning models5-30s

Connection Optimization

# Reuse client instance (connection pooling)
# BAD: creating new client per request
for prompt in prompts:
    c = OpenAI(base_url="https://openrouter.ai/api/v1", ...)  # New TCP connection each time
    c.chat.completions.create(...)

# GOOD: reuse single client
client = OpenAI(
    base_url="https://openrouter.ai/api/v1",
    api_key=os.environ["OPENROUTER_API_KEY"],
    timeout=30.0,           # Set appropriate timeout
    max_retries=2,          # Built-in retry with backoff
    default_headers={"HTTP-Referer": "https://my-app.com", "X-Title": "my-app"},
)
for prompt in prompts:
    client.chat.completions.create(...)  # Reuses HTTP connection

Output

  • A latency benchmark table per model from benchmark_model(): p50_ms, p95_ms, avg_ms, min_ms, max_ms over N sample requests
  • Streaming metrics from stream_completion(): the full content plus ttft_ms and total_ms for each request
  • A list of completions from parallel_completions() produced in roughly one request's wall-clock time instead of N sequential round-trips
  • A prioritized tuning plan drawn from the Performance Optimization Checklist (lever, expected impact, effort)

Examples

Benchmark two fastest-tier candidates before committing to one:

for model in ["openai/gpt-4o-mini", "anthropic/claude-3-haiku"]:
    r = benchmark_model(model, n=5)
    print(f"{r['model']}: p50={r['p50_ms']}ms p95={r['p95_ms']}ms avg={r['avg_ms']}ms")
# openai/gpt-4o-mini: p50=430ms p95=610ms avg=455ms
# anthropic/claude-3-haiku: p50=395ms p95=580ms avg=418ms

Both land in the fastest tier (200-500ms typical TTFT), so choose on cost or quality — then stream_completion() cuts perceived latency further for user-facing paths. More worked examples: references/examples.md.

Error Handling

ErrorCauseFix
High TTFT (>5s)Model cold-starting or overloadedSwitch to :nitro variant or different provider
Timeout errorsmax_tokens too high or model too slowReduce max_tokens; use streaming; increase timeout
Throughput bottleneckSequential processingUse async + semaphore for concurrent requests
Inconsistent latencyProvider load variesUse provider.order to pin to fastest provider

Enterprise Considerations

  • Benchmark models in your infrastructure, not just locally -- network path matters
  • Use streaming for all user-facing requests to minimize perceived latency
  • Set max_tokens on every request to bound response time and cost
  • Reuse client instances to benefit from HTTP connection pooling
  • Use asyncio.Semaphore to control concurrency and avoid overwhelming the API
  • Monitor P95 latency, not just average -- tail latencies indicate provider issues
  • Consider :nitro model variants for latency-critical paths

References

When not to use it

  • When benchmarking models without sufficient credits
  • When the application does not support streaming

Prerequisites

OpenRouter API key exported as OPENROUTER_API_KEYPython 3.8+ with openai package

Limitations

  • Benchmark results depend on local network conditions
  • High concurrency may hit API rate limits

How it compares

This method provides quantitative performance data to inform model selection, rather than relying on anecdotal speed observations.

Compared to similar skills

openrouter-performance-tuning side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
openrouter-performance-tuning (this skill)127dReviewIntermediate
sentry-rate-limits127dCautionIntermediate
optimizing-performance12moReviewIntermediate
azure-monitor-opentelemetry-py029dReviewIntermediate

Try saying

Example prompts that trigger this skill in your AI assistant.

More by jeremylongshore

View all by jeremylongshore

analyzing-logs

jeremylongshore

Analyze application logs to detect performance issues, identify error patterns, and improve stability by extracting key insights.

14123

ollama-setup

jeremylongshore

Configure auto-configure Ollama when user needs local LLM deployment, free AI alternatives, or wants to eliminate hosted API costs. Trigger phrases: "install ollama", "local AI", "free LLM", "self-hosted AI", "replace OpenAI", "no API costs". Use when appropriate context detected. Trigger with relevant phrases based on skill purpose.

1167

backtesting-trading-strategies

jeremylongshore

Backtest crypto and traditional trading strategies against historical data. Calculates performance metrics (Sharpe, Sortino, max drawdown), generates equity curves, and optimizes strategy parameters. Use when user wants to test a trading strategy, validate signals, or compare approaches. Trigger with phrases like "backtest strategy", "test trading strategy", "historical performance", "simulate trades", "optimize parameters", or "validate signals".

1071

generating-database-seed-data

jeremylongshore

Process this skill enables AI assistant to generate realistic test data and database seed scripts for development and testing environments. it uses faker libraries to create realistic data, maintains relational integrity, and allows configurable data volumes. u... Use when working with databases or data models. Trigger with phrases like 'database', 'query', or 'schema'.

1033

cursor-codebase-indexing

jeremylongshore

Execute set up and optimize Cursor codebase indexing. Triggers on "cursor index setup", "codebase indexing", "index codebase", "cursor semantic search". Use when working with cursor codebase indexing functionality. Trigger with phrases like "cursor codebase indexing", "cursor indexing", "cursor".

885

testing-mobile-apps

jeremylongshore

Execute mobile app testing on iOS and Android devices/simulators. Use when performing specialized testing. Trigger with phrases like "test mobile app", "run iOS tests", or "validate Android functionality".

810

You might also like

sentry-rate-limits

jeremylongshore

Manage Sentry rate limits and quota optimization. Use when hitting rate limits, optimizing event volume, or managing Sentry costs. Trigger with phrases like "sentry rate limit", "sentry quota", "reduce sentry events", "sentry 429".

120

optimizing-performance

CloudAI-X

Analyzes and optimizes application performance across frontend, backend, and database layers. Use when diagnosing slowness, improving load times, optimizing queries, reducing bundle size, or when asked about performance issues.

113

azure-monitor-opentelemetry-py

microsoft

Azure Monitor OpenTelemetry Distro for Python. Use for one-line Application Insights setup with auto-instrumentation. Triggers: "azure-monitor-opentelemetry", "configure_azure_monitor", "Application Insights", "OpenTelemetry distro", "auto-instrumentation".

01

klingai-prod-checklist

jeremylongshore

Execute pre-launch production readiness checklist for Kling AI. Use when preparing to deploy video generation to production. Trigger with phrases like 'klingai production', 'kling ai go-live', 'klingai launch checklist', 'deploy klingai'.

10

ascend-profiling-analysis

Ascend

Analyze Ascend NPU profiling data to identify training performance bottlenecks. Breaks down step-level time into compute, unoverlapped communication, and freetime; within compute, analyzes compute vs memory-bound ratios and cube vs vector utilization to summarize the model's performance bottleneck.

00

python-performance-optimization

wshobson

Profile and optimize Python code using cProfile, memory profilers, and performance best practices. Use when debugging slow Python code, optimizing bottlenecks, or improving application performance.

27131

Search skills

Search the agent skills registry