Every FiveM server owner eventually asks some version of “why is my server laggy when the VPS CPU is only at 40%?”
The answer is almost always TPS — server ticks per second. It's the metric that determines whether your server feels smooth, independently of your hardware spec. Here's what it is and how to actually fix it.
What TPS actually means
FiveM's server-side scripting runtime runs on a loop. Every iteration of that loop is a tick: the server processes incoming events, runs every script's Wait(0) loops, handles callbacks, sends network updates to connected players, and repeats.
The target rate is 60 ticks per second — one tick every ~16.67 ms. When your scripts are light enough that the work finishes inside that 16.67 ms budget, you run at 60 TPS and everything feels smooth.
When a script takes longer — say 25 ms to finish its tick work — you run at 40 TPS instead of 60. That's where rubber-banding, delayed menu responses, and “I pressed E and nothing happened” come from.
TPS is not a hardware metric. It's a script-quality metric. Upgrading your VPS almost never fixes a TPS problem because the FiveM main thread is single-threaded — a faster single core helps marginally, more cores help not at all.
The four TPS killers
1. Unoptimized script loops
The most common TPS killer is a script doing more work per tick than it needs to. Classic mistakes: calling GetPlayerPed(-1) inside a tight loop (use the ox_lib cache.ped instead); iterating over all players on every tick when you only need to check every second; running heavy math inCitizen.CreateThread with Wait(0) whenWait(1000) would do.
txAdmin's resmon (F8 on the server console) shows per-resource CPU time per tick. Any resource using more than 1-2 ms on average is a candidate for rewriting. Anything over 5 ms is usually a ticking time bomb.
2. Database work on the main thread
Synchronous database queries (MySQL.Sync.fetchAll and similar) block the main tick until they return. A single 40 ms query drops your TPS for that tick to 25. Switch to async (MySQL.Async or the oxmysql promise-based API) and index your queries — see the Quasar University FiveM database design guide for the full treatment.
3. Resource startup spikes
When a server restarts, all resources start in parallel. If you have 80+ resources loading at once, you get a 20-30 second window of 10-15 TPS while everything initializes. Stagger critical resources using server.cfgordering, and avoid heavy work in a resource's top-level CreateThreadthat runs on start.
4. Entity density hotspots
Areas with lots of NPCs, vehicles, or props (police HQ, hospitals, the Legion Square bank) cause local entity-update surges that impact the server tick. Mitigations: use polyzone-based resource activation (only run NPC logic when a player is nearby), despawn unused vehicles, and cap NPC counts per zone.
What almost never helps
- Upgrading from a 4-core to an 8-core VPS.Main thread is single-threaded.
- More RAM. Only helps if you were actually running out, which is rare.
- Switching Linux ↔ Windows. Marginal at best.
- Removing ox_lib or ox_inventory.These are well-optimized; they're almost never the problem.
Diagnosing TPS in under 10 minutes
- Open
txAdmin→ Server dashboard. Note current TPS on both server and network threads. - On the server console, hit
F8and typeresmon. Sort by CPU time. - The top 3 resources by CPU time are your suspects. Anything above 1 ms average and you start there.
- For each suspect, open the resource's
.luafiles and search forwhile true doandWait(0). Most unoptimized scripts have at least one of these running more often than needed. - If it's a third-party resource, check for an updated version, or an alternative that does the same job.
When to get help
TPS diagnosis is the single most common “bring your server to the call” topic in Academy Elite. If you've gone through the checklist above and still can't identify the bottleneck, Elite gets you a weekly code review that almost always resolves this in one session. The Enterprise track includes done-with-you server profiling.
Frequently asked questions
- What's a good TPS for a FiveM server?
- 60 TPS on both the server and network threads is the healthy target. 50-59 is tolerable for most players. Below 48, the server starts to feel laggy in ways players blame on their internet. Below 40, players rage-quit. Monitor with txAdmin's server monitor or resource-monitor tools.
- What causes TPS drops in FiveM?
- Four main causes, in order of frequency: unoptimized scripts with tight loops (while true do ... Wait(0) everywhere), synchronous database queries on the main thread, too many resources starting at once during restart, and entity/vehicle/ped density in one area (dense zones like banks, ambulance, police HQ). CPU exhaustion on the VPS is a distant fifth cause.
- Does upgrading my VPS fix low TPS?
- Usually not. TPS drops are most often single-thread bottlenecks — a faster CPU with more cores rarely helps because the FiveM main thread is single-threaded. A 3.5 GHz modern CPU and a 5.0 GHz modern CPU run the same TPS on the same script stack. Fix the script, then think about hardware.
- How do I measure TPS on my FiveM server?
- txAdmin's dashboard shows TPS and thread-hitch data. resmon (the built-in resource monitor, F8) shows per-resource CPU time per tick. For deeper analysis, the /profiler command produces flame graphs you can import. These three together cover 95% of TPS diagnosis.
- Does ox_lib or ox_inventory affect TPS?
- They're both well-optimized. On a typical server stack, ox_lib and ox_inventory combined run well under 1ms per tick. The usual TPS killers are older framework scripts (legacy ESX resources especially), custom one-off scripts from smaller authors, and any script that does database work in a per-tick loop. Profile before you blame a dependency.