Introduction
resmon (Resource Monitor) is built into FiveM client and server. It shows real-time CPU usage and RAM consumed by each resource. The #1 tool to understand why your server lags, why a script crashes, or why a resource consumes 200 MB when it should consume 20.
Prerequisites
- A FiveM server at VeryCloud
- A FiveM client (you in-game as admin)
- Access to F8 console
Step 1: Open resmon (client)
In-game, F8 console:
resmon
Or bind to a key:
bind keyboard f3 "resmon"
You get a floating window with resource list, CPU% and MEM.
Step 2: Read the indicators
| Column | Meaning |
|---|---|
| Resource | Resource name |
| CPU msec | CPU time per tick (in ms) |
| Memory | RAM consumed |
| Streaming | MB of streamed assets |
| Time | Cumulative time since start |
Thresholds to know:
- CPU msec < 0.5ms: OK
- CPU msec 0.5–1ms: watch
- CPU msec > 1ms: optimization needed
- CPU msec > 3ms: that's what ruins your perf
Step 3: Identify problem resources
Sort resmon by decreasing CPU msec. Top 2-3 resources consume the most.
Often:
- Frameworks (ESX, QBCore): 0.5-1.5ms — normal as they're everywhere
- ox_lib or util: 0.1-0.3ms — OK
- A custom resource at 2-5ms → suspect, profile it
- Anticheat: 0.5-1.5ms — normal but monitor
Step 4: Fine profiling with ProfData
Beyond resmon, FiveM exposes a more advanced profiler:
profiler record 1000
# wait 10 seconds of normal gameplay
profiler view
Generates a dump viewable in Chrome DevTools (chrome://tracing).
profiler save mygame_profile.json
Detailed timeline analysis of hooks and events.
Step 5: Diagnose a memory leak
If a resource's memory climbs without ever going down:
- Note Memory value at T0
- Wait 30 minutes of normal gameplay
- Compare
Doubled without functional reason → leak.
Classic causes:
- Unsubscribed event listeners (cumulative
RegisterNetEvent) - Lua tables growing without purging (
logs[#logs+1] = ...never cleared) - Uncleared timers (looping
SetTimeout)
Step 6: Optimize a Lua resource
CPU reduction techniques:
Increase Wait in loops:
-- BAD: tick every frame
CreateThread(function()
while true do
Wait(0)
end
end)
-- GOOD: every 500ms if non-critical
CreateThread(function()
while true do
Wait(500)
end
end)
Avoid recomputes:
-- BAD: recompute every call
function GetNearbyPlayers()
local players = {}
for _, p in ipairs(GetActivePlayers()) do
if #(GetEntityCoords(...) - ...) < 50 then
table.insert(players, p)
end
end
return players
end
-- GOOD: cache + periodic refresh
local _cache = {}
CreateThread(function()
while true do
_cache = ComputeNearbyPlayers()
Wait(1000)
end
end)
function GetNearbyPlayers() return _cache end
Targeted events instead of global broadcasts:
-- BAD: everyone receives
TriggerClientEvent('myevent', -1, data)
-- GOOD: only the concerned player
TriggerClientEvent('myevent', playerId, data)
Step 7: Optimize on natives side
Major consumers:
GetEntityCoords()in tight loops → cacheGetClosestVehicle()→ batch less frequentlyDrawText3D()every frame without distance guard
-- Guard before heavy draw
local plyCoord = GetEntityCoords(PlayerPedId())
local targetCoord = GetEntityCoords(target)
if #(plyCoord - targetCoord) < 20 then
DrawText3D(...)
end
Step 8: Reduce RAM usage
Lua-side:
- Clear unused tables:
myTable = {} - Occasional
collectgarbage('collect')after big operations - Don't store entities in tables — only IDs
Assets-side:
- Compress YTDs via OpenIV
- Delete unused stream resources
Step 9: Server-side profiling
FXServer console:
prof start
prof stop
Or txAdmin → System Logs → CPU server-side per resource.
A resource consuming >5% CPU server-side continuously is suspect.
Step 10: Scheduled restarts
Well-coded resources shouldn't need restarts. But many third-party scripts have micro-leaks. Schedule auto-restarts:
- Every 12h via Wisp Schedules (Action: Power → Restart)
- Announce in-game 5 min before via Discord webhook or broadcast
- Off-peak time (5 AM)
Troubleshooting
resmon shows nothing — you're not admin (sometimes required), F8 wrong binding (try ~ or ^).
Huge CPU msec on a "idle" resource — infinite loop without Wait somewhere; memory leak forcing constant GC.
Server lags but no resource >1ms — not FiveM the issue. Check hardware (Wisp graphs) or network latency.
Useful commands
resmon
profiler record 1000
profiler view
prof start
prof stop
restart <resource>
stop <resource>
Conclusion
resmon = perf swiss army knife. 10 minutes to identify hungry resources, a few hours to fix the worst bottlenecks, server goes from "lag at 50 players" to "stable at 100". Combined with scheduled restarts you have a clean operation. Advanced profiler (profiler record) when resmon isn't enough.
Going further: load testing with bots, external monitoring via custom Prometheus exporter, hot path optimization in C++ via natives.


















