Skip to content

feat: add transparent rate limiting to prevent AWS API throttling#240

Merged
karl-cardenas-coding merged 1 commit intokarl-cardenas-coding:mainfrom
casey-robertson-paypal:feat/add-rate-limiting
Mar 7, 2026
Merged

feat: add transparent rate limiting to prevent AWS API throttling#240
karl-cardenas-coding merged 1 commit intokarl-cardenas-coding:mainfrom
casey-robertson-paypal:feat/add-rate-limiting

Conversation

@casey-robertson-paypal
Copy link
Copy Markdown
Contributor

@casey-robertson-paypal casey-robertson-paypal commented Mar 7, 2026

Refs #241

Summary

  • Adds a token-bucket rate limiter (golang.org/x/time/rate) at 10 requests/second to proactively pace AWS API calls
  • Prevents TooManyRequestsException errors when processing environments with many Lambda functions (60+ observed to trigger throttling)
  • Fully transparent — no new CLI flags, no user configuration needed
  • golang.org/x/time was already an indirect dependency; promoted to direct with no new transitive deps

Problem

In environments with many Lambda functions, the tool fires ListVersionsByFunction, ListAliases, and DeleteFunction calls in tight sequential loops with no pacing. The AWS Lambda control plane API enforces a hard limit of 15 requests/second shared across all control plane APIs (excluding invocation, GetFunction, and GetPolicy). This limit cannot be increased. The SDK's standard retry (3 attempts) cannot recover from sustained throttling:

time=03/05/26 level=error msg="operation error Lambda: ListAliases, exceeded maximum number of attempts, 3,
  https response error StatusCode: 429, RequestID: 29affba0-..., TooManyRequestsException: Rate exceeded"
time=03/05/26 level=fatal msg="ERROR: Failed to retrieve Lambda version list."

With 60 Lambdas and --skip-aliases, the tool makes 120+ control plane API calls in rapid succession — exhausting the shared 15 rps budget within ~4 seconds.

Approach

A rate.Limiter set to 10 rps (leaving headroom below the hard 15 rps limit) is created once per execution and passed to all functions that make AWS API calls. limiter.Wait(ctx) is called before each API request, which blocks only when the request rate would exceed the limit.

The rate is hardcoded rather than user-configurable because the AWS control plane rate limit is a fixed, non-adjustable constant — there is no correct user-chosen value other than "below 15." Debug-level logging (--verbose) shows when the limiter is active.

Changes

File Change
cmd/clean.go Add defaultAPIRPS constant, create rate.Limiter, call limiter.Wait(ctx) before each AWS API call
cmd/clean_test.go 3 new unit tests for limiter behavior; updated existing tests with unlimited limiter
cmd/root_test.go Updated function calls with unlimited limiter
go.mod Promote golang.org/x/time from indirect to direct

Test plan

  • All existing unit tests pass with unlimited limiter (no behavior change)
  • TestRateLimiterPacesRequests — verifies limiter enforces pacing at configured rate
  • TestRateLimiterUnlimited — verifies rate.Inf imposes no delay
  • TestRateLimiterContextCancellation — verifies limiter respects context cancellation
  • go vet ./... clean
  • Integration tests pass (Docker/LocalStack — all 14 tests)

Adds a token-bucket rate limiter (golang.org/x/time/rate) at 10
requests/second to proactively pace AWS API calls. This prevents
TooManyRequestsException errors when processing environments with many
Lambda functions, where tight sequential loops of ListVersionsByFunction,
ListAliases, and DeleteFunction calls exceed the 15 rps per-account API
limit.

The rate limiting is transparent — no user configuration required. The
limiter is applied before each AWS API call in:
- getAllLambdaVersion (ListVersionsByFunction and ListAliases pagination)
- getAllLambdas with custom list (GetFunction per Lambda)
- deleteLambdaVersion (DeleteFunction per version)

Made-with: Cursor
@casey-robertson-paypal casey-robertson-paypal changed the title feat: add application-level rate limiting to prevent AWS API throttling feat: add transparent rate limiting to prevent AWS API throttling Mar 7, 2026
@karl-cardenas-coding
Copy link
Copy Markdown
Owner

Ran test suit locally - 👍🏻

@karl-cardenas-coding karl-cardenas-coding merged commit c591145 into karl-cardenas-coding:main Mar 7, 2026
3 of 4 checks passed
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