Skip to the content
Docs

Performance

On this page7

What this resource costs a server, how that was measured, and what you can do about it.

The short answer

Built and load-tested for a 256-player server. No database query in any tick, no query to recognise somebody, about 32 database writes a minute at full load, and about 2.5 KB of server memory per remembered person. An idle server costs about 0.01 ms per second.

How it was measured

The numbers come from a load simulation: the real server code of the resource runs with 256 simulated characters, and every database call is counted. It is not a test with 256 real players.

The profile is deliberately extreme:

Characters online256
Scans running at the same time50
Live results open at the same time100
Devices switched on32
Deaths being resolved8
Staff watching pairs4
Memory tablea year of memories, 30 % expired, 15 % disguise memories
Scan churnone scan per player every ten minutes, sustained

Fifty simultaneous scans on a 256-player server is far beyond what a normal evening looks like. It is chosen as a ceiling, not as a typical load.

What to expect

An idle or quiet server pays almost nothing. With 256 characters loaded and nobody scanning, the server loops cost about 0.01 ms per second: they have nothing to do and return at once.

The database is quiet. About 32 writes and 68 reads per minute at the full profile above: roughly one write per finished scan.

  • No query is ever issued from inside a per-second loop.
  • Recognising somebody issues no query at all. The answer comes from memories that are already loaded, because the person looking is online.

MySQL is not on this resource's busy path.

Memory is proportional and stable. Each remembered person costs about 2.5 KB of server memory.

PlayersRoughly
64≈ 18 MB
128≈ 36 MB
256≈ 72 MB

Treat those figures as a floor and budget about 25 % more on a live server (≈ 90 MB at 256 players). Over a sustained run the memory use stayed level — nothing leaks.

The scan and live-result loops are where the cost is. At the full stress profile — 50 simultaneous scans and 100 live results — these two loops are the largest single item. Both scale with activity, not with player count: a server with three scans running pays for three scans.

How the work scales

Everything is sized by what is happening, never by players × players:

WorkRunsGrows with
Scan progressevery 0.5 sScans running right now
Live resultsevery 1 sLive results open right now
Device batteriesevery 1 sDevices switched on right now
Saving a finished scanwhen a scan endsScans that just ended
Database clean-upevery ServerConfig.Prune.IntervalMinutes (15 min)Rows past their retention

That is why an empty server costs almost nothing and a busy one costs in proportion to how busy it is.

Tuning

If you need to reduce the load, these are the levers, in order of effect:

SettingEffect
Config.Scene.Seconds (600)Shorter live results = fewer to keep updated. The largest single lever
Config.Scene.ShowDistance (10.0)Smaller = fewer live results to keep updated
Config.Scan.MaxScannersPerTarget (3)Fewer simultaneous scans on the same person
Config.Scan.MaxParallel (3)Fewer people one player can scan at once
Config.Scan.PairCooldownSeconds (60)Raise it to cut repeated scans of the same pair
Config.Scan.StaleSlotSeconds (10)Lower it so scans that gain nothing free their slot sooner
Config.Environment.EnabledSwitching weather and light off removes one calculation per scan step
ServerConfig.Retention.*Shorter retention = smaller tables

On the client side:

SettingEffect
Config.Scan.CandidateIntervalMs (300)How often a player's game looks for people in front of them
Config.Scan.MaxCandidates (8)How many arrows can be drawn at once
Config.Prompt.ShowOthersOff = only the selected person gets an arrow

Checking your own server

Code
recognition:status

Prints the running scans, cache sizes, which integrations were detected, the voice low-trust flags, the Discord queues and a rolling performance window.

Code
recognition:selftest

The installation check. Every line should say PASS. Include its output when you report a problem.

Database sizing

TableGrows with
MemoriesPlayers × people each of them has met. Removed when they expire
ScansScans finished. Kept for the retention time
Recognition recordsAims, shots, cuffs, robberies. Kept for the retention time, and the busiest table on a combat-heavy server
Clothing classificationsYour clothing packs. Fixed size, written once
PapersCamera reports and statements. Papers go blank after 60 days

recognition:prune runs the clean-up immediately if you would rather not wait for the next run (every 15 minutes by default).