Command Palette

Search for a command to run...

Rate Limiter overview
Deployment guide

Run the rate limiter with Docker

Put the gateway in front of your API, try the fixed-window limits locally, then use Redis to share quotas across replicas.

Linux amd64 + arm64Non-root imageView on Docker Hub

1. Start a local demo

Install Docker with Compose and start the Docker engine. No Go installation or repository checkout is needed. Pull the published image:

Terminal
docker pull hiteshs0lanki/distributed-rate-limiter:latest

In an empty directory, save this as compose.yaml. It starts the gateway and the demo backend included in the same image. Only the gateway publishes a host port.

compose.yaml
name: rate-limiter-demo
services:
  gateway:
    image: hiteshs0lanki/distributed-rate-limiter:latest
    ports:
      - "127.0.0.1:8088:8080"
    environment:
      RATE_LIMIT_STORAGE: ram
      RATE_LIMIT_UPSTREAM: http://backend:8080
    read_only: true
    cap_drop: [ALL]
    security_opt: [no-new-privileges:true]
    depends_on:
      backend:
        condition: service_healthy

  backend:
    image: hiteshs0lanki/distributed-rate-limiter:latest
    entrypoint: ["/demo-backend"]
    command: []
    healthcheck:
      test: [CMD, /ratelimitd, -healthcheck, "http://127.0.0.1:8080/healthz"]
      interval: 5s
      timeout: 3s
      retries: 5
Terminal
docker compose up -d --wait

The gateway is available at http://localhost:8088. Its bundled configuration allows three requests per client IP in each fixed 10-second window. RAM mode keeps counters in one gateway process.

2. Verify forwarding and limits

Check readiness, then send four requests in quick succession:

Terminal
curl -i http://localhost:8088/readyz

curl -i http://localhost:8088/orders
curl -i http://localhost:8088/orders
curl -i http://localhost:8088/orders
curl -i http://localhost:8088/orders

Readiness returns 200. Within one window, the first three order requests return 200 and the fourth returns 429 with a Retry-After header. If the requests cross a window boundary, the allowance resets. Wait for the next window to try again.

Readiness checks do not consume quota. The demo backend echoes forwarded requests, so you can also try a POST after the quota resets:

Terminal
curl -i -X POST 'http://localhost:8088/orders?source=demo' -d 'hello'

3. Connect your own backend

For a backend on an existing Docker network, run the gateway on that network. Replace your-app-network and your-backend:3000 with your network and service address:

Terminal
docker run -d --name rate-limiter \
  --network your-app-network \
  -p 127.0.0.1:8089:8080 \
  --read-only --cap-drop ALL \
  --security-opt no-new-privileges:true \
  -e RATE_LIMIT_UPSTREAM=http://your-backend:3000 \
  hiteshs0lanki/distributed-rate-limiter:latest

Send API traffic to http://localhost:8089. On Docker Desktop, a backend running on your host can use http://host.docker.internal:3000 as the upstream. Inside a container, localhost refers to that container.

To customize routes, limits, windows, or identity policies, mount your complete version-1 proxy configuration with -v "$PWD/proxy.json:/etc/ratelimit/proxy.json:ro". Restart the container after changing the file. The architecture page has a configuration editor for exploring policies.

4. Share quotas with Redis

Use Redis when multiple gateways need one shared allowance. Save the following beside compose.yaml as compose.redis.yaml. Redis stays on the private Compose network.

compose.redis.yaml
services:
  gateway:
    environment:
      RATE_LIMIT_STORAGE: redis
      REDIS_URL: redis://redis:6379/0
    depends_on:
      redis:
        condition: service_healthy

  redis:
    image: redis:7.4.7-alpine
    command: [redis-server, --appendonly, "yes", --maxmemory, 128mb, --maxmemory-policy, noeviction]
    volumes:
      - redis-data:/data
    healthcheck:
      test: [CMD, redis-cli, ping]
      interval: 2s
      timeout: 2s
      retries: 15

volumes:
  redis-data:
Terminal
docker compose down
docker compose -f compose.yaml -f compose.redis.yaml up -d --wait

Replicas must use the same namespace and policy settings, including revisions. Configure RATE_LIMIT_NAMESPACE to separate deployments. Redis counters survive gateway restarts until expiry; if Redis becomes unavailable, the gateway returns 503 and does not forward requests.

5. Inspect, update, and stop

Terminal · RAM demo
docker compose logs -f gateway

# Pull the latest image and recreate the services
docker compose pull
docker compose up -d --wait

# Stop and remove the demo containers
docker compose down

For Redis mode, include -f compose.yaml -f compose.redis.yaml in each Compose command. Stopping the stack preserves the Redis volume; adding -v deletes it and resets stored state. Remove the standalone gateway with docker rm -f rate-limiter.

Gateway health endpoints and error responses
ResponseMeaning
/healthzGateway process is alive.
/readyzGateway is ready; includes Redis checks in Redis mode, but does not check the upstream.
429Request allowance exhausted. Retry after the indicated delay.
503Rate-limit storage or key capacity unavailable.
502 / 504Upstream unreachable or timed out. Check its address and network.

The examples bind to loopback for local use. For a public deployment, terminate TLS at your ingress and keep the backend private so clients cannot bypass the gateway. The latest tag can change; pin a tested image digest for reproducible deployments.