The idea of a leaky-bucket rate limiter is as follows. There is a bucket with a limited capacity for water, and each request adds some water to the bucket.

Add water

If a request would have overflowed the bucket then it is rejected instead. The capacity of the bucket is written LC.

Reject on overflow

The bucket leaks its contents at a particular rate, r, freeing up capacity for further requests.

Leak at fixed rate

As a function of time the level L of water in the bucket follows a path like this as requests arrive.

Level vs time

It is possible to simulate the leak of water from the bucket with a simple loop that subtracts water from the bucket on each iteration, or else on each request, the new level L’ of water in the bucket can be calculated as follows.

On each request

It follows that the amount of water that can be added to the bucket in a time interval Δt is at most rΔt + LC.

This whole post is available in one image.