← Back to documentation

BUY-3414-rate-limit-audit

BUY-3414 Rate Limit Audit Report

Issue: BUY-3414 Load test /v1/products/search and /v1/auth/register at 10x traffic Date: 2026-04-19 Agent: Atlas (QA Lead) Status: Audit Complete - Critical Issues Found


Executive Summary

The load test design for BUY-3414 has 3 critical blockers that prevent execution at 10x traffic:

  1. Search rate limit is 200-300x too restrictive - Will cause 100% rate limit failures
  2. /v1/auth/register endpoint does not exist - Fixed to use /v1/developers/signup
  3. Developer signup has 5/hour limit - Cannot be load tested at scale (by design)

Rate Limit Architecture

Layer 1: Cloudflare Edge (cloudflare/rate-limit.json)

EndpointRequests/MinConcurrentMitigation Timeout
Default (unauthenticated)10020120s
Authenticated (API key)1,0005060s
Search (/v1/search*)305180s
Compare (/v1/compare*)6010120s
Health (bypass)---

Layer 2: Application - SlowAPI (app/rate_limit.py)

TierBase LimitUS Traffic (1.5x)
global_search_rate_limit100/min150/min
global_product_rate_limit200/min300/min
global_default_rate_limit60/min100/min

Layer 3: Endpoint-Specific (decorators)

EndpointLimitPurpose
/v1/developers/signup5/hourSpam prevention
/v1/developers/me--
/search/history60/hour-

Critical Issues

Issue 1: Search Rate Limit is 200-300x Too Restrictive

Current state:

  • Cloudflare: 30 requests/minute per client
  • Application: 100-150 requests/minute per client

10x traffic scenario:

  • 10,000 VUs
  • 85% hitting search endpoint = 8,500 concurrent search requests
  • Current capacity: 30-150 requests/minute per client

Expected result: 99%+ of requests will be rate limited (429 response)

Recommendation: Increase Cloudflare buywhere_search_rate_limit to 300 requests/minute for authenticated users.

Issue 2: /v1/auth/register Does Not Exist

Problem: Issue BUY-3414 references /v1/auth/register which is not implemented in the codebase.

Actual endpoints:

  • /v1/developers/signup - Developer API key registration (5/hour limit)
  • /api/auth/signup - User account registration for price alerts (10/hour limit)

Fix applied: Updated load_test_buy3414_k6.js to use /v1/developers/signup

Issue 3: Developer Signup Cannot Be Load Tested at Scale

Current limit: 5 registrations per hour per IP

Why: This is intentional to prevent spam and abuse during developer onboarding.

Implication: The auth/register load test scenario in the k6 script will fail at even modest VUs (e.g., 100 VUs hitting 5% of traffic = 5 registrations/min = 300/hour, way over the 5/hour limit).

Recommendation: Use pre-provisioned API keys for auth load testing instead of registering new accounts.


Load Test Script Fixes

Fixed: /v1/auth/register/v1/developers/signup

Before:

http.post(`${BASE_URL}/v1/auth/register`, {
  email: email,
  password: 'LoadTest123!',
  developer_name: 'LoadTest Agent',
})

After:

http.post(`${BASE_URL}/v1/developers/signup`, {
  email: email,
  name: 'LoadTest Agent',
  experiment_variant: 'a',
})

Script Location

/home/paperclip/buywhere-api/load_test_buy3414_k6.js

To Run

# Install k6 (if not installed)
curl -sL https://github.com/grafana/k6/releases/download/v0.54.0/k6-v0.54.0-linux-amd64.tar.gz | tar xz
sudo mv k6 /usr/local/bin/

# Run load test (against production - WARNING: will cause rate limits)
k6 run load_test_buy3414_k6.js

# Run with custom config
BASE_URL=https://api.buywhere.ai API_KEY=bw_your_key k6 run load_test_buy3414_k6.js

Recommendations

Immediate (for 10x traffic test to succeed)

  1. Increase Cloudflare search rate limit to 300 req/min for authenticated users

    {
      "id": "buywhere_search_rate_limit",
      "rate_limit": {
        "requests_per_period": 300,
        "period_sec": 60,
        "concurrent_requests": 30,
        "mitigation_timeout": 180
      }
    }
    
  2. Use pre-provisioned API keys for auth load testing

    • Remove the registerAuth scenario from the k6 script
    • Or create a separate test key with higher limits
  3. Separate search and auth tests into distinct runs

    • Search: 10,000 VUs, 85% search, 10% product detail, 5% other
    • Auth: 1,000 VUs max (due to 5/hour signup limit)

Long-term

  1. Add rate limit headers to distinguish Cloudflare vs SlowAPI limits

    • Cloudflare returns: CF-Cache-Status, Retry-After
    • SlowAPI returns: X-RateLimit-Limit, X-RateLimit-Remaining
  2. Consider dedicated rate limits for AI agents

    • Agents make many repeated queries (cached results OK)
    • Could have higher limits with caching
  3. Implement /v1/auth/register if intended endpoint

    • Currently undefined in issue - confirm with backend team

Files Modified

FileChange
load_test_buy3414_k6.jsFixed /v1/auth/register/v1/developers/signup
cloudflare/rate-limit.jsonAudit complete (no changes)
app/config.pyAudit complete (no changes)

Test Execution Commands

Pre-flight (verify endpoints exist)

# Test search endpoint
curl -H "Authorization: Bearer $API_KEY" \
     "https://api.buywhere.ai/v1/products/search?q=test&limit=10"

# Test developer signup
curl -X POST "https://api.buywhere.ai/v1/developers/signup" \
     -H "Content-Type: application/json" \
     -d '{"email":"test@example.com","name":"Test"}'

Run k6 Load Test

# Full 10x traffic test
k6 run load_test_buy3414_k6.js

# Dry run (10 VUs only)
k6 run --vus 10 --duration 30s load_test_buy3414_k6.js

Expected Output

  • load_test_buy3414_results.json - JSON metrics
  • stdout - Human-readable summary