Files
litellm/docs/my-website/docs/benchmarks.md
T
Alexsander Hamir 5b1fda02fb Add infrastructure recommendations to benchmarks documentation (#18264)
Added concise PostgreSQL and Redis specifications based on benchmark results and industry standards for API gateway deployments. Includes tiered recommendations for different RPS workloads, configuration best practices, and scaling guidelines.
2025-12-19 13:44:36 -08:00

7.8 KiB
Raw Blame History

import Image from '@theme/IdealImage';

Benchmarks

Benchmarks for LiteLLM Gateway (Proxy Server) tested against a fake OpenAI endpoint.

Use this config for testing:

model_list:
  - model_name: "fake-openai-endpoint"
    litellm_params:
      model: openai/any
      api_base: https://your-fake-openai-endpoint.com/chat/completions
      api_key: "test"

2 Instance LiteLLM Proxy

In these tests the baseline latency characteristics are measured against a fake-openai-endpoint.

Performance Metrics

Type Name Median (ms) 95%ile (ms) 99%ile (ms) Average (ms) Current RPS
POST /chat/completions 200 630 1200 262.46 1035.7
Custom LiteLLM Overhead Duration (ms) 12 29 43 14.74 1035.7
Aggregated 100 430 930 138.6 2071.4

4 Instances

Type Name Median (ms) 95%ile (ms) 99%ile (ms) Average (ms) Current RPS
POST /chat/completions 100 150 240 111.73 1170
Custom LiteLLM Overhead Duration (ms) 2 8 13 3.32 1170
Aggregated 77 130 180 57.53 2340

Key Findings

  • Doubling from 2 to 4 LiteLLM instances halves median latency: 200ms → 100ms.
  • High-percentile latencies drop significantly: P95 630ms → 150ms, P99 1,200ms → 240ms.
  • Setting workers equal to CPU count gives optimal performance.

Machine Spec used for testing

Each machine deploying LiteLLM had the following specs:

  • 4 CPU
  • 8GB RAM

Configuration

  • Database: PostgreSQL
  • Redis: Not used

Infrastructure Recommendations

Recommended specifications based on benchmark results and industry standards for API gateway deployments.

PostgreSQL

Required for authentication, key management, and usage tracking.

Workload CPU RAM Storage Connections
1-2K RPS 4-8 cores 16GB 200GB SSD (3000+ IOPS) 100-200
2-5K RPS 8 cores 16-32GB 500GB SSD (5000+ IOPS) 200-500
5K+ RPS 16+ cores 32-64GB 1TB+ SSD (10000+ IOPS) 500+

Configuration: Set proxy_batch_write_at: 60 to batch writes and reduce DB load. Total connections = pool limit × instances.

Redis was not used in these benchmarks but provides significant production benefits: 60-80% reduced DB load.

Workload CPU RAM
1-2K RPS 2-4 cores 8GB
2-5K RPS 4 cores 16GB
5K+ RPS 8+ cores 32GB+

Requirements: Redis 7.0+, AOF persistence enabled, allkeys-lru eviction policy.

Configuration:

router_settings:
  redis_host: os.environ/REDIS_HOST
  redis_port: os.environ/REDIS_PORT
  redis_password: os.environ/REDIS_PASSWORD

litellm_settings:
  cache: True
  cache_params:
    type: redis
    host: os.environ/REDIS_HOST
    port: os.environ/REDIS_PORT
    password: os.environ/REDIS_PASSWORD

:::tip Use redis_host, redis_port, and redis_password instead of redis_url for ~80 RPS better performance. :::

Scaling: DB connections scale linearly with instances. Consider PostgreSQL read replicas beyond 5K RPS.

See Production Configuration for detailed best practices.

Locust Settings

  • 1000 Users
  • 500 user Ramp Up

How to measure LiteLLM Overhead

All responses from litellm will include the x-litellm-overhead-duration-ms header, this is the latency overhead in milliseconds added by LiteLLM Proxy.

If you want to measure this on locust you can use the following code:

import os
import uuid
from locust import HttpUser, task, between, events

# Custom metric to track LiteLLM overhead duration
overhead_durations = []

@events.request.add_listener
def on_request(request_type, name, response_time, response_length, response, context, exception, start_time, url, **kwargs):
    if response and hasattr(response, 'headers'):
        overhead_duration = response.headers.get('x-litellm-overhead-duration-ms')
        if overhead_duration:
            try:
                duration_ms = float(overhead_duration)
                overhead_durations.append(duration_ms)
                # Report as custom metric
                events.request.fire(
                    request_type="Custom",
                    name="LiteLLM Overhead Duration (ms)",
                    response_time=duration_ms,
                    response_length=0,
                )
            except (ValueError, TypeError):
                pass

class MyUser(HttpUser):
    wait_time = between(0.5, 1)  # Random wait time between requests

    def on_start(self):
        self.api_key = os.getenv('API_KEY', 'sk-1234567890')
        self.client.headers.update({'Authorization': f'Bearer {self.api_key}'})

    @task
    def litellm_completion(self):
        # no cache hits with this
        payload = {
            "model": "db-openai-endpoint",
            "messages": [{"role": "user", "content": f"{uuid.uuid4()} This is a test there will be no cache hits and we'll fill up the context" * 150}],
            "user": "my-new-end-user-1"
        }
        response = self.client.post("chat/completions", json=payload)
        
        if response.status_code != 200:
            # log the errors in error.txt
            with open("error.txt", "a") as error_log:
                error_log.write(response.text + "\n")

LiteLLM vs Portkey Performance Comparison

Test Configuration: 4 CPUs, 8 GB RAM per instance | Load: 1k concurrent users, 500 ramp-up Versions: Portkey v1.14.0 | LiteLLM v1.79.1-stable
Test Duration: 5 minutes

Multi-Instance (4×) Performance

Metric Portkey (no DB) LiteLLM (with DB) Comment
Total Requests 293,796 312,405 LiteLLM higher
Failed Requests 0 0 Same
Median Latency 100 ms 100 ms Same
p95 Latency 230 ms 150 ms LiteLLM lower
p99 Latency 500 ms 240 ms LiteLLM lower
Average Latency 123 ms 111 ms LiteLLM lower
Current RPS 1,170.9 1,170 Same

Lower is better for latency metrics; higher is better for requests and RPS.

Technical Insights

Portkey

Pros

  • Low memory footprint
  • Stable latency with minimal spikes

Cons

  • CPU utilization capped around ~40%, indicating underutilization of available compute resources
  • Experienced three I/O timeout outages

LiteLLM

Pros

  • Fully utilizes available CPU capacity
  • Strong connection handling and low latency after initial warm-up spikes

Cons

  • High memory usage during initialization and per request

Logging Callbacks

GCS Bucket Logging

Using GCS Bucket has no impact on latency, RPS compared to Basic Litellm Proxy

Metric Basic Litellm Proxy LiteLLM Proxy with GCS Bucket Logging
RPS 1133.2 1137.3
Median Latency (ms) 140 138

LangSmith logging

Using LangSmith has no impact on latency, RPS compared to Basic Litellm Proxy

Metric Basic Litellm Proxy LiteLLM Proxy with LangSmith
RPS 1133.2 1135
Median Latency (ms) 140 132