# Caddy Rate_limit Configuration


## Why Rate Limiting

Public-facing services inevitably face traffic abuse:

- Crawlers scraping the entire site
- Brute-force login attempts
- CC attacks consuming bandwidth
- Script kiddies hammering APIs

Rate limiting is the most basic defense. Caddy's `rate_limit` plugin implements a **token bucket algorithm**, performing rate checks before requests reach the reverse proxy, preventing pressure from propagating to backend services.

## Defining a Rate Limit Zone

```caddyfile
example.com {
    rate_limit {
        zone dynamic_zone {
            key {client_ip}
            events 50
            window 10s
        }
        log_key
    }
}
```

### Zone Parameters

- **`key {client_ip}`**: Differentiate by client IP. When `trusted_proxies` is configured, this uses the real client IP extracted from `X-Forwarded-For`, not the proxy's IP.
- **`events 50`**: Maximum number of requests allowed within the window.
- **`window 10s`**: Time window - 10 seconds here.

Combined: **each client IP can make at most 50 requests per 10 seconds**. Excess requests receive a 429 Too Many Requests response.

### log_key for Debugging

```caddyfile
log_key
```

When enabled, Caddy logs the rate-limited client key (IP address). Output looks like:

```
rate_limit exceeded for key: 192.168.1.100
```

When deploying a new service, enable `log_key` first to observe normal request patterns, then determine appropriate thresholds.

## References

- [caddy-ratelimit](https://github.com/mholt/caddy-ratelimit)
- [Caddy Log Directive](https://caddyserver.com/docs/caddyfile/directives/log)
- [Building Custom Caddy with xcaddy](/posts/custom-caddy-build/)
- [Caddy Cloudflare DNS-01 Challenge](/posts/caddy-cloudflare-dns-challenge/)


---

> Author: Nite  
> URL: https://www.nite07.com/en/posts/caddy-rate-limit/  

