Rate Limiting
Brume Limit: define rules, evaluate with limit/check, and read X-RateLimit-* headers.
Brume Limit: define rules, evaluate with limit/check, and read X-RateLimit-* headers.
Brume Limit is a rate-limiting gateway: you define rules, evaluate requests against them with a single HTTP call, and read the standard X-RateLimit-* response headers. Every evaluation runs as one atomic Lua script against a dedicated Redis — no race windows, no double-counting, nothing for you to operate.
A rule binds five things:
| Field | Meaning |
|---|---|
namespace | Grouping key, e.g. api, login, webhook (1–128 chars) |
identifier_type | What the rule counts: key, ip, user, or route |
algorithm | One of the four algorithms below |
limit | Maximum requests allowed in the window |
window_seconds | The window length |
Optional fields: cost (default cost per request, 1–10,000), and for token bucket, burst (burst ceiling, defaults to limit) and refill_rate (tokens/second, defaults to limit / window_seconds).
Create, update, list, and delete rules under /v1/ratelimit/rules.
| Algorithm | Wire name | Behavior |
|---|---|---|
| Token bucket | token_bucket | Tokens refill continuously; bursts allowed up to burst |
| Fixed window | fixed_window | One counter per window; resets on the boundary |
| Sliding window log | sliding_window_log | Exact timestamps; strictest fairness, highest memory |
| Sliding window counter | sliding_window_counter | Weighted blend of current and previous window; constant memory |
Pick token bucket for smooth APIs with occasional bursts, fixed window for simple predictable resets, sliding window log where exactness matters, and sliding window counter for high-volume rolling rates.
POST /v1/ratelimit/limit consumes capacity. POST /v1/ratelimit/check is read-only — it always evaluates with cost 0 and never moves a counter. Use check to show "remaining" state in a UI without spending the user's budget.
Both accept an optional cost to consume more than one unit (an expensive search might cost 5), and an optional explicit identifier. When the identifier is omitted it is derived server-side from the rule's identifier_type — client IP, API key, or route.
Evaluate several existing rules in one call with limitMulti / checkMulti. Each entry references a rule by namespace; the response is the most restrictive result across all rules:
Here the request is evaluated against both the api rule (per-minute) and the api-daily rule (per-day) in a single round trip, and denied if either denies.
Evaluations always return HTTP 200 with a JSON body:
success: false means over the limit. retry_after (seconds) is present only on denial. degraded: true means the rate-limit Redis was unreachable and the request was allowed via fail-open — see Error Handling.
GET /v1/ratelimit/status/:namespace returns the rule plus a read-only usage evaluation for the caller's identifier — useful for "you have N requests left" UIs.
Overrides, quotas, and blocklists are managed in the dashboard and enforced inside the same atomic evaluation.
GET /v1/ratelimit/analytics?namespace=api&from=...&to=... returns the top identifiers by request count in a time window, each with allowed, denied, and cost totals, plus aggregate totals for the window. from and to accept epoch milliseconds or ISO 8601. Use it to find the client hammering a namespace without adding counters to your own code — the dashboard's Analytics tab renders the same data as a table.
degraded: true means the analytics store was unreachable and empty data was returned. Analytics requires the API key's read_stats scope.