Vix.cpp v2.8.5 is here Read the blog
Skip to content

Rate limiting ​

This guide shows how to add rate limiting to a Vix API.

Rate limiting protects your application from repeated requests, abuse, accidental loops, and brute-force attempts.

What is rate limiting? ​

txt
Allow 60 requests per minute per IP address.

If the client sends too many requests, the API returns 429 Too Many Requests.

Setup ​

bash
vix new rate-limit-api
cd rate-limit-api
cpp
#include <vix.hpp>
#include <vix/middleware.hpp>

Simple global rate limit ​

cpp
app.use(vix::middleware::app::rate_limit({
    .max_requests = 60,
    .window_seconds = 60
}));

Stricter login rate limit ​

cpp
// Global limit
app.use(vix::middleware::app::rate_limit({.max_requests = 60, .window_seconds = 60}));

// Stricter limit for /auth
vix::middleware::app::use_on_prefix(
    app,
    "/auth",
    vix::middleware::app::rate_limit({.max_requests = 5, .window_seconds = 60}));

Custom rate limit options ​

cpp
vix::middleware::security::RateLimitOptions options;
options.max_requests = 60;
options.window_seconds = 60;
options.key = "ip";   // or "user", "api_key"

app.use(vix::middleware::app::adapt_ctx(
    vix::middleware::security::rate_limit(std::move(options))));

Where to apply rate limiting ​

EndpointSuggested limit
GET /healthHigh limit or no limit.
GET /api/*Normal application limit.
POST /auth/loginStrict authentication limit.
POST /auth/registerStrict registration limit.
POST /password/resetVery strict recovery limit.

Test rate limiting ​

bash
for i in $(seq 1 80); do
  curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8080/api/data
done

After the limit is reached, responses should become 429.

Rate limit response headers ​

text
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 42
X-RateLimit-Reset: 1710000000
Retry-After: 30
txt
CORS → rate limit → security headers → body limit → authentication → routes

Rate limiting behind Nginx ​

Nginx forwards the real client IP via headers:

nginx
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

Only trust forwarded headers from your own reverse proxy.

Common mistakes ​

Not limiting login ​

Without a rate limit, attackers can retry many passwords quickly.

Returning 403 instead of 429 ​

cpp
res.status(429).json({
  "ok", false,
  "error", "rate_limit_exceeded"
});

Making local limits too high during testing ​

For testing:

cpp
.max_requests = 3,
.window_seconds = 30

What to use next ​

Released under the MIT License.