ViceHubFiveM discovery hub
ScriptsServersStreamersViceAIArticlesMerch
Sign inSign in

Navigate

ScriptsServersStreamersViceAIArticlesMerchSign in
ViceHub
ScriptsServersStreamersArticlesShopsFiveM StatsAboutMethodologyEditorial PolicyContactMerchSubmitSign in
QBCore Scripts·ESX Scripts·Free FiveM Scripts·Best FiveM Scripts·FiveM Server List·Live GTA Streams
© 2026 ViceHub · Independent FiveM discovery hub.Privacy · Terms · Not affiliated with Cfx.re, Rockstar Games, or Take-Two Interactive.
All articles →

FiveM Performance: How to Actually Find What's Eating Your Frames

ByBoris K.·Founder & Editor, ViceHub
Jun 24, 20267 min read

Half the performance advice in FiveM is wrong, including the famous one about Wait(0) — the official docs mandate exactly what the community tells you to avoid. Here is how to find the real culprit.

There is more confidently-wrong advice about FiveM performance than about any other part of the platform, and one piece of it — the famous rule about Citizen.Wait(0) — is not just wrong, it is the exact opposite of what the official documentation says. We will get to that.

First, the tools, because most people never get them working.

Step 1: Make resmon actually run

You open F8, you type resmon, and you get:

Access denied for command resmon

This stops an enormous number of people, and the answer is not in most guides. resmon is a developer command, and developer commands require the client to be in developer mode. Two ways to get there:

  • Launch FiveM with +set moo 31337 — add it to the target of your FiveM shortcut. This is the normal way.
  • Or run a non-production update channel (Beta or Latest).

Then resmon true opens the resource monitor. (resmon 1 works identically — FiveM's boolean parser treats any non-zero integer as true.)

While you are there, netgraph true gives you live network metrics — ping, packets and bytes in and out — which is the tool for "is this lag or is this frames?", a question people answer wrong constantly.

Step 2: Read the columns properly

resmon gives you six columns, and most people only look at one:

  • — the resource name.

Related articles

How Many Players Does a FiveM Server Need to Feel Alive?
Jul 13, 2026

How Many Players Does a FiveM Server Need to Feel Alive?

The median FiveM server peaked at two players. Not two hundred — two. We measured 31,334 of them. Here is what a server realistically needs to feel alive, and why your slot count is fiction.

server datafivem serverserver owners
7 min readRead
FiveM Server Requirements: What Actually Matters (and What Hosts Invent)
Jul 13, 2026

FiveM Server Requirements: What Actually Matters (and What Hosts Invent)

Every FiveM server requirements table you have read was invented by a company selling servers. Cfx.re publishes no hardware spec at all. Here is what actually determines whether your server runs well.

fivem serverhostingperformance
6 min read
Resource
  • CPU msec — average tick time. This is the number everyone stares at.
  • Time % — this resource's share of total script time, not of your frame. A resource can show a big percentage simply because everything else is cheap.
  • CPU (inclusive) — total time including what it calls into.
  • Memory — script runtime memory.
  • Streaming — streaming memory for that resource's assets. This is the one people ignore, and for map and MLO resources it is often the column that actually matters.
  • There is also a [Total CPU] summary row showing total script time and script time as a share of frame time. That row is the honest one: if your total script time is small and your frames are still bad, your problem is not scripts, and no amount of resmon-staring will fix it.

    Step 3: Know the only real threshold

    Everyone will tell you a resource should idle at 0.01ms and that anything over 1ms is broken. Cfx.re publishes no such threshold. Those numbers are community folklore, repeated until they sound official.

    Here is what actually exists inside FiveM's code:

    • resmon colour-grades CPU time on a 1ms to 8ms scale — green around 1ms, red around 8ms.
    • The client shows players an on-screen warning when a resource's average tick time exceeds 6ms: "Resource time warning… Please contact the server owner to resolve this issue."

    That second one is the number to care about, because it is the point at which FiveM itself decides your server is bad enough to tell your players about it. 6ms average tick is the line FiveM's own code calls a problem. Use that, and ignore anyone quoting you a decimal place.

    Context matters more than any single figure anyway. A resource sitting at 3ms while you are actively using its menu is fine. A resource sitting at 3ms while you stand still in a field doing nothing is a bug.

    Step 4: Use the profiler, which nobody does

    resmon tells you which resource is expensive. It does not tell you why. The profiler does, and it is built in, and almost nobody uses it.

    In the client console (F8) or the server console:

    profiler record 500
    profiler status
    profiler view

    500 frames is the documented starting point. profiler view opens the capture in Google Chrome (it needs Chrome — server-side, it prints a link you paste in yourself). You can also profiler saveJSON myprofile.json and load the file into Chrome DevTools under the Performance tab.

    What you get is a flame graph of the actual script threads, frame by frame. You can see the exact function that spiked. This is the difference between "qb-something is at 4ms" and "this specific loop is calling an expensive native every frame" — and only one of those is actionable.

    It works server-side too, which is how you chase down hitch warnings.

    The Wait(0) myth, which needs to die

    Here is the advice you have read a hundred times: "never use Citizen.Wait(0), it destroys performance — use Wait(500) instead."

    The official FiveM documentation says the opposite. From the Citizen.Wait reference, near-verbatim: something that needs to run per frame should use Wait(0) — using Wait(5) or Wait(10) will cause ticks to be missed at higher frame rates.

    The reasoning is simple once you see it. Wait(0) means "resume on the next game tick". At 60fps that is every 16.6ms; at 180fps every 5.5ms. If your loop genuinely must run every frame — drawing a marker, checking a key, rendering text — then Wait(10) does not make it cheaper, it makes it skip frames, and your marker flickers.

    Raising the Wait value does not fix a slow loop. It just runs the slow loop less often and hides the number in resmon. The actual documented advice is:

    • Do less inside the tick. The official best practices call out heavy natives — expensive shape tests and similar — as the thing not to call per frame.
    • Cache what you call repeatedly. PlayerPedId() is the canonical example: cache it, do not call it several times per frame.
    • Sleep dynamically. The documented pattern is a variable sleep: run at Wait(0) when the player is near the thing you care about, and set the sleep to 500 or 1000 when they are not. One loop, two speeds.
    CreateThread(function()
        while true do
            local sleep = 1000
            local ped = PlayerPedId()
            local coords = GetEntityCoords(ped)
    
            if #(coords - MARKER_COORDS) < 20.0 then
                sleep = 0
                DrawMarker(--[[ ... ]])
            end
    
            Wait(sleep)
        end
    end)

    That loop costs almost nothing when the player is across the map and runs every frame when they are standing on top of it. That is the answer. Not Wait(500).

    And to be clear on the one thing everyone gets right: a while true do loop with no Wait at all will hang the client. That is real. It is just not an argument for Wait(500).

    Server-side is a different problem

    Client frames and server hitches are not the same thing, and people mix them up constantly.

    FXServer runs three threads, and the one that matters is svMain:

    • svMain ticks at 20Hz — a 50ms budget per tick.
    • Every server-side resource ticks on svMain.

    Read that second line again, because it is the whole story of server performance. There is no per-resource isolation. One blocking script stalls every other resource on the server. A slow SQL query with no index, a long synchronous loop, a badly written export — any of them freeze everything for everyone.

    When svMain overruns badly you get this in console:

    server thread hitch warning: timer interval of 384 milliseconds

    That is FXServer telling you a tick took hundreds of milliseconds against a 50ms budget. Every player felt it. The two usual culprits, per Cfx's own guidance, are underperforming SQL queries and unoptimised loops that halt script execution — so start with your database. A missing index on a table your framework queries on every player spawn will do this, and it will get worse as your player table grows, which is why servers mysteriously start hitching six months in.

    Chase it with the server-side profiler. It is the only tool that will tell you which resource, and which function, ate the tick.

    The order to actually debug in

    1. Check [Total CPU] in resmon first. If total script time is low and frames are still bad, stop looking at scripts. It is your GPU, your graphics mods, or streaming.
    2. Sort by CPU msec. Anything averaging over 6ms is a problem FiveM itself will complain to your players about.
    3. Check the Streaming column on map and MLO resources. Frames are not always about script time.
    4. Profile the offender rather than guessing. profiler record 500, then read the flame graph.
    5. Test with players on. A server that is clean when empty and dies at 25 players has a problem that only exists under load — and per our population data, 25 concurrent players already puts you in the top few percent of servers, so this is a good problem to have.
    6. For server hitches, look at your database first. It is almost always the database.

    And one habit worth more than all of the above: add resources one at a time. When you install eight scripts in an evening and the server starts hitching, you have eight suspects and no baseline. Add one, run it, look at resmon, then add the next. You can browse resources with their framework compatibility declared up front on the FiveM scripts marketplace.

    Frequently asked questions

    Why does resmon say 'Access denied for command resmon'?

    Because resmon is a developer command and your client is not in developer mode. Launch FiveM with the +set moo 31337 argument (add it to a shortcut), or run a non-production update channel such as Beta. Then resmon true, or resmon 1, will open the resource monitor.

    What is a good ms value for a FiveM resource?

    Cfx.re does not publish an official threshold, and anyone quoting you a precise safe number is repeating community folklore. What does exist in FiveM's own code: resmon colour-grades CPU time on a 1ms to 8ms scale, and the client shows players a resource time warning when a resource's average tick exceeds 6ms. Treat 6ms as the line FiveM itself considers a problem.

    Should I avoid Citizen.Wait(0) in FiveM scripts?

    No — and this is the most repeated bad advice in FiveM. The official documentation states that anything that genuinely needs to run every frame should use Wait(0), because Wait(5) or Wait(10) will cause missed ticks at higher frame rates. The fix for a heavy loop is to do less work inside the tick, or to sleep dynamically when idle, not to arbitrarily raise the Wait value.

    How do I use the FiveM profiler?

    In the client console (F8) or the server console, run profiler record 500, then profiler status to check it, then profiler view to open the capture in Google Chrome. You can also use profiler saveJSON filename.json and load the file in Chrome DevTools under the Performance tab. It works on both the client and the server.

    What is a server thread hitch warning?

    It means FXServer's main thread took far longer than its budget for a tick. The main thread runs at 20Hz, a 50ms budget, and every server-side resource ticks on it — so one blocking script stalls every other resource on the server. That is why a single bad SQL query or unguarded loop can freeze the whole server.

    Researched and drafted with AI assistance. How ViceHub guides are made

    fivem serverperformanceresmonoptimizationscripting

    Join the Discord for more FiveM signal

    Get resource discovery notes, shop and server discussion, server-owner advice, and community updates from the ViceHub crew.

    Join the Discord

    Written by

    Boris K.Founder & Editor, ViceHub

    Built the crawler behind ViceHub's server data. Writes the guides here.

    More from Boris →

    On this page

    Step 1: Make resmon actually runStep 2: Read the columns properlyStep 3: Know the only real thresholdStep 4: Use the profiler, which nobody doesThe Wait(0) myth, which needs to dieServer-side is a different problemThe order to actually debug in
    FiveM resourcesAll articles
    Read
    Why Your FiveM Server Isn't Showing in the Server List
    Jul 13, 2026

    Why Your FiveM Server Isn't Showing in the Server List

    Your server boots, you can join by IP, and it is nowhere in the browser. There is a specific list of causes, and one of them — an artifact rule Cfx.re enforces — is the one nobody mentions.

    fivem serverfxservertroubleshooting
    8 min readRead