Guide ·
FiveM Resmon Explained: How to Find and Fix High-ms Scripts
Read FiveM's resource monitor, know what a good ms value is, and fix the code patterns that make scripts heavy - with Lua examples you can copy.
When a FiveM server "feels laggy", the cause is usually one or two scripts eating CPU time on every frame. FiveM has a built-in tool to find them: resmon, the resource monitor.
Open resmon
Press F8 in-game and type:
resmon 1A table appears in the corner with every running client resource. Type resmon 0 to hide it.
Read the columns
| Column | Meaning |
|---|---|
| CPU msec | Milliseconds of CPU time per frame the resource uses on your PC |
| Time % | Share of the frame spent in that resource |
| Memory | RAM the resource's scripts use |
| Streaming | Size of the models and textures it streams |
At 60 FPS a whole frame is about 16.6 ms, and the game itself needs most of it. Every millisecond a script takes comes straight out of the player's FPS.
What is a good value?
| CPU msec (idle) | Verdict |
|---|---|
| 0.00 - 0.02 | Excellent, script sleeps when not in use |
| 0.03 - 0.10 | Fine |
| 0.10 - 0.30 | Worth a look if many scripts sit here |
| above 0.30 | Heavy, fix or replace it |
Values while a menu is open or a job is running can be higher. What matters is what a script costs when nobody is using it, because players spend most of their time there.
The usual culprits and how to fix them
Loops that never sleep
The most common problem: a loop that runs every frame to check a distance.
CreateThread(function()
while true do
Wait(0)
local coords = GetEntityCoords(PlayerPedId())
if #(coords - shopCoords) < 2.0 then
DrawText3D(shopCoords, "[E] Open shop")
end
end
end)Fix it by sleeping long when the player is far away and only running every frame when they are close:
CreateThread(function()
while true do
local sleep = 1000
local coords = GetEntityCoords(PlayerPedId())
local distance = #(coords - shopCoords)
if distance < 20.0 then
sleep = 0
if distance < 2.0 then
DrawText3D(shopCoords, "[E] Open shop")
end
end
Wait(sleep)
end
end)Doing the work yourself instead of using zones
If you use ox_lib, lib.points and lib.zones handle the distance checks for you and only call your code when the player is nearby. A script built on them idles at 0.00 ms.
local point = lib.points.new({ coords = shopCoords, distance = 2.0 })
function point:onEnter()
lib.showTextUI("[E] Open shop")
end
function point:onExit()
lib.hideTextUI()
endMarkers drawn for every location at once
Drawing 50 markers per frame for 50 garages costs a lot. Draw only those within 20-30 metres, or replace markers with ox_target interactions.
Native calls repeated every frame
Calls like PlayerPedId() and GetVehiclePedIsIn() are cheap alone, but add up across many scripts. ox_lib's cache.ped and cache.vehicle keep them for you.
Go deeper with the profiler
For a precise picture, record a profile in F8:
profiler record 300
profiler viewThis records 300 frames and opens a timeline showing which function in which resource took the time.
Server-side lag
resmon only shows the client. If the server console shows hitch warnings like server thread hitch warning, the problem is on the server: slow database queries, big loops over all players, or a script waiting on an HTTP request. Run the same profiler commands in the server console to find it.
Scripts that start light
SleepyCode scripts are built to idle at or near 0.00 ms, and the documentation lists the measured values, for example for Garages V2. Browse the FiveM scripts, or read how to install FiveM scripts properly.
Every script for ESX and QBCore, in one place.
Browse scripts