FiveM Lua Optimization Guide 2026: Write Faster Scripts for RP Servers

Published on

How to optimize Lua scripts for FiveM: avoid per-tick loops, use native caching, reduce database calls, and improve server performance.

Poorly optimized Lua scripts are the number one cause of FiveM server lag. Here are the most impactful optimizations.

1. Avoid Per-Tick Loops

The most common mistake:

-- BAD: Runs every frame (~60 times per second)
Citizen.CreateThread(function()
    while true do
        Wait(0)
        -- Heavy operation every frame
        local coords = GetEntityCoords(PlayerPedId())
        DrawMarker(...)
    end
end)

-- GOOD: Only run heavy operations occasionally
Citizen.CreateThread(function()
    while true do
        Wait(1000) -- Once per second
        local coords = GetEntityCoords(PlayerPedId())
        -- Check distance, then switch to fast loop only when needed
        if #(coords - targetCoords) < 50.0 then
            nearTarget = true
        else
            nearTarget = false
        end
    end
end)

Citizen.CreateThread(function()
    while true do
        if nearTarget then
            Wait(0)
            DrawMarker(...)
        else
            Wait(500)
        end
    end
end)

2. Cache Natives

-- BAD: Calling expensive natives repeatedly
Citizen.CreateThread(function()
    while true do
        Wait(0)
        local ped = PlayerPedId()  -- Called every frame
        local coords = GetEntityCoords(ped)  -- Called every frame
    end
end)

-- GOOD: Cache values
local cachedPed = PlayerPedId()
local cachedCoords = GetEntityCoords(cachedPed)

Citizen.CreateThread(function()
    while true do
        Wait(500)
        cachedPed = PlayerPedId()
        cachedCoords = GetEntityCoords(cachedPed)
    end
end)

3. Minimize Database Calls

-- BAD: Database query on every event
RegisterNetEvent('myResource:getData')
AddEventHandler('myResource:getData', function()
    MySQL.query('SELECT * FROM players WHERE id = ?', {source}, function(result)
        -- ...
    end)
end)

-- GOOD: Cache database results
local playerCache = {}

AddEventHandler('playerConnecting', function()
    local src = source
    MySQL.query('SELECT * FROM players WHERE id = ?', {src}, function(result)
        playerCache[src] = result[1]
    end)
end)

4. Use Resmon to Find Lag

Type resmon 1 in the server console. Any resource consistently above 1ms should be investigated.

5. Avoid table.insert in Hot Loops

-- BAD: table.insert is slow in tight loops
for i = 1, 10000 do
    table.insert(myTable, value)
end

-- GOOD: Direct index assignment
for i = 1, 10000 do
    myTable[#myTable + 1] = value
end

FAQ

What causes FiveM server lag? Most commonly: Lua scripts running expensive operations every frame (Wait(0) loops).

How do I find which script is lagging? Use resmon 1 in the server console.

Does the number of resources affect performance? Yes. Fewer, well-optimized resources perform better than many small, unoptimized ones.

Related: FiveM resmon guide, FiveM event security, ox_lib tutorial

Launch Your FiveM Server Today

Get started with professional GTA V roleplay hosting powered by enterprise hardware. Instant deployment and 12/7 support included.