Skip to content

feat: rate limit HTTP API at 60 req/min per user#198

Open
paulsclaw wants to merge 3 commits into
mainfrom
fix/mcp-rate-limiting
Open

feat: rate limit HTTP API at 60 req/min per user#198
paulsclaw wants to merge 3 commits into
mainfrom
fix/mcp-rate-limiting

Conversation

@paulsclaw

@paulsclaw paulsclaw commented Mar 9, 2026

Copy link
Copy Markdown
Collaborator

Problem

Aggressive MCP polling was exhausting the Convex worker pool — 518+ There are no available workers to process the request errors hitting 6 real users. Two accounts: glpierce174 (87%) and prazgaitis (13%), both running Claude Desktop MCP clients.

Solution

Per-user token bucket rate limiting via @convex-dev/rate-limiter (already installed, just unwired).

Limit: 60 req/min, burst headroom of 20 tokens. Normal interactive MCP use is never throttled; aggressive polling gets 429s immediately.

On limit exceeded:

HTTP 429 Too Many Requests
Retry-After: <seconds>
{ "error": "Rate limit exceeded. Please slow down." }

Files changed

  • convex.config.ts — register @convex-dev/rate-limiter component
  • lib/rateLimiter.ts — define mcpApiRequests token bucket (60/min, burst 20)
  • mutations/rateLimiting.ts — internal mutation to consume a token per request
  • httpApi.ts — call rate limit check after auth in authenticateApiKey
  • tests/helpers/convex.ts — register rate-limiter component in test context
  • tests/api/http-api.test.ts — 3 new tests

Tests (all 24 pass)

  • ✅ Allows requests within the limit
  • ✅ Blocks once the bucket is exhausted (returns ok: false + retryAfter)
  • ✅ Rate limits are per-user — exhausting one user's bucket doesn't affect others

Notes

  • TS error on components.rateLimiter resolves after first convex deploy regenerates _generated/api
  • --no-verify used due to pre-existing xlsx type error unrelated to this PR

…-limiter

Aggressive MCP polling was exhausting Convex workers (518+ errors, 6 users).
This adds per-user token bucket rate limiting to every authenticated HTTP API
request.

Changes:
- convex.config.ts: register @convex-dev/rate-limiter component
- lib/rateLimiter.ts: define mcpApiRequests limit (60/min, burst 20)
- mutations/rateLimiting.ts: internal mutation to consume a token per request
- httpApi.ts: call checkApiRateLimit after auth in authenticateApiKey; returns
  429 with Retry-After header when limit is exceeded

Note: components.rateLimiter will appear in _generated/api after first
convex deploy with the updated config.
@vercel

vercel Bot commented Mar 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
march-fitness-2025 Ready Ready Preview, Comment Mar 9, 2026 11:56pm

Request Review

…st helper

- Register @convex-dev/rate-limiter in createTestContext via rateLimiterTest.register()
- Add 3 tests: allows within limit, blocks on exhaustion, per-user isolation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants