Room capacity

maxClients defaults to 64. Load-test your room to choose a player count that meets your performance targets.

Capacity signals

What runs outWhat it looks likeWhere you see it
Bandwidth per clientPlaying gets choppy, then a client is dropped with E_SLOW_CONSUMERirtio simulate’s bytes in per bot, and the bandwidth invariant
Tick timeThe room ticks late, then sheds a tick’s backlogThe tick-health invariant, and irtio status’s per-room tick health
MemoryThe room restarts from its saved state. Three restarts in a minute closes the roomThe rss series on the dashboard, and irtio logs
maxClientsThe next join is refused with E_ROOM_FULLYour own join errors

Bandwidth is usually first, because it is the one that grows with the square of the room. Every client receives an update about every other client by default, so doubling the players doubles what each client receives and quadruples what the room sends.

maxClients is the only one of the four you set directly, and it should be the number you measured, with headroom for busy moments. Capacity depends on your schema, tick rate, and visibility settings.

A room’s memory ceiling counts everything it holds, not only its JavaScript objects: typed arrays, Buffers, and WebAssembly memory are charged to the room the same way. A room that keeps decoded assets or audio buffers can therefore reach its ceiling with a small object graph, and irtio logs names both figures when it does. See memory.

Find your own number

Run the room locally and point real client sessions at it.

npx irtio dev                                             # in one terminal
npx irtio simulate --bots 30 --seconds 60 --profile       # in another

Read four things off the report:

  • tick-health. ok means the server never dropped a tick’s backlog during the run. This is the hard stop: past it the room is doing less work than the game asked for.
  • Bytes in per bot. What one player’s connection costs. Compare it to the budget you intend to hold, not to the 128,000 B/s default, which is a ceiling rather than a target.
  • Convergence. The median milliseconds from one bot writing a value to another bot’s view showing it. A number that climbs as you add bots is the room falling behind.
  • correction-storm. A rising correction rate under load usually means the room is late rather than wrong.

Then step the bot count: 10, 20, 40, 80. Your capacity is the largest count where tick health stays ok, per-client bytes stay inside your budget, and convergence stays flat. Set maxClients a little below it.

Four things will bend the answer if you let them.

  • Hundreds of bots on one machine measure the machine. Treat a run in the hundreds as a profile, not a pass or fail.
  • Against a deployed project, the per-address cap is 120 new connections per minute. A bigger run has to go at irtio dev or come from several addresses.
  • A cold deployed project fails its first run on E_STARTING. Warm it with a throwaway run first.
  • The random script wanders. If capacity depends on where players go, such as anything using visibility: 'spatial-grid', write a script instead. See invariants and load runs.

Bandwidth breakdown

Before you cut anything, find out what you are paying for.

npx irtio dev --profile
npx irtio simulate --profile

The bandwidth profiler breaks traffic down per field rather than giving you a total, and the answer is often not the field you suspected. In one 60 Hz room, 55% of everything the server sent was framing: the op tag that says which entity changed, and the per-frame delta header. That room was paying for addressing, not for data, and no total would have said so.

Increase capacity

  1. Reduce data sent to each player using visibility and narrower schema fields.
  2. Select a larger class in room configuration when the room needs more memory.
  3. Use more servers to spread separate rooms across servers. A single room runs on one server at a time.

Repeat the load test after each change. Larger memory alone does not guarantee a higher player count.

Watch it after launch

npx irtio status              # every project-wide metric, then a per-room table
npx irtio status --room <id>  # one room's recent history

The dashboard’s Metrics page carries the same series: sockets, roomsByState.*, ingressBytes, egressBytes, rss. The two to watch against capacity are rss, which should rise and fall rather than only rise, and egressBytes, which is what a room costs the network.