# Health (/docs/health)

**Health** shows whether your game runs well: how fast servers tick, how much memory they use, how many script errors players hit and how many servers crash. Pick a range (last hour, 24 hours or 7 days) and, to judge one update, a version. Release markers (`v418`) show when each update went out.

It needs no setup beyond the [RoChart module](/docs/getting-started/install). Servers send health numbers on every heartbeat (every 60 seconds), and errors as they happen.

## Overview [#overview]

| Chart | What it shows |
| --- | --- |
| **Server FPS** | `workspace:GetRealPhysicsFPS()` per heartbeat: the median and the 10th percentile over all servers' heartbeats in each bucket. 60 is perfect; the 10th percentile shows your worst servers. |
| **Server memory** | `Stats:GetTotalMemoryUsageMb()`, averaged. Memory that climbs with uptime is usually a leak. |
| **Heartbeat time** | `Stats.HeartbeatTimeMs`, averaged: how long a server frame takes. Above about 16 ms a server can't hold 60 FPS. |
| **Player ping** | The mean `player:GetNetworkPing()` of the players on each server, averaged over servers. |
| **Script errors** | Error occurrences per bucket (the sum of `$count`, see below), from servers and clients. |
| **Crashed servers** | Servers whose heartbeats stopped in that bucket and never resumed, without a `$server_shutdown`. |

With a version selected, every chart only uses servers running that version (and errors reported from it).

## Errors [#errors]

Errors are grouped by **fingerprint**: the side, the script and the message with numbers and quoted strings removed. So `attempt to index nil with 'Foo'` on line 12 and on line 14 are one group. For each group you see the latest message and script, server or client, occurrences, players affected (client errors), the versions it happened on, when it was last seen and a trend over the range. Click a row for a sample stack trace.

**New in v418** marks errors only ever seen on the newest update, and only since it went out: the ones your last publish introduced.

Search matches the message or the script; the side filter splits server and client errors.

<Callout type="info" title="Occurrences, not events">
  The module groups identical errors for up to 60 seconds and sends one `$error` with a `$count`, and sends at most 30 error events per server per minute (client reports at most 5 per player per minute). Occurrences add up `$count`, so a script that errors every frame shows as thousands of occurrences, not 30 events.
</Callout>

## Servers [#servers]

Every running server right now — one that sent a heartbeat in the last 2 minutes and hasn't shut down — refreshed every 10 seconds: players and max players, version, uptime, FPS, memory, ping and server type (public, private, reserved). Servers on an older version than the newest one running are marked **outdated**, and the totals show how many players are still on them.

## Definitions [#definitions]

| Term | Meaning |
| --- | --- |
| **Crash** | A server whose heartbeats stop for more than 3 minutes without a `$server_shutdown`. Its time is its last heartbeat. Servers that Roblox closes normally run `BindToClose` and send a shutdown, so they don't count. |
| **Live server** | A server with a heartbeat in the last 2 minutes and no shutdown. |
| **Version** | The server's `game.PlaceVersion` (`$place_version`). |

## For agents [#for-agents]

Health is three queries: `game_health` (the charts, with optional `placeVersion`), `game_errors` (groups; `side`, `placeVersion`, `search`), and `game_servers` (live servers). For example:

```json
{ "kind": "game_errors", "dateRange": { "from": "-24h" }, "side": "server", "placeVersion": 418 }
```

Ask an agent *"Which errors did v418 introduce?"* or *"Is server memory growing with uptime?"*.
