Rate Limiting

Token bucket rate limiter with per-IP or global modes

Category: Practical
Task: Limit request rates

Prerequisites: Praxis runtime; An HTTP backend

Expected outcome: Requests within the configured limit are forwarded; excess requests are rejected.

Run it: Use ghcr.io/praxis-proxy/praxis:0.7.2 and follow the first reverse-proxy tutorial to mount and start the configuration.

This configuration comes from the selected release. The example has not been run here; external services are not bundled.

Download the source file.

# Rate Limiting
#
# Token bucket rate limiter with per-IP or global modes.
# Rejects excess traffic with 429 and standard rate limit headers.
#
# This example shows per-IP limiting on :8080 and global limiting
# on :8081 sharing a single bucket across all clients. Per-IP mode
# keys IPv4 clients by address and IPv6 clients by network prefix
# (one address by default; this example groups by /64 as an
# internet-facing listener should), so rotating addresses within one
# IPv6 allocation does not reset the limit.
#
listeners:
  - name: per-ip
    address: "127.0.0.1:8080"
    filter_chains:
      - per-ip-chain

  - name: global
    address: "127.0.0.1:8081"
    filter_chains:
      - global-chain

filter_chains:
  - name: per-ip-chain
    filters:
      - filter: rate_limit
        mode: per_ip         # independent bucket per source IP
        rate: 10             # demo value; tune for production
        burst: 20            # demo value; tune for production
        ipv6_prefix_len: 64  # IPv6 clients share one bucket per /64 (default 128)

      - filter: router
        routes:
          - path_prefix: "/"
            cluster: backend

      - filter: load_balancer
        clusters:
          - name: backend
            endpoints:
              - "127.0.0.1:3000"

  - name: global-chain
    filters:
      - filter: rate_limit
        mode: global         # one shared bucket for all clients
        rate: 50             # demo value; tune for production
        burst: 100           # demo value; tune for production

      - filter: router
        routes:
          - path_prefix: "/"
            cluster: backend

      - filter: load_balancer
        clusters:
          - name: backend
            endpoints:
              - "127.0.0.1:3000"

insecure_options:
  allow_private_endpoints: true # example proxies to local backends