# Limits

> Sizes, rates, timeouts and spending caps that rooms, connections and projects work within.

These limits are provisional and may change before launch. Going over a
connection limit closes the connection with the close code listed below.

## Rooms

| Limit | Value |
|---|---|
| Room state | 32 MB; a room whose room state grows past it stops |
| Tick rate | 1 to 120 ticks per second; default 20 |
| Private state of a player who left | kept 24 hours by default; a room's `privateRetention` sets it |
| Room ID | 1 to 64 characters of `A-Z`, `a-z`, `0-9`, `_`, `-` |
| Connections per room | 64 for `standard`, 256 for `large`, 1,024 for `extra-large`; a room's `maxPlayers` caps it lower |
| Hibernate after the last connection leaves | 30 seconds |
| VM stops after its last room hibernates | 5 minutes |
| Wake timeout before held connections are closed | 10 seconds |
| Room state written to object storage | every 30 seconds when changed, and on hibernate |

## Replays and clips

| Limit | Value |
|---|---|
| A replay's records | 64 MB, then recording stops |
| A replay's length | 2 hours, then recording stops |
| One tick's records | 4 MB, or recording stops |
| Recordings a room starts | one every 10 seconds |
| A clip | 1 to 60 seconds |
| Clips | one every 10 seconds, 20 per replay |
| Replays and clips a room keeps | its newest 20 replays and 100 clips |
| Replay retention | `rooms.replayRetention`, 1 hour to 30 days; default 7 days |
| Replay and clip IDs | 1 to 64 characters of `A-Z`, `a-z`, `0-9`, `_`, `-` |

## Player data, collections and leaderboards

| Limit | Value |
|---|---|
| A value | 64 KB of JSON or bytes |
| A player's data | 256 keys and 1 MB |
| Keys and entry IDs | 1 to 64 characters of `A-Z`, `a-z`, `0-9`, `_`, `.`, `:`, `-` |
| An entry's `meta` | 1 KB, flat strings, numbers and booleans |
| A collection | 1,000,000 entries; `maxOwn` per player from clients, default 100 |
| Collections | 32 per project |
| A list or `top` page | 100 entries, 20 by default |
| Leaderboard periods kept | the current one and the three before it |
| Calls | 200 a second and 64 at once per room; 10 a second per client address and per player; 2,000 a second per project |
| Guests minted with `POST /v1/guest` | 10 a minute per client address, with those connecting mints |
| A request | 128 KB |
| Deadline | 5 seconds, then `E_UNAVAILABLE` |
| Guests' player data | deleted 90 days after it was last written |

Reads and writes are metered and free within these limits. See
[Player data, collections and leaderboards](/docs/guides/player-data).

## Messages and connections

| Limit | Value |
|---|---|
| Message size | 64 KB |
| Messages per connection | 120 per second |
| Connections per player per room | 1; a new one closes the old one |
| WebTransport connect before falling back to WebSocket | 3 seconds |

A state update for one tick can span several messages, so a client
entering a large view isn't bound by the message size.

## Outbound calls from rooms

| Limit | Value |
|---|---|
| Protocols and ports | `fetch` to `https://` on port 443 only, by host name |
| Addresses | public only; names resolving to private, loopback or link-local addresses are refused |
| Connections open at once | 64 per VM |
| Bandwidth | 10 MB a second per VM, both directions together |
| Idle connection | closed after 5 minutes |

