Overview
Theratelimit middleware implements token bucket rate limiting to control request rates. It protects your application from abuse, ensures fair usage, and prevents resource exhaustion.
Use it when you need:
- API rate limiting
- Protection against brute force attacks
- Fair usage enforcement
- Resource protection
Installation
Quick Start
Configuration
Options
| Option | Type | Default | Description |
|---|---|---|---|
Rate | int | 100 | Requests allowed per interval |
Interval | time.Duration | 1m | Time window |
Burst | int | Same as Rate | Maximum burst capacity |
KeyFunc | func(*mizu.Ctx) string | Client IP | Rate limit key extractor |
Headers | bool | true | Include rate limit headers |
ErrorHandler | func(*mizu.Ctx) error | - | Custom error handler |
Skip | func(*mizu.Ctx) bool | - | Skip rate limiting |
Examples
Basic Rate Limiting
Custom Rate and Interval
With Burst
Rate Limit by API Key
Rate Limit by User
Skip Certain Requests
Custom Error Handler
Disable Headers
Different Limits for Different Routes
Tiered Rate Limits
Custom Store
Response Headers
WhenHeaders is enabled (default), these headers are included:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests allowed |
X-RateLimit-Remaining | Remaining requests in window |
X-RateLimit-Reset | Unix timestamp when limit resets |
Retry-After | Seconds until retry (when limited) |
API Reference
Functions
Store Interface
RateLimitInfo
Token Bucket Algorithm
The middleware uses the token bucket algorithm:- Bucket starts full with
Bursttokens - Requests consume one token
- Tokens refill at
RateperInterval - Burst allows temporary spikes
Technical Details
The rate limit middleware implements the token bucket algorithm, a sophisticated approach for managing request rates with support for burst traffic. The implementation details are as follows:Token Bucket Implementation
The algorithm maintains a bucket of tokens for each rate limit key:- Initialization: Each bucket starts with
Bursttokens (default equalsRate) - Token Consumption: Each request consumes exactly one token from the bucket
- Token Refill: Tokens are added continuously based on elapsed time:
- Refill rate:
Rate / Intervaltokens per second - Formula:
tokensToAdd = (Rate * elapsedSeconds) / intervalSeconds
- Refill rate:
- Capacity Limit: Bucket capacity is capped at
Bursttokens to prevent unlimited accumulation - Request Decision: Request is allowed if bucket has at least 1 token available
In-Memory Store
The defaultMemoryStore provides:
- Thread Safety: Uses
sync.Mutexfor concurrent access protection - Per-Key Tracking: Maintains separate buckets for each key (IP, user ID, API key, etc.)
- Automatic Cleanup: Background goroutine removes stale buckets after 10 minutes of inactivity
- Fractional Tokens: Uses
float64for precise token calculations during refills
Rate Limit Information
For each request, the middleware calculates and returns:- Limit: Maximum requests allowed per interval (from
Rateoption) - Remaining: Current token count (floored to nearest integer)
- Reset: Timestamp when bucket will be full again (current time +
Interval)
Best Practices
- Set reasonable limits based on expected usage
- Use different limits for different endpoints
- Include rate limit headers for client awareness
- Monitor rate limit hits for tuning
- Consider user tiers for fair access
Testing
The rate limit middleware includes comprehensive test coverage for all functionality:| Test Case | Description | Expected Behavior |
|---|---|---|
TestNew | Basic rate limiting with IP-based keys | First N requests succeed, subsequent requests return 429; different IPs tracked separately |
TestWithOptions_Headers | Rate limit headers in response | Headers include X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset |
TestWithOptions_ErrorHandler | Custom error handler for rate limit exceeded | Custom error handler called instead of default when limit exceeded |
TestWithOptions_KeyFunc | Custom key extraction function | Rate limits applied per custom key (e.g., API key) instead of IP |
TestWithOptions_Skip | Skip rate limiting for certain requests | Requests matching skip condition bypass rate limiting |
TestWithOptions_RetryAfter | Retry-After header on rate limit | Retry-After header included when request is rate limited |
TestPerSecond | PerSecond convenience function | Middleware created with per-second interval |
TestPerMinute | PerMinute convenience function | Middleware created with per-minute interval |
TestPerHour | PerHour convenience function | Middleware created with per-hour interval |
TestMemoryStore_Allow | Token bucket allows/denies requests | Allows up to limit, denies when bucket empty |
TestMemoryStore_TokenRefill | Token bucket refills over time | Tokens refill after interval allowing new requests |
TestMemoryStore_DifferentKeys | Different keys have independent buckets | Exhausting one key doesnβt affect other keys |
Related Middlewares
- circuitbreaker - Circuit breaker pattern
- timeout - Request timeout