Skip to content

Performance

imshooter edited this page Oct 24, 2026 · 1 revision

Measured on one computer against MariaDB 10.4 on the same machine, with scripts compiled with -d3. The game thread is what a server pays in its tick, and the time until written is what a player waits for.

Natives

Work R41 with pawn-json MySQL
Six cells of a row 1.2 µs 0.7 µs
Four attributes of a JSON cell 5.4 µs 0.9 µs
A formatted query sent 1.6 µs 0.6 µs
A 1000 row insert built in pieces 2.75 ms 0.95 ms

A JSON cell is parsed once, the first time it is read, and the attributes read after the first find it ready.

Saving a gamemode

2000 items of a gamemode, each a row with its JSON attributes, the bags and their insides in tables of their own:

Game thread Until written
R41 with pawn-json 57 ms 98 ms
MySQL, one query built in pieces 17 ms 63 ms
MySQL, prepared statements in batches 16 ms 45 ms

Batches against queries

Rows of items sent by a program of the connector straight to the server, without Pawn, so only the database work is measured. The time runs from the first row added until the server answered, as the median of many rounds.

Rows Insert as text Insert as a batch Upsert as text Upsert as a batch
10 1.38 ms 1.38 ms 0.16 ms 0.11 ms
50 1.71 ms 1.47 ms 0.56 ms 0.34 ms
500 7.75 ms 6.80 ms 4.88 ms 2.63 ms
2000 27.05 ms 19.78 ms 19.46 ms 9.78 ms

A batch gains most where a save writes rows that exist already, the usual case of a gamemode saving its players, and gains more the more rows it sends. A few rows cost the same either way.

Passwords

An Argon2id hash with the defaults, 19 MiB and two passes, takes about 36 ms on a thread of the component. The game thread pays only for sending the work and calling the public.

Hints

  • Read the cells of a row with MySQL_GetRow when there are many of them.
  • Send the same query for many players, items or vehicles as a prepared statement, and many rows as a batch.
  • Keep MySQL_Run for the start of the gamemode, as the server stops while it waits.
  • Give reads that need no order a pool and MySQL_ParallelQuery, so a long one never holds the saves.

Clone this wiki locally