# Stats and usage alerts

> Per-build players, rooms, reconnects, errors and tick cost in the dashboard, and alerts before a project reaches its spending caps.

The dashboard's **Stats** tab shows each build's numbers a minute at a
time, as tables, for the last 14 days. Use it to see how a new build
behaves next to the one before it.

## What's counted

Measured by the router, outside your rooms:

| Column | Meaning |
|---|---|
| Peak players | The most connections at once in the minute or range. Each router counts its connections about every second, and each room counts the most it had since the count before, so a connection shorter than a second still counts. A player who moves between rooms within one count counts once in each room. Rooms on different routers are added up |
| Peak rooms | The most active rooms at once |
| Reconnects | Connections from a player who left the same room in the last minute, or who connected again before their last connection was seen to drop |

Reported by rooms, from inside their VM:

| Column | Meaning |
|---|---|
| Errors | Lines the room SDK logs at level `error`, such as a hook that threw |
| Ticks | Ticks run |
| Average tick, longest tick | Time spent in a tick, from the room host's own measurements |

Numbers reported by rooms come from your own code's process, so they're
your build's account of itself: good for debugging, and never used for
billing. Billing counts only what IRT measures outside your rooms; see
[Limits](/docs/limits).

A build's row in a range shows the highest per-minute peak and the totals
of the rest. Click a build to see its last hour minute by minute.

`irt stats` prints the same table in a terminal, and
`irt stats --build <id>` one build minute by minute; see
[CLI](/docs/cli#irt-stats). Tick cost is a build's average and longest
tick over all its rooms. For one room's cost per hook, such as how much
of a tick `onTick` or the state update takes, run the room under
`irt dev` and open its [inspector](/docs/dev-tools), which shows the
tick profile as p50, p95 and max.

## From your backend

The same numbers are in the [HTTP API](/docs/http-api), with an API key:

- `GET /projects/{p}/stats?from=...&to=...`: each build over a range, by
  default the last 24 hours, at most 14 days.
- `GET /projects/{p}/builds/{id}/stats?from=...&to=...`: one build per
  minute, by default the last hour, at most 24 hours.

`from` and `to` are RFC 3339 times, such as `2026-11-04T12:00:00Z`, or
dates, such as `2026-11-04`, which mean midnight UTC at their start.
Anything else answers `400` with the code `invalid`.

```json
{
  "minute": "2026-11-04T10:05:00Z",
  "peakPlayers": 42,
  "peakRooms": 7,
  "reconnects": 3,
  "reportedByRooms": { "errors": 0, "ticks": 8400, "tickMsAvg": 1.2, "tickMsMax": 9.5 }
}
```

`tickMsAvg` and `tickMsMax` are `null` for a minute with no ticks.

## Usage alerts

When a project passes 80% of `limits.maxRoomHoursPerDay` or
`limits.maxActiveRooms`, IRT sends a `usage.alert`
[webhook](/docs/webhooks) and the dashboard shows a banner on the
project's pages. Each limit alerts at most once per UTC day, so raise the
cap in the project's settings if the project is meant to grow past it.
Room-hours count from room periods that ended today, as the cap does, and
active rooms from the router's count in the last few minutes.

`GET /projects/{p}/alerts` lists today's alerts:

```json
{ "alerts": [{ "limit": "maxRoomHoursPerDay", "used": 164.2, "max": 200, "day": "2026-11-04", "at": "2026-11-04T15:20:00Z" }] }
```
