Skip to main content
Modelence provides a built-in rate limiting system you can use to protect any mutation or query from abuse. Authentication endpoints come with their own default limits.

Defining Rate Limits

You can define your own rate limits by adding a rateLimits array to a Module. Each rule specifies a bucket name, the type of actor being limited (ip or user), a time window, and a maximum number of allowed calls within that window.
Multiple rules can share the same bucket to enforce more than one window. All rules on a bucket are checked — if any one is exceeded, the call is rejected:

Consuming a Rate Limit

Call consumeRateLimit inside a mutation or query handler to check and increment the rate limit counter. It throws a RateLimitError automatically when any matching rule is exceeded:
An optional message parameter lets you provide a user-facing error message instead of the default:

Reverse Proxy Deployments

For backward compatibility, Modelence trusts the complete X-Forwarded-For chain when no proxy configuration is present. This preserves existing client IP behavior during upgrades, but callers can supply their own value. Production deployments should list only the proxy addresses or networks they control:
For hosted deployments, the equivalent environment variable takes precedence over the startApp() setting:
trustedProxies accepts IP addresses, CIDR ranges, and the Express named ranges loopback, linklocal, and uniquelocal. Modelence then walks the forwarded chain from the app toward the client and uses the first untrusted address. Forged values prepended by a caller do not become the IP rate-limit key. Configure the edge proxy to overwrite or append the actual peer address, and prevent untrusted clients from connecting directly to the application port.

Cloudflare

Cloudflare appends to an inbound X-Forwarded-For header rather than overwriting it, so its left-most value is chosen by the caller. Cloudflare therefore recommends reading CF-Connecting-IP, which always holds exactly one address. Set clientIpHeader to use it:
clientIpHeader is only read when the connecting peer matches trustedProxies, so it must be configured alongside them with Cloudflare’s published IP ranges. Two caveats:
  • With the default trust-all behavior (neither trustedProxies nor MODELENCE_TRUSTED_PROXIES set), every peer counts as trusted, so anyone able to reach the application port directly could set the header themselves. Always pair clientIpHeader with an explicit trusted proxy list.
  • If the trusted list does not cover the full Cloudflare edge, requests through uncovered addresses fall back to the peer address, collapsing many clients onto a single rate-limit key.
True-Client-IP works the same way, but is Enterprise-only and must be enabled via a Managed Transform. Cloudflare warns that in a stacked-CDN setup its value can be spoofed unless your own edge sets it.