Marcio Cunha

Distributed Rate Limiting in Serverless with Token Bucket and Redis Cluster

Learn how to implement scalable traffic control in serverless architectures using the Token Bucket algorithm integrated with a distributed Redis cluster.

Marcio Cunha•4 min
Also available in:EspañolPortuguês
Summary
  • Environments without dedicated servers require external counters to manage traffic due to unpredictable scaling behavior.
  • The Token Bucket algorithm allows controlled traffic bursts without immediately penalizing legitimate users.
  • Redis Cluster distributes control keys across multiple machines to prevent performance bottlenecks.
  • Lua scripts executed directly inside the database guarantee atomic operations without race conditions.
  • Network latency between ephemeral functions and cache nodes requires smart resilience and fallback strategies.

The Challenge of Traffic Control in Ephemeral Functions

When building modern applications using environments without dedicated servers—known in engineering as serverless architectures—the code wakes up to handle a request and goes right back to sleep. In practice, this means we do not have a centralized memory running on a fixed machine to count how many times a user has accessed the system. Each request might land on a different container scattered around the globe, turning traffic management into a fascinating engineering puzzle.

If a malicious bot decides to take down your API by firing thousands of calls per second, the cloud provider will spin up thousands of functions to try and handle them all, resulting in a staggering bill at the end of the month. To prevent this financial nightmare and keep the service stable, we need a rate limiting mechanism—an intelligent digital bouncer that decides who gets in and who waits in line based on strict consumption rules.

Understanding the Token Bucket Dynamics

There are several ways to limit traffic, but the algorithm known as Token Bucket stands out for its flexibility. Imagine a bucket that receives tokens at a constant rate every second until it reaches a maximum limit. Each time a user makes a request, the system withdraws a token from this bucket. In practice, this means if the bucket has tokens, the request goes through immediately; if it is empty, access is blocked or queued.

The great advantage of this model over simple fixed-time counters is its tolerance for legitimate usage spikes. If a user clicks several buttons quickly, they consume the tokens accumulated during idle periods without being unfairly banned. To implement this at scale, we need an ultra-fast in-memory database that can update and read these tokens in microseconds, which is where Redis comes into play.

Why Redis Cluster Becomes the Ideal Choice

Redis is a data storage system based on RAM that answers queries almost instantly, acting as an ultra-fast message center. When operating in ultra-high-traffic corporate environments, a single Redis server can become a bottleneck or crash from overwork. This is the scenario where we adopt Redis Cluster, a topology that splits data across several independent interconnected nodes.

In practice, the cluster spreads different users' token buckets across multiple distinct machines. This guarantees high availability and resilience: if one cluster server fails for any reason, the rest of the system keeps running without taking down the entire application. However, coordinating distributed keys requires extra attention to prevent mathematical inconsistencies in the token balance.

Ensuring Atomic Consistency with Lua Scripts

The greatest danger in distributed systems is the famous race condition, which happens when two requests from the same user arrive at the exact same millisecond on different Redis nodes. If both read the token balance before any update occurs, the system might allow double the authorized limit. To solve this without locking the entire system, we use scripts written in the Lua language running directly inside Redis itself.

In practice, the Lua script acts as an unbreakable black box: Redis executes all instructions in the script at once, from start to finish, without letting any other operation interfere in the middle. This guarantees atomicity, ensuring that the calculation of refilling and deducting tokens happens in perfect synchronization, regardless of how many instances are calling the database simultaneously.

Resilience, Silent Failures, and Fallback Strategies

No cloud architecture is immune to network glitches or temporary infrastructure outages. If our Redis cluster becomes unreachable for a few seconds due to maintenance or instability, our API cannot simply stop working and reject all legitimate clients. We need to plan fallback strategies, which act as an escape plan when the primary system fails.

In practice, we configure the serverless function code to detect Redis connection failures after a strict time limit, such as fifty milliseconds. If the database fails, the system assumes a tolerant mode and allows traffic to pass temporarily, prioritizing business availability over blocking users due to internal infrastructure issues.

Final Considerations on Scalability and Control

Developing a robust traffic control strategy in serverless architectures requires balancing speed, mathematical precision, and fault tolerance. The combined use of the Token Bucket algorithm with a distributed Redis cluster offers a mature solution to handle millions of requests without compromising cloud budgets or user experience. The secret to success lies in operational simplicity and the correct use of in-memory atomic operations.