Expand description
2026-09-26: Per-identity token-bucket rate limiter for /v1/* requests: one bucket metered in requests and one in tokens, each refilling linearly with elapsed time up to its burst.
The identity (extract_identity) is, first match wins: a hash of the
Authorization: Bearer token, the first X-Forwarded-For entry, then the
peer IP. X-Forwarded-For is trusted as sent.
Configuration, read once at startup (RateLimitConfig::from_env): unset
METRALE_RATE_LIMIT_RPM and METRALE_RATE_LIMIT_TPM mean 0, which
disables that bucket; METRALE_RATE_LIMIT_BURST_RPM and
METRALE_RATE_LIMIT_BURST_TPM default to the matching rate. With both
rates 0 every request is admitted and the headers carry fixed “unlimited”
values.
Owner: server rate limiter. Invariants:
- A bucket never holds more than its burst: refill and refund both cap at it.
- A denied request consumes nothing: a request debited before a token denial is refunded.
Structs§
- Bucket
Snapshot - 2026-09-26: One bucket’s limit, remaining budget and reset time, for the
x-ratelimit-*response headers. - Rate
Decision - Rate
Limit Config - 2026-09-26: Limiter configuration. A rate of 0 disables that bucket; bursts are at least 1.
- Rate
Limiter - 2026-09-26: The limiter, shared across requests.
- Request
Context - 2026-09-26: What the rate-limit middleware stores in the request’s
extensions when the limiter is enabled and admitted the request: the
identity and the tokens reserved (
max_seq_len). The chat handlers use it to refund the unused part (api/chat_blocking.rs,api/chat_stream/handle_done.rs,handle_error.rs).
Enums§
Functions§
- extract_
identity - 2026-09-26: The rate-limit key, first match wins:
bearer:<hash>for a non-emptyAuthorization: Bearertoken,xff:<ip>for the first non-emptyX-Forwarded-Forentry (taken as sent, not validated), thenpeer:<ip>, orpeer:unknownwithout a peer address.rate_limit_middleware(main_modules/middleware.rs) keys the limiter with it.