Token bucket rate limiting per API key on API Gateway + Lambda, usage plans not granular enough?
by ClickOk5811
Context: I'm running a public API on API Gateway + Lambda, with DynamoDB behind it. Endpoints have very different backend costs, cheap reads vs. a couple of routes that kick off heavier aggregation work. Currently using API Gateway usage plans with a single throttle limit per API key, applied flat across all routes. The problem: usage plans throttle by requests/second regardless of which route is hit, so a client hammering cheap GETs eats the same budget as one calling the expensive routes, and there's no way (as far as I can find) to weight individual routes differently within a single usage plan without splitting them into separate API Gateway stages/plans per cost tier, which gets awkward to manage as the number of "cost classes" grows. What I've looked at so far: Per-stage/per-plan splitting: works, but means maintaining N usage plans and N sets of API keys per client if a client needs access to routes at more than one cost tier. Custom Lambda authorizer + DynamoDB counter: doing weighted token-bucket logic myself (consume different token amounts per route, check/decrement atomically via DynamoDB conditional writes), seems doable but adds a DynamoDB read/write on every request just for the rate-limit check, plus I'd be reimplementing throttling that API Gateway mostly already does for free. Briefly looked at whether Lambda reserved/provisioned concurrency per function could act as an implicit cost-based limiter (route the expensive endpoint through its own function with tighter concurrency), but that limits total throughput, not per-client fairness. Has anyone actually shipped weighted/cost-based rate limiting on top of API Gateway usage plans, or does everyone end up rolling their own with a Lambda authorizer + DynamoDB/ElastiCache counter once costs diverge enough between routes? And if you rolled your own, did you keep API Gateway's built-in throttling as a coarse backstop on top of it, or drop it entirely in favor of the custom logic? submitted by /u/ClickOk5811 to r/aws [link] [comments]