Client and server in depth · Lesson 2/4 · 9 min

Threads and Wait(): performance without dying

Badly written loops are the #1 cause of lag in FiveM. Learn to use Wait() properly.

On the client, a lot of code runs in loops (threads). If a loop doesn't rest (Wait), it kills FPS. The trick is to Wait long when nothing is happening and short only when needed. This is independent of the framework.

The FPS killer

lua
-- ❌ BAD: runs 60+ times per second ALWAYS
CreateThread(function()
  while true do
    Wait(0) -- never a permanent Wait(0)!
    local ped = PlayerPedId()
    -- heavy checks every frame...
  end
end)

Kills performance

The healthy version

lua
CreateThread(function()
  while true do
    local sleep = 1000 -- by default rest 1s
    local ped = PlayerPedId()
    local coords = GetEntityCoords(ped)
    local dist = #(coords - Config.ZonaTienda)

    if dist < 20.0 then
      sleep = 0 -- only when you're close, go per frame
      -- draw marker, detect E key, etc.
    end
    Wait(sleep)
  end
end)

Dynamic Wait

Golden pattern: a sleep variable that starts high (500-1000ms) and only drops to 0 when the player is close/interacting. That way your resource uses ~0.01ms at idle (check it with resmon).

Practice what you learned

0/3
Test

¿Cuál es la causa nº1 de lag (caída de FPS) en el cliente de FiveM?

Corrige el error

Este thread quema CPU: corre cada frame siempre. Arréglalo con un Wait dinámico que descanse 1000ms por defecto y solo baje a 0 cuando el jugador esté cerca.

Este código tiene un fallo:

1CreateThread(function()
2 while true do
3 Wait(0)
4 local ped = PlayerPedId()
5 local dist = #(GetEntityCoords(ped) - Config.ZonaTienda)
6 if dist < 20.0 then
7 -- dibujar marcador
8 end
9 end
10end)

Reescríbelo corregido:

Pista

Declara local sleep = 1000 al principio del bucle, ponlo a 0 solo dentro del if dist < 20.0, y termina con Wait(sleep).

Ordena el código

Ordena un thread con Wait dinámico que solo trabaja cuando el jugador está cerca de la zona.

Coloca las líneas en el orden correcto con las flechas.

local dist = #(GetEntityCoords(PlayerPedId()) - Config.ZonaTienda)
Wait(sleep)
CreateThread(function()
local sleep = 1000
end)
end
if dist < 20.0 then sleep = 0 end
while true do
Pista

Abre el thread y el bucle, declara sleep alto, calcula distancia, bájalo solo si estás cerca, y duerme con Wait(sleep) al final.

Challenge: code it yourself

Convert a loop that always draws a 3D text into one that only works when the player is less than 15 meters away.

Write it yourself in your editor (VS Code) and test it on your server. You learn here by doing it, not by copying.

See hint

Compute #(coords - target); if dist<15 sleep=0 and draw, otherwise sleep=1000.

Escribe aquí tu solución:

How was this lesson?