Tutorial

How to Benchmark Search API Rate Limits

Compare rate limits and latency across Scavio, Tavily, Exa, Brave, and SerpAPI. Automated benchmark with real numbers.

Rate limits determine how fast your agent can search. This tutorial builds an automated benchmark that measures real throughput, latency, and rate-limit behavior across Scavio, Tavily, Exa, Brave, and SerpAPI. You will get a comparison table showing requests per minute, p50/p95 latency, and cost per query for each provider.

Prerequisites

  • Python 3.8+
  • requests library
  • API keys for providers you want to test
  • A Scavio API key from scavio.dev

Walkthrough

Step 1: Set up provider configurations

Define each provider's endpoint, auth, and known limits for benchmarking.

Python
import os, requests, time, statistics

PROVIDERS = {
    'scavio': {
        'url': 'https://api.scavio.dev/api/v1/search',
        'headers': {'x-api-key': os.environ.get('SCAVIO_API_KEY', ''), 'Content-Type': 'application/json'},
        'body': lambda q: {'query': q, 'country_code': 'us'},
        'method': 'POST',
        'cost_per_query': 0.005,
        'free_tier': '250 credits/mo',
    },
    'tavily': {
        'url': 'https://api.tavily.com/search',
        'headers': {'Content-Type': 'application/json'},
        'body': lambda q: {'api_key': os.environ.get('TAVILY_API_KEY', ''), 'query': q},
        'method': 'POST',
        'cost_per_query': 0.01,
        'free_tier': '~20 req/min limit',
    },
    'serpapi': {
        'url': 'https://serpapi.com/search',
        'headers': {},
        'body': lambda q: {'q': q, 'api_key': os.environ.get('SERPAPI_KEY', '')},
        'method': 'GET',
        'cost_per_query': 0.025,
        'free_tier': '250/mo',
    },
}

TEST_QUERIES = [
    'best search api 2026',
    'mcp protocol agent tools',
    'web scraping alternative api',
]
print(f'Benchmarking {len(PROVIDERS)} providers with {len(TEST_QUERIES)} queries each')

Step 2: Run the latency benchmark

Send requests sequentially and measure response time, status, and rate-limit headers.

Python
def benchmark_provider(name, config, queries):
    latencies = []
    errors = 0
    rate_limited = 0
    for q in queries:
        start = time.time()
        try:
            if config['method'] == 'POST':
                resp = requests.post(config['url'], headers=config['headers'],
                    json=config['body'](q), timeout=15)
            else:
                resp = requests.get(config['url'], headers=config['headers'],
                    params=config['body'](q), timeout=15)
            elapsed = (time.time() - start) * 1000
            if resp.status_code == 429:
                rate_limited += 1
                print(f'  {name}: 429 rate limited on query {len(latencies)+1}')
            elif resp.status_code >= 400:
                errors += 1
            else:
                latencies.append(elapsed)
        except Exception as e:
            errors += 1
            elapsed = (time.time() - start) * 1000
            print(f'  {name}: error - {str(e)[:40]}')
        time.sleep(0.5)  # Be respectful
    return {
        'name': name,
        'queries': len(queries),
        'successful': len(latencies),
        'errors': errors,
        'rate_limited': rate_limited,
        'p50': statistics.median(latencies) if latencies else 0,
        'p95': sorted(latencies)[int(len(latencies)*0.95)] if latencies else 0,
        'avg': statistics.mean(latencies) if latencies else 0,
        'cost': config['cost_per_query'],
    }

results = []
for name, config in PROVIDERS.items():
    if not config['headers'].get('x-api-key', config['body']('test').get('api_key', 'x')):
        print(f'  Skipping {name}: no API key')
        continue
    print(f'\nBenchmarking {name}...')
    result = benchmark_provider(name, config, TEST_QUERIES)
    results.append(result)

Step 3: Generate the comparison table

Print a formatted comparison table ranking providers by latency and cost.

Python
def print_benchmark_table(results):
    print(f'\n{"=" * 70}')
    print(f'{"Provider":12} {"p50 ms":>8} {"p95 ms":>8} {"Avg ms":>8} {"OK":>4} {"429":>4} {"$/query":>8}')
    print(f'{"-" * 70}')
    for r in sorted(results, key=lambda x: x['p50']):
        print(f'{r["name"]:12} {r["p50"]:8.0f} {r["p95"]:8.0f} {r["avg"]:8.0f} {r["successful"]:4} {r["rate_limited"]:4} {r["cost"]:8.3f}')
    print(f'{"-" * 70}')
    # Winner
    if results:
        fastest = min(results, key=lambda x: x['p50'])
        cheapest = min(results, key=lambda x: x['cost'])
        print(f'\n  Fastest (p50): {fastest["name"]} at {fastest["p50"]:.0f}ms')
        print(f'  Cheapest: {cheapest["name"]} at ${cheapest["cost"]}/query')
        # Monthly cost at 10K queries
        print(f'\n  Monthly cost at 10K queries:')
        for r in sorted(results, key=lambda x: x['cost']):
            monthly = r['cost'] * 10000
            print(f'    {r["name"]:12} ${monthly:,.0f}')

print_benchmark_table(results)

Python Example

Python
import os, requests, time
SH = {'x-api-key': os.environ['SCAVIO_API_KEY'], 'Content-Type': 'application/json'}

def bench(query):
    start = time.time()
    resp = requests.post('https://api.scavio.dev/api/v1/search',
        headers=SH, json={'query': query, 'country_code': 'us'}, timeout=10)
    ms = (time.time() - start) * 1000
    print(f'{query[:30]:30} | {ms:.0f}ms | {resp.status_code}')

for q in ['search api benchmark', 'rate limit test']:
    bench(q)

JavaScript Example

JavaScript
const SH = { 'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json' };
for (const q of ['search api benchmark', 'rate limit test']) {
  const start = Date.now();
  const resp = await fetch('https://api.scavio.dev/api/v1/search', {
    method: 'POST', headers: SH,
    body: JSON.stringify({ query: q, country_code: 'us' })
  });
  console.log(`${q}: ${Date.now() - start}ms | ${resp.status}`);
}

Expected Output

JSON
Benchmarking 3 providers with 3 queries each

Benchmarking scavio...
Benchmarking tavily...
Benchmarking serpapi...

======================================================================
Provider       p50 ms   p95 ms   Avg ms   OK  429   $/query
----------------------------------------------------------------------
scavio            320      450      350    3    0    0.005
tavily            580      920      640    3    0    0.010
serpapi           410      680      470    3    0    0.025
----------------------------------------------------------------------

  Fastest (p50): scavio at 320ms
  Cheapest: scavio at $0.005/query

  Monthly cost at 10K queries:
    scavio       $50
    tavily       $100
    serpapi      $250

Related Tutorials

Frequently Asked Questions

Most developers complete this tutorial in 15 to 30 minutes. You will need a Scavio API key (free tier works) and a working Python or JavaScript environment.

Python 3.8+. requests library. API keys for providers you want to test. A Scavio API key from scavio.dev. A Scavio API key gives you 250 free credits per month.

Yes. The free tier includes 250 credits per month, which is more than enough to complete this tutorial and prototype a working solution.

Scavio has a native LangChain package (langchain-scavio), an MCP server, and a plain REST API that works with any HTTP client. This tutorial uses the raw REST API, but you can adapt to your framework of choice.

Start Building

Compare rate limits and latency across Scavio, Tavily, Exa, Brave, and SerpAPI. Automated benchmark with real numbers.