See [Calling your backend](/docs/reference/room-sdk#calling-your-backend).

## State sync

| Limit | Value |
|---|---|
| A `bytes` field | 48 KB |
| A `string` field | 16 KB of UTF-8 |
| A `json` field | 16 KB serialized |
| An entity, encoded with every field | 61,376 bytes (60 KB minus 64) |
| Prediction inputs held ahead of the room | 32 ticks |
| How far a view tick, and `room.rewind`, reach back | 250 ms (`MAX_REWIND_MS`), plus two ticks kept |
| Lag compensation history | 8 MB per room (`MAX_HISTORY`); 8 bytes per field per kept tick per entity, plus 128 bytes |
| Interest keys a connection subscribes to | 4,096 |
| Entities a connection sees, presence entries included | 16,384 |
| Presence entries in a room | 1,024 |
| A presence name | 64 characters |
| A presence status | 1 KB serialized |

Going over a state sync cap is an error in the room's log; the extra keys
or entities are left out.

## Player tokens

| Limit | Value |
|---|---|
| Lifetime (`exp` after `iat`) | at most 24 hours |
| Player ID (`sub`) | 1 to 128 bytes, not starting with `guest:` |
| `meta` | JSON, up to 1 KB |

## Join codes

6 characters of `A-H`, `J-N`, `P-Z` and `2-9`, so codes have no `I`, `O`,
`0` or `1`.

## Project settings with limits

| Setting | Default | Meaning |
|---|---|---|
| `limits.maxActiveRooms` | 100 | Rooms active at once |
| `limits.maxRoomHoursPerDay` | 200 | Room-hours per day |
| `limits.maxRooms` | 1000 | Rooms that exist at once, hibernated or not |
| `limits.maxSleepingConnections` | 10,000 | Connections the project's [sleeping rooms](/docs/hibernation#sleeping-rooms) hold in a region; past it, a room that sleeps closes its connections with 4011 |
| `voice.maxSpeakers` | 64 | Speakers each listener hears, 1 to 64, a ceiling on each room's own; see [Proximity voice](/docs/guides/proximity-voice#turning-it-on) |
| `rooms.retention` | `"7d"` | How long a hibernated room is kept: `"none"`, `"<n>h"`, `"<n>d"` up to 365 days, or `"forever"` |

The `limits` are spending caps, set only in the dashboard, never from
`irt.config.ts`. A project over `maxActiveRooms` or `maxRoomHoursPerDay`
can't wake more rooms, and clients get close code 4009. At 80% of either,
IRT sends a [usage alert](/docs/stats#usage-alerts) first. A project at
`maxRooms` can't create more until rooms expire or are deleted. A project
can have 10,000 active [bans](/docs/moderation).

## Credit

Usage is paid from your account's prepaid credit, which you top up by
card on the dashboard's Billing page. Below a low-balance threshold the
dashboard shows a banner and each project with a webhook gets a
`billing.low_balance` event. When the balance reaches zero your projects
keep running for 24 hours. After that they can't wake rooms, their
players are disconnected with close code 4009, the server API answers
`429 limit`, and running rooms hibernate. Topping up undoes this at
once. Running out never deletes a room.

## Close codes

| Code | Meaning | Client SDK |
|---|---|---|
| 4000 | Protocol version not supported | Fails; the site needs a newer SDK |
| 4001 | Token invalid or expired | Fails |
| 4002 | Room not found, and `players.createRooms` is off | Fails |
| 4003 | Room full: at its size's connection limit or its `maxPlayers` | Fails |
| 4004 | Schema differs from the room's build | Fails; rebuild and redeploy the client and room together, or reload the site |
| 4005 | Rate or size limit exceeded | Reconnects after backoff |
| 4006 | Kicked by the room, or its `onJoin` threw | Fails |
| 4007 | Room stopped | Fails |
| 4008 | Room moved or restarted | Reconnects at once |
| 4009 | Project over its spending limit, or out of credit | Fails |
| 4010 | Wake timed out | Reconnects after backoff |
| 4011 | The room hibernated by its own request, or went to sleep past `limits.maxSleepingConnections` | Fails; the game can offer to rejoin |
| 4012 | The same player connected again elsewhere | Fails |
| 4013 | The player is [banned](/docs/moderation) from the project | Fails |

Any other close reconnects with backoff. See [Errors and close
codes](/docs/reference/errors) for what causes each and what to do.
