Rate Limit Plugin
Provide request rate limiting with multiple storage backends and per-endpoint custom rules.
Overview
The Rate Limit plugin provides request rate limiting with multiple storage backends and per-endpoint custom rules to protect your application from abuse and brute force attacks.
Features
- Multiple Storage Backends — In-memory (default), Redis, or Database storage
- Custom Rules Per Endpoint — Different limits for different paths or methods
- Client IP-Based Limiting — Tracks requests by client IP address
- Standard HTTP Rate Limit Headers — Client-aware headers for rate limit information
- Automatic Cleanup — Removes expired entries to prevent memory leaks
- Fail-Open Behavior — Allows requests when storage provider errors occur
- Production Auto-Enable — Automatically enabled when
GO_ENVIRONMENT=production
Configuration
Standalone Mode:
[plugins.ratelimit]
enabled = true
window = "1m" # Time window for rate limiting (default: 1 minute)
max = 100 # Max requests per window (default: 100)
prefix = "ratelimit:" # Storage key prefix (default: "ratelimit:")
provider = "memory" # Options: memory, redis, database (default: memory)
# In-Memory storage configuration (default provider)
[plugins.ratelimit.memory]
cleanup_interval = "1m" # How often to clean expired entries (default: 1 minute)
# Database storage configuration (optional)
[plugins.ratelimit.database]
cleanup_interval = "1m" # How often to clean expired entries (default: 1 minute)
# Custom rules for specific endpoints
[plugins.ratelimit.custom_rules]
"/some/path" = { window = "5m", max = 5 } # Stricter limits
"/some/other/path" = { disabled = true } # Disable rate limiting for this pathLibrary Mode:
import (
ratelimitplugin "github.com/Authula/authula/plugins/rate-limit"
)
ratelimitplugin.New(ratelimitplugin.RateLimitPluginConfig{
Enabled: true,
Provider: ratelimitplugin.RateLimitProviderRedis,
Window: time.Minute,
Max: 100,
Prefix: "ratelimit:",
CustomRules: map[string]ratelimitplugin.RateLimitRule{
"/some/path": {
Disabled: true,
},
},
})Storage Providers
| Provider | Performance | Persistence | Best For |
|---|---|---|---|
| Memory | Fastest | No | Single-instance deployments |
| Database | Moderate | Yes | Strict audit requirements |
| Redis | Fast | Yes | Multi-instance deployments |
API Reference
The Rate Limit plugin does not expose its own HTTP endpoints. Instead, it applies rate limiting as a hook to all incoming requests.
Custom Rules
Override default rate limits for specific paths:
[plugins.ratelimit.custom_rules]
# Stricter rate limit for login attempts
"/auth/sign-in" = { window = "15m", max = 10 }
# Different limits for specific endpoint
"/some/path" = { window = "1h", max = 3 }
# Disable rate limiting for specific endpoint
"/some/path" = { disabled = true }HTTP Response Headers
The plugin adds standard rate limit headers to all responses:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests allowed in the window |
X-RateLimit-Remaining | Remaining requests in current window |
X-RateLimit-Reset | Unix timestamp when the window resets |
X-Retry-After | Seconds to wait before retry (only when rate limited) |
When rate limited:
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1738302000
X-Retry-After: 45
{
"message": "rate limit exceeded",
"retry_after": 45,
"limit": 100,
"remaining": 0
}Database Schema
Table: rate_limits
| Field | Type | Key | Description |
|---|---|---|---|
key | string | PK | Rate limit key (e.g., client IP) |
count | int | - | Current request count |
expires_at | timestamp | - | When the entry expires |
- SQLite: this table is set as a temp table to ensure it is automatically cleared on server restart.
- PostgreSQL: this table is set as an unlogged table to improve performance, with a periodic cleanup process to remove expired entries.
- MYSQL: this table is set as a MEMORY table to store data in memory for fast access, with automatic cleanup of expired entries.
Migrations are automatically handled when the plugin is initialized.
Plugin Capabilities
This plugin doesn't have any capabilities. However, it does have a global hook which is applied if the plugin is enabled and there are custom rules defined which applies rate limiting to specific endpoints.
Security Recommendations
- Client IP Detection — Uses client IP from the request. Configure
trusted_proxiesandtrusted_headersin the global security config if behind a load balancer. - Fail-Open — Provider errors allow requests through to prevent denial-of-service from rate limiter failures.
- OPTIONS Requests — Automatically skipped to prevent blocking CORS preflight requests.
- Stricter Limits for Auth Endpoints — Apply lower limits to sensitive endpoints on other plugins to prevent brute force attacks.
- Use Redis for Multi-Instance — When running multiple server instances, use Redis to share rate limit state across all instances.
