NAME

PAGI::Middleware::RateLimit - Request rate limiting middleware

SYNOPSIS

use PAGI::Middleware::Builder;

my $app = builder {
    enable 'RateLimit',
        requests_per_second => 10,
        burst => 20,
        key_generator => sub  {
    my ($scope) = @_; $scope->{client}[0] };
    $my_app;
};

DESCRIPTION

PAGI::Middleware::RateLimit implements token bucket rate limiting per client. Clients exceeding the rate limit receive 429 Too Many Requests.

CONFIGURATION

  • requests_per_second (default: 10)

    Average requests allowed per second.

  • burst (default: 20)

    Maximum burst size (bucket capacity).

  • key_generator (default: client IP)

    Coderef to generate rate limit key from $scope.

  • backend (default: in-memory)

    Rate limit storage backend. Can be 'memory' or a custom object implementing get/set methods.

  • cleanup_interval (default: 60)

    Seconds between periodic cleanup of stale buckets.

  • max_buckets (default: 10000)

    Maximum number of tracked client buckets. When exceeded, the oldest half are evicted as a safety valve.

RATE LIMITING ALGORITHM

This middleware uses the token bucket algorithm:

  • Each client has a "bucket" that holds tokens

  • Tokens are added at a constant rate (requests_per_second)

  • The bucket has a maximum capacity (burst)

  • Each request consumes one token

  • If no tokens available, request is rejected

This allows short bursts of traffic while maintaining an average rate.

MULTI-WORKER NOTE

The in-memory bucket storage is per-process. In a pre-fork multi-worker setup each worker maintains its own independent rate limit state, so the effective rate limit is multiplied by the number of workers. For accurate cross-worker rate limiting, use an external backend such as Redis.

SEE ALSO

PAGI::Middleware - Base class for middleware