The Complete FiveM Server Optimization Guide for 2026
I’ve optimized dozens of FiveM servers over the past few years, from small 32-slot RP communities to 200-player servers. This guide covers everything I’ve learned — the stuff that actually moves the needle.
Server.cfg Settings That Actually Matter
OneSync
If you’re not running OneSync, stop reading and go enable it right now.
set onesync on
Without it, you’re capped at 32 players and entity synchronization is significantly worse. There’s no reason not to use it in 2026.
Game Build
Lock your game build so every player is on the same version. This prevents weird desync issues caused by different game versions having different behaviors.
sv_enforceGameBuild 3258
Use the latest build that’s stable for your setup.
Rate Limiters
State bag abuse is a real thing. Without rate limiters, a single bad client can spam state changes and lag your entire server.
set rateLimiter_stateBagFlood 150
Connection Queue
If you’re running a popular server, set up a proper connection queue to prevent join floods:
sv_maxclients 128
set sv_endpointprivacy true
Script Optimization Basics
The GetDistanceBetweenCoords Problem
This native is slow. Like, really slow compared to the alternative. Every time you call it, you’re making a native call across the Lua-C bridge.
-- Slow (native call)
local dist = GetDistanceBetweenCoords(x1, y1, z1, x2, y2, z2, true)
-- Fast (pure Lua math)
local dist = #(vector3(x1, y1, z1) - vector3(x2, y2, z2))
The vector math version is significantly faster because it stays in Lua. If you have scripts checking distances every frame (which you shouldn’t, but we’ll get to that), this adds up fast.
Cache Your Natives
Calling PlayerPedId() every frame is wasteful. The player’s ped doesn’t change that often.
-- Bad: calling native every frame
while true do
Wait(0)
local ped = PlayerPedId()
-- do stuff with ped
end
-- Better: cache it and refresh periodically
local myPed = PlayerPedId()
CreateThread(function()
while true do
myPed = PlayerPedId()
Wait(1000)
end
end)
DrawMarker Distance Checks
This one drives me crazy. I see it in probably 70% of scripts I audit. A DrawMarker call running every frame with no distance check means the client is rendering a marker that might be 2 kilometers away and completely invisible.
-- Bad: rendering marker from across the map
while true do
Wait(0)
DrawMarker(1, x, y, z, ...)
end
-- Good: only render when close
while true do
local dist = #(GetEntityCoords(myPed) - vector3(x, y, z))
if dist < 30.0 then
Wait(0)
DrawMarker(1, x, y, z, ...)
else
Wait(2000)
end
end
Entity Management
Clean Up After Yourself
The number one rule of entity management: if you create it, delete it. Every CreateVehicle, CreatePed, and CreateObject should have a corresponding DeleteEntity or SetEntityAsNoLongerNeeded.
Server-Side Entity Limits
You can control the maximum number of entities per type:
set onesync_entityLockdown strict
This prevents clients from creating unauthorized entities — a common exploit vector.
Vehicle Cleanup Scripts
Run a vehicle cleanup that periodically removes abandoned vehicles. Not the kind that deletes everything every 5 minutes (your players will hate you), but one that intelligently removes vehicles with no recent driver that are far from any player.
Database Optimization
Indexes Matter
If your queries are slow, chances are you’re missing an index. The most common one I see:
-- If you're looking up players by identifier frequently
CREATE INDEX idx_users_identifier ON users(identifier);
Connection Pooling
oxmysql handles this for you, but if you’re using raw mysql-async, make sure you’re not creating a new connection for every query.
Query Optimization
Avoid SELECT * when you only need one column. Avoid running queries inside loops. Batch operations where possible.
Monitoring Is Not Optional
You wouldn’t run a web application without monitoring. Your FiveM server deserves the same treatment.
The problem with resmon is that it’s a snapshot. You see the current state but not the trend. You can’t tell if that 0.15ms resource has been slowly climbing over the past week, or if hitches spike every evening when player count peaks.
FivePulse tracks everything over time — health scores, per-resource CPU usage, entity counts, hitches, player count. When something goes wrong, you can look at the timeline and see exactly when it started and what changed.
Quick Wins Checklist
If you’re looking for the fastest improvements:
- Search all client scripts for
Wait(0)and add distance-based adaptive waits - Replace
GetDistanceBetweenCoordswith vector math - Switch any
MySQL.Synccalls to async - Remove unused resources
- Add entity cleanup for abandoned vehicles
- Enable OneSync if you haven’t
- Set rate limiters in server.cfg
Do those seven things and you’ll see a noticeable improvement. For everything else, let FivePulse scan your server — it catches things humans miss.
Want to find your server's problems automatically?
FivePulse scans your server and tells you exactly what's wrong — with copy-paste fixes.
Try FivePulse Free