Rate limiting

Ferron implements token bucket-based rate limiting with the rate_limit directive. This helps reduce brute-force login attempts and API abuse. When a client exceeds the configured rate, the server returns a 429 Too Many Requests response with a Retry-After header.

Protect login endpoints⁠#

Apply stricter limits to authentication paths than to the rest of the site:

example.com {
    root /var/www/html

    # General traffic limit for the site.
    rate_limit {
        rate 50
        burst 100
        key remote_address
    }

    # Tighter limits for login endpoints.
    location /login {
        rate_limit {
            rate 5
            burst 10
            key remote_address
        }
    }

    location /api/auth {
        rate_limit {
            rate 5
            burst 10
            key remote_address
        }
    }
}
Note
  • Rate limiting uses a token bucket algorithm: capacity = rate + burst tokens, refilled at rate tokens per second.
  • Ferron stores rate limit buckets in memory. They do not survive configuration reloads.
Important

If Ferron is behind another proxy/load balancer, make sure the client IP is correctly resolved. See HTTP host directives for client_ip_from_header configuration.

Protect APIs with tiered limits⁠#

Use host-level and location-level limits together:

api.example.com {
    location / {
        proxy http://localhost:3000

        # Default API limit.
        rate_limit {
            rate 100
            burst 200
            key remote_address
        }
    }

    # Heavier endpoints can have stricter caps.
    location /v1/search {
        rate_limit {
            rate 20
            burst 40
            key remote_address
        }
    }

    location /v1/login {
        rate_limit {
            rate 5
            burst 10
            key remote_address
        }
    }
}
Tip

Start with permissive values. Tighten them after you observe production traffic patterns. Keep login and token endpoints on stricter limits than read-only API endpoints.

API key rate limiting⁠#

You can also key rate limits off request headers (for example, API keys):

api.example.com {
    proxy http://localhost:3000

    rate_limit {
        rate 50
        burst 100
        key request.header.X-Api-Key
    }
}

Each unique API key gets its own token bucket, independent of the client IP.

Throttling⁠#

To enable throttling for rate-limited requests, use the throttle subdirective:

api.example.com {
    proxy http://localhost:3000
    rate_limit {
        rate 50
        burst 100
        key request.header.X-Api-Key
        throttle
    }
}