# limit_req and limit_conn in Nginx: Rate Limiting Guide

> How to configure limit_req and limit_conn in Nginx: memory zones, burst, nodelay, and 429/503 response codes when limits are exceeded.

## Why limit request rate in Nginx

The limit\_req and limit\_conn modules protect a server from overload: from bots that brute-force forms, from scrapers that crawl a catalog, and from a plain traffic spike after a marketing email. Without limits, a single client can occupy every PHP-FPM worker and take the site down for everyone else.

limit\_req restricts the request rate per second from a single IP address. limit\_conn restricts the number of simultaneous connections. These are different mechanisms, and they are often used together.

## How to configure limit\_req

The memory zone for a limit is declared once in the `http {}` section, and applied inside the needed `location`:

```
http {
    limit_req_zone $binary_remote_addr zone=perip:10m rate=5r/s;
}

server {
    location /login.php {
        limit_req zone=perip burst=10 nodelay;
    }
}
```

The `perip` zone sized at 10 MB stores roughly 160 thousand unique IP addresses. The `rate=5r/s` parameter means 5 requests per second from one address on average.

## limit\_req parameters: what they mean

| Parameter | Value | Effect |
| --- | --- | --- |
| rate | 5r/s, 10r/m | Average request rate from one address |
| burst | number of requests | How many requests above rate to queue |
| nodelay | flag | Do not delay requests from burst, pass them through immediately |
| limit\_req\_status | response code | Which code to return when exceeded, 503 by default |

Without `nodelay`, Nginx holds back extra requests and serves them with a delay, smoothing the flow. With `nodelay`, requests from burst are processed right away, and extra ones are dropped with code 503.

## How to configure limit\_conn

limit\_conn restricts the number of simultaneous connections from one address — useful against downloading large files in several threads or against slow bots:

```
http {
    limit_conn_zone $binary_remote_addr zone=connperip:10m;
}

server {
    location /download/ {
        limit_conn connperip 3;
    }
}
```

This setting allows no more than three simultaneous connections from one IP address to the `/download/` directory.

## How to return a clear error code

By default Nginx returns code 503 Service Unavailable when a limit is exceeded. For an API, code 429 Too Many Requests is more logical:

```
limit_req_status 429;
limit_conn_status 429;
```

Additionally configure a custom error page with `error_page 429 /rate-limit.html;`, so a visitor sees a clear message instead of a bare response code.

## Where to apply limits, and where not to

It makes sense to limit specific addresses, not the whole site:

- login and registration forms — against password brute-forcing
- site search — against scrapers that load the database
- the API — against clients that send requests faster than agreed
- static assets and the homepage are better left alone: limits there hurt more often than they help

## Summary

A checklist for rolling out limits:

- declare the limit\_req\_zone and limit\_conn\_zone memory zones in http {}
- apply the limit selectively — to login forms, search, and the API
- tune rate and burst to real traffic, not by guessing
- return code 429 instead of 503 where the limit protects an API

Limits are worth combining with overall server protection: see the article on [general Nginx security hardening](https://www.zevshost.net/en/kb/nginx-security-hardening/) and on [diagnosing 502 and 504 errors](https://www.zevshost.net/en/kb/nginx-502-504-diagnostika/), which often come from backend overload rather than from Nginx itself.

---

Source: https://www.zevshost.net/en/kb/nginx-limit-req-limit-conn/
