---
title: Rate Limit
description: >-
  Limits the number of requests each client (by IP address) can make to a
  location in a period of time.
---
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.page/luizfonseca/super/llms.txt
> Use this file to discover all available pages before exploring further.

Limits the number of requests each client (by IP address) can make to a location in a period of time. Clients over the limit get a `429 Too Many Requests`, with a `Retry-After` header.

By default, `rate_limit` runs before any other block (priority `0`), so it also protects endpoints that use authentication from brute force.

## Options

<table><thead><tr><th width="205">Name</th><th>Description</th></tr></thead><tbody><tr><td><code>requests</code></td><td>Number of requests allowed for each client in each period</td></tr><tr><td><code>per</code></td><td>The period, such as <code>"10s"</code>, <code>"1m"</code> or <code>"1h"</code></td></tr><tr><td><code>burst</code></td><td>Requests a client may make at once on top of <code>requests</code>, refilled at the same rate (default: none)</td></tr><tr><td><code>priority</code></td><td>When it runs among the blocks of the location (default: <code>0</code>)</td></tr></tbody></table>

### Usage

**config.hcl**
```hcl
host "mywebsite.com" {
  # A stricter limit for the login page
  location "/login" {
    upstream "localhost:3000" {}

    # 40 at once, then 30 a minute
    rate_limit {
      requests = 30
      per      = "1m"
      burst    = 10
    }
  }

  location "/" {
    upstream "localhost:3000" {}

    rate_limit {
      requests = 120
      per      = "1m"
    }
  }
}
```

### Good to know

- Requests are spread evenly over `per`: with `requests = 60` and `per = "1m"`, a client gets one more request each second. A client can make `requests + burst` at once, and `Retry-After` says how many seconds until its next request is let through.
- `burst` is added to `requests`. In [`bandwidth_limit`](/plugins/bandwidth-limit), `burst` is the whole allowance instead.
- Each location, and each rule, counts its own requests.
- With the [Redis store](/configuration/redis), every Super server using it shares each block's limit. Each server decides on its own, without waiting for Redis, and syncs every 250ms: a client can go over by about what it sends in 250ms to each other server, plus its first requests on a server that hasn't seen it yet. If Redis can't be reached, each server keeps limiting on its own until it can. Each server shares up to 896 clients per block in each sync; more clients than that, or ones counted while the block is very busy, are limited by that server only until the next sync. Each client a server lets through is kept in Redis until its requests are refilled (up to `per`), so a very large number of different clients takes room in Redis.
- With the memory and SQL stores, counts are kept on each Super server, and start over when the host's configuration changes.
- Counts use a fixed amount of memory and are estimates: with a very large number of clients in the same period, a client can be limited slightly before reaching `requests`, never after.
- Clients are identified by the IP address of the connection. Behind another proxy or load balancer, every request comes from its address, so the limit would apply to all clients together. List it in `server.trusted_proxies`, and the client is the address it forwards in `X-Forwarded-For` instead:

  ```hcl
  server {
    trusted_proxies = ["10.0.0.0/8", "192.168.1.10"]
  }
  ```

  Only addresses forwarded by trusted proxies are used: going from the right of `X-Forwarded-For`, the client is the first address that isn't a trusted proxy, so a client can't choose its own address by sending the header itself. Access logs show the same client, and so do upstreams (`X-Real-IP`, see [headers](/routing/headers)).
