Ramp calls dozens of third-party APIs (Finicity, Teller, Zendesk, Salesforce) that each impose their own quotas, runs periodic Celery tasks across its whole user base, and wanted to rate-limit inbound traffic by authenticated user rather than by IP. All three needs pointed at the same missing piece: a rate limiter that was accurate across every worker and server, not just within one.

Ramp's existing approach relied on Celery's built-in per-task rate limiting. That limit applied per worker, not globally, so enforcing a true system-wide rate required an engineer to know the queue's worker count and autoscaling behavior and manually divide the desired limit across workers -- a number that went stale the moment worker count changed. Under certain Celery prefetch configurations, rate-limited tasks could even block a worker from picking up new work, stalling entire queues.

Ramp evaluated fixed-window, sliding-window, and leaky-bucket algorithms before settling on the Generic Cell Rate Algorithm (GCRA), a leaky-bucket variant that only needs to store a single computed timestamp per key instead of a full request log. They implemented it against Redis, adding a distributed lock to close a race-condition gap in the reference implementations and using Redis's server time instead of each app server's clock to avoid drift between machines.

The result was a single rate-limiting framework Ramp could point at all three use cases -- third-party API calls, global Celery task throttling, and per-user inbound API limits -- without an engineer needing to reason about worker counts at all.

A global GCRA rate limiter backed by Redis

Storing one TAT value per key is far cheaper than a sliding window's full request log, so the limiter stays fast even at Ramp's request volume.

Reading current time from Redis itself, rather than from whichever app server handles the request, removes clock drift as a source of inconsistent enforcement.

A Redis lock around the check-and-set closes the race condition where two concurrent requests could both read a stale TAT and both get approved.

Building one general framework instead of a one-off limiter meant the same code could serve third-party quotas, Celery task throttling, and per-user API limits without duplicated logic.

A rate limit enforced per-process only approximates a global limit; centralizing the counter in a shared, lockable store is what makes the number actually mean what it says.

Ramp rolled the GCRA-on-Redis limiter out to the three use cases described in the post -- global third-party API quotas, Celery task throttling, and inbound per-user API limiting -- with unit tests and manual verification, and said it planned to extend the same framework to new rate-limiting algorithms as further use cases came up.

FOLLOW THE EVIDENCE

The sources

  1. Rate limiting with Redis builders.ramp.com