Back to Blog
team@tinypod.app

Rate Limiting for Self-Hosted Apps: Protect Your Infrastructure

Rate limiting prevents abuse by restricting how many requests a client can make. Essential for any self-hosted app exposed to the internet.

rate-limitingsecurityinfrastructure

Why Rate Limit?


Without rate limiting, a single client can:

  • Brute force login pages
  • DDoS your server with requests
  • Scrape your entire database via API
  • Consume all server resources

  • Types of Rate Limiting


    Fixed Window

    Allow N requests per time window (e.g., 100 requests per minute). Simple but can allow bursts at window boundaries.


    Sliding Window

    Smooth rate limiting that tracks requests over a rolling window. More accurate than fixed window.


    Token Bucket

    Tokens are added at a fixed rate. Each request consumes a token. Allows short bursts while maintaining an average rate.


    Leaky Bucket

    Requests flow through at a fixed rate. Excess requests are queued or dropped. Smoothest output rate.


    Where to Rate Limit


    Reverse Proxy Level

    First line of defense. Rate limit at Caddy/Nginx before requests reach your app.


    #### Caddy

    Caddy has rate limiting available via plugins. Configure per-IP limits.


    #### Nginx

    limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;

    location /api {

    limit_req zone=api burst=20;

    }


    Application Level

    More granular control. Rate limit by user account, API key, or endpoint.


    Framework middleware:

  • Express: express-rate-limit
  • Django: django-ratelimit
  • Go: golang.org/x/time/rate

  • API Gateway

    For complex setups, use a dedicated API gateway (Kong, Tyk) for centralized rate limiting.


    What to Rate Limit


    Login Pages

    5-10 attempts per minute per IP. Prevents brute force attacks.


    API Endpoints

    100-1000 requests per minute per API key. Depends on your application.


    File Uploads

    Limit upload frequency and size. Prevent storage abuse.


    Password Reset

    3-5 requests per hour per email. Prevents email flooding.


    Response to Rate Limiting


    Return HTTP 429 Too Many Requests with:

  • Retry-After header (how long to wait)
  • Rate limit headers (remaining requests, reset time)

  • Cloudflare Rate Limiting


    If your app is behind Cloudflare, use their rate limiting rules (free tier includes basic rules). Rate limiting at the edge stops abuse before it reaches your server.