To find the resource eating a FiveM server's CPU, use FXServer's own profiler in the server console: profiler record 500 records 500 frames, then profiler view gives you a link that opens the capture in Chrome's performance viewer, where each resource's time shows up by name. resmon won't help for this: it's a client command that shows the scripts running on your own game, not the server.
Here's what the hitch warnings mean, how to read the profiler, the usual culprits, and what ServerStats records for you in the meantime.
What a hitch warning means
The warning looks like this in the server console:
server thread hitch warning: timer interval of 412 millisecondsFXServer runs several threads. The ones you see in warnings and in txAdmin's performance chart:
- svMain (the "server thread"): runs every server script's ticks, event handlers and timers. All Lua, JS and C# server resources share it.
- svSync: handles OneSync state: entity ownership and syncing entities to clients.
- svNetwork: sends and receives network packets.
A hitch means one of those threads took far longer than normal to come back around its loop. The number is how long it was stuck. While svMain is stuck, no server script runs: events queue up, callbacks are late, and players see delayed interactions, stuck menus or desync. You may also see sync thread hitch warning or network thread hitch warning, which point at OneSync load or networking instead of scripts.
How worried to be:
- A handful of hitches during startup or a resource restart: normal.
- Occasional hitches under 200 ms with no pattern: watch, but not urgent.
- Regular hitches with players online, or several hundred ms and up: something is blocking the thread and players are feeling it.
resmon vs the server profiler
resmon 1 in the F8 console opens the resource monitor: CPU time and memory for every resource on your client. That's the right tool for client-side FPS drops (a HUD or a client loop running every frame), and useless for server CPU.
For the server, FXServer has a built-in profiler:
profiler record 500 record 500 server frames
profiler status is it recording, and how far along
profiler view prints a link; open it in Chrome to see the capture
profiler saveJSON capture.json save the capture to a file for laterRun it in the server console (or txAdmin's live console) while the problem is happening: during peak hours, or right after an action that you know hitches. Five hundred frames is a sensible start. The capture opens in Chrome DevTools' performance view; look for the long frames and expand them. Resource names appear on the script calls, so the wide blocks in a long frame tell you which resource was running.
Two practical notes: recording costs CPU, so don't leave it running, and a capture of a quiet minute tells you nothing about a spike that happens once an hour.
The usual culprits
Server loops with Wait(0)
Wait(0) means "run again next frame". On the client that's sometimes needed for drawing. On the server it's almost never needed, and a resource with several while true do ... Wait(0) end loops doing real work (iterating all players, all vehicles, all peds) adds that work to every single server frame. Most server loops can wait 500 ms, 1 s or longer, or be replaced by an event.
Database work around the query
oxmysql's async functions and its .await variants yield the script's coroutine while the database works, so a slow query by itself doesn't freeze svMain. What does:
- Loading a huge table in one query and then looping over thousands of rows in Lua.
json.encode/json.decodeon big inventories or metadata blobs, every save, for every player.- Firing a query per player or per item inside a loop instead of batching.
- Saving every player at the same moment on a timer.
oxmysql already logs slow queries with the resource that sent them. The threshold is the mysql_slow_query_warning convar (200 ms by default); set mysql_slow_query_warning 100 in server.cfg makes it stricter.
Net event spam
A client-triggered server event that does real work (inventory checks, database writes) can be fired far more often than the author expected, by many players at once, or by a cheater on purpose. Rate-limit expensive events on the server side.
Entity load and OneSync
With OneSync, the server tracks every networked entity. Resources that spawn vehicles, peds or objects and never clean them up grow the entity count until svSync struggles. Sync thread hitches plus a rising entity count point here, not at a script's CPU.
The host
If hitches line up with backups, other game servers on the same machine, or disk-heavy tasks, the problem is outside FXServer. Check host CPU and disk before rewriting scripts.
txAdmin's performance chart
txAdmin's dashboard charts the server thread's tick times alongside player count, which is the quickest way to see whether hitches track player load or happen at fixed times (saves, restarts, scheduled jobs). It doesn't attribute time to resources; for that you still need the profiler.
What ServerStats records on FiveM
The ServerStats FiveM resource is a server-only resource (no client script) for FiveM and RedM. For performance it records:
- Thread tick times for svMain, svSync and svNetwork, read from FXServer's own Prometheus endpoint (
/perf/, the same data txAdmin charts), as a distribution per 10-second window, plus the server tick rate. - Every hitch warning, counted per thread with its duration, and a hitch event you can see on the timeline. The resource listens to the console for the warning lines above.
- Entities by type, created and removed, and in deep mode (
serverstats_deep true) entities by resource, which is how you catch a resource that leaks vehicles or peds. - Resource starts and stops, so a hitch that follows a restart of one resource is easy to spot.
- Host and process CPU and memory, so you can separate your server from the machine.
- Its own server-thread cost per tick, shown by
serverstats statusin the console.
What it does not do today: it doesn't measure CPU per resource. The only source for that is the profiler commands above, which cost CPU while recording and whose output format isn't documented, so the resource doesn't run them. Use ServerStats to see when and how often hitches happen and what else changed at that moment, then run profiler record at those times to name the resource.
You can get a Discord alert on lag spikes, on every plan including Free. Installing is two lines in server.cfg: see installing on FiveM and RedM.
Checklist
- Note which thread the warnings name: server (scripts), sync (entities) or network.
- Check whether hitches follow player count, a schedule or a resource restart.
- Run
profiler record 500during a bad period and read the long frames withprofiler view. - Search your resources for server-side
Wait(0)loops and per-player queries in loops. - Read oxmysql's slow-query lines (tune
mysql_slow_query_warning) to see slow queries by resource. - Watch entity counts for leaks, and host CPU for neighbours.