Middleware
Rate Limiter
Limit request rates per client, per API key, or globally with a token bucket.
RateLimiter refuses requests that arrive faster than a set rate, answering 429 Too Many Requests. It uses a token bucket: each request spends one token, and tokens refill at a steady rate up to a maximum burst.
For most public APIs, limit per client IP:
app.Use(middleware.IPRateLimiter(20, 40)) // 20 requests per second, bursts up to 40Configure trusted proxies first when the app runs behind a load balancer. Otherwise every request shares the load balancer’s IP and one bucket.
Choose what to limit by
Section titled “Choose what to limit by”| Constructor | One bucket per |
|---|---|
IPRateLimiter(rate, burst) |
Client IP, from c.IP() |
RateLimiter(config) with KeyGenerator |
Whatever the function returns, such as an API key or user ID |
RateLimiter() with no arguments |
Nothing: one bucket shared by every request |
Limit by API key
Section titled “Limit by API key”app.Use(middleware.RateLimiter(middleware.RateLimiterConfig{ Rate: 30, // tokens per second Capacity: 60, // maximum burst KeyGenerator: func(c *zinc.Context) string { return c.GetHeader("X-API-Key") }, LimitReachedHandler: func(c *zinc.Context) error { c.SetHeader("Retry-After", "1") return c.Status(zinc.StatusTooManyRequests).JSON(zinc.Map{"error": "rate limit exceeded"}) },}))When you pass a config, set both Rate and Capacity. They default to 0, which rejects every request.
Configuration
Section titled “Configuration”| Field | Default | Meaning |
|---|---|---|
Rate |
10 without a config, else required |
Tokens added per second |
Capacity |
10 without a config, else required |
Largest burst |
KeyGenerator |
none | Returns the bucket key for a request |
IPLookup |
none | Returns a client identity; used when KeyGenerator is not set |
StatusCode |
429 |
Status when the limit is hit |
LimitReachedHandler |
plain-text 429 |
Writes the response when the limit is hit |
Keys are chosen in this order: KeyGenerator, then IPLookup, then one global bucket.
Memory use
Section titled “Memory use”Each distinct key keeps its bucket for the life of the process. With keys from a bounded set, such as your API keys or user IDs, that is fine. Per-IP limiting on public traffic grows with the number of distinct clients. Restart periodically, or enforce the limit at your load balancer or API gateway.
Related
Section titled “Related”- Throttle limits concurrent requests instead of request rate.
- Client IP and Proxies makes per-IP keys accurate.
Keyed limiters retain at most MaxKeys buckets (default 10,000) with keys of at most MaxKeyBytes bytes (default 256). When full, new keys receive the configured limit response; existing quotas remain in force. Idle buckets expire after IdleTTL (default five minutes), once their tokens have fully replenished. Cleanup is bounded and runs during requests. Choose the capacity for your expected client population; saturation deliberately denies new clients rather than granting fresh quotas through eviction.
Zero Rate and Capacity use 10 tokens/second and a burst of 10. Invalid negative or non-finite settings panic during construction. StatusCode defaults to 429 and is respected by the default rejection handler. Now can supply a deterministic clock for tests.