# Rate limits

> Per-form rate limit presets with the exact numbers, how they refill, and what a 429 looks like.

Rate limits stop one visitor, or one script, from flooding a form. Every form has a preset, and every limit is counted exactly, before the body is read. A rejected post doesn't use up any allowance.

## Presets

| Preset | Per visitor and form | Good for |
| --- | --- | --- |
| Standard (default) | 5 a minute, at most 3 in 10 seconds | Most forms |
| Relaxed | 20 a minute | Forms behind a login, internal tools, events on shared Wi-Fi |
| Strict | 2 every 10 minutes | Contact and sales forms, where a repeat is a double click or a bot |
| Custom | 1 to 1,000 every 10 seconds, minute, 10 minutes, hour or day | One entry per person, kiosks and other special cases |

## The presets compared

A visitor who presses Send once a second for two minutes gets this many posts through, simulated with the same algorithm Ikiform runs:

| Preset | Accepted of 120 | Accepted at second |
| --- | --- | --- |
| Standard | 14 | 0, 1, 2, 4, 7, 12, 24, 36, 48, 60, 72, 84, ... |
| Relaxed | 59 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... |
| Strict | 2 | 0, 1 |

## How limits refill

Limits are a smooth allowance, not a fixed clock window. A quiet visitor starts with the full allowance and can use it at once. After that, one more post is allowed every window divided by limit: every 12 seconds for Standard, every 3 seconds for Relaxed and every 5 minutes for Strict. After a full quiet window the allowance is full again.

Standard also has a burst rule of 3 posts per 10 seconds, so its first burst is 3, not 5. Relaxed, Strict and Custom have no separate burst rule.

## Limits that always apply

| Rule | Limit | Counted per |
| --- | --- | --- |
| Flood guard, before the form is looked up | 600 a minute | IP, across every form |
| Cross-form | 30 a minute, or the Custom per-minute rate when higher | IP, across every form |
| Form-wide | 300 a minute, or a Custom cap of 1 to 10,000 | Form, across every visitor |
| `GET /f/<formId>/schema` | 60 a minute | IP and form |
| The Ikiform check frame | 60 a minute | IP and form |
| REST API | 100 a minute | API key |

Custom rates faster than the flood guard are refused when you save; for example, a 10-second window allows at most 100. Loading a form's schema or the human check never spends the submit allowance.

## Custom

- **Submissions per visitor:** a whole number from 1 to 1,000, and a window of 10 seconds, a minute, 10 minutes, an hour or a day.
- **Form-wide cap per minute:** optional, from 1 to 10,000. It replaces the 300 a minute default for the whole form.
- An hour or a day window suits one-entry-per-person forms such as giveaways or RSVPs. Remember that many people can share one IP, for example at an office or event.

## When a limit is hit

The post is refused with `429 rate_limited` and a `Retry-After` header with the whole seconds until the next post is allowed. Browser form posts see a hosted "Slow down" page. `fetch` code can read `Retry-After`, because Ikiform exposes it through CORS.

`429 Too Many Requests`:

```http
HTTP/1.1 429 Too Many Requests
Retry-After: 12
X-Request-Id: req_01k7v2c9t3e8m5q4x6z0a1b2c3
Content-Type: application/json; charset=utf-8

{"ok":false,"error":{"code":"rate_limited","message":"Too many requests. Please slow down."},"request_id":"req_01k7v2c9t3e8m5q4x6z0a1b2c3"}
```

1. Wait for `Retry-After` seconds before sending again.
2. If honest visitors hit the limit, switch the form to Relaxed or Custom.
3. If your server posts for visitors, every post shares your server's IP. See [From a server](https://ikiform.com/docs/guides/server.md#what-changes).

> Rate limit settings are private. They are never exposed by the schema endpoint or the REST API.
