-
Notifications
You must be signed in to change notification settings - Fork 0
Home
Sliding-window rate limiting for Rex, at three levels: per endpoint → per router → global.
go get github.com/kryovyx/rextension-ratelimitimport (
"github.com/kryovyx/rex"
ratelimit "github.com/kryovyx/rextension-ratelimit"
)
app := rex.New(ratelimit.WithRateLimit(
ratelimit.WithGlobalLimit(600, time.Minute),
ratelimit.WithTrustedProxies(ratelimit.PrivateNetworks()...),
))A route can override that:
type LoginRoute struct{ rxroute.Route }
func (r *LoginRoute) RateLimit() ratelimit.LimitConfig {
return ratelimit.LimitConfig{Rate: 5, Window: time.Minute}
}Not only refusals:
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 583
X-RateLimit-Reset: 1757000000
A client that can read its remaining quota can slow down. A client that cannot discovers the limit by exceeding it.
For a browser client, those headers must be exposed — which
rextension-cors does by
default.
HTTP/1.1 429 Too Many Requests
Retry-After: 34
Content-Type: application/problem+json
{"type":"urn:rex:problem:rate-limit-exceeded","title":"Too Many Requests",
"status":429,"detail":"rate limit exceeded"}
rextension.PriorityRateLimit (300) — before authentication (400).
That order is not arbitrary. Rate limiting after authentication means every flooded request costs a password hash or a token verification before being rejected: the limiter then protects nothing, it just adds work.
Per-endpoint limits are resolved at build time, from the route itself.
Resolution used to happen per request from the live URL against an index keyed
by the route's pattern — those never match for a parameterized route, so a
per-endpoint limit silently never applied to any route with a path parameter.
A route declaring 5/minute was limited at whatever the global rate happened to
be, and nothing said so.
X-Forwarded-For is walked right to left, through trusted hops only. The
header is client-appendable, so the leftmost entry is the attacker's own value.
Taking it — the obvious reading, and the one most naive implementations use —
lets a client rotate the header and defeat the limiter entirely. See
Behind a Proxy.
- Limits and Precedence — the three levels, fixed and dynamic
- Client Identity — what a bucket is keyed by
- Behind a Proxy — the one thing you must configure behind an ingress
- The Store — buckets, eviction and the memory cap
- Configuration · Troubleshooting
rextension-ratelimit — global, per-router and per-endpoint rate limiting for Rex · MIT · © 2026 Kryovyx
Ecosystem