Symfony 5.1’s rate limiter, and the two algorithms

A rate limiter is four lines of Redis and a decision between two algorithms that behave differently at the boundary, and most hand-rolled ones pick the worse of the two by accident.

framework:
  rate_limiter:
    api:
      policy: 'sliding_window'
      limit: 100
      interval: '1 minute'

    uploads:
      policy: 'token_bucket'
      limit: 10            # burst
      rate: { interval: '1 minute', amount: 5 }

# fixed_window allows 200 requests across a boundary. avoid.

A fixed window allows the full limit at the end of one window and again at the start of the next, so the effective burst is double — which is the failure mode of almost every naive implementation. A sliding window is the sensible default for an API. A token bucket is the right choice when a burst is legitimate and a sustained rate is not, which is uploads and almost nothing else.