Profiler ton serveur FiveM avec resmon

Profiler ton serveur FiveM avec resmon

resmon est l'outil natif de profiling FiveM : identifier les ressources qui consomment, les memory leaks, et les tick lags. Guide pour identifier les goulets d'étranglement sur Wisp chez VeryCloud.

Introduction

resmon (Resource Monitor) est intégré à FiveM client et serveur. Il affiche en temps réel le CPU usage et la RAM consommée par chaque ressource. C'est l'outil n°1 pour comprendre pourquoi ton serveur lag, pourquoi un script crash, ou pourquoi une ressource bouffe 200 Mo qui devraient en faire 20.

Prérequis

  • Un serveur FiveM chez VeryCloud
  • Un client FiveM (toi en jeu en tant qu'admin)
  • Accès console F8

Étape 1 : Ouvrir resmon (client)

En jeu, console F8 :

resmon

Ou bind sur une touche pour l'ouvrir vite :

bind keyboard f3 "resmon"

Tu obtiens une fenêtre flottante avec la liste des ressources, CPU% et MEM.

Étape 2 : Lire les indicateurs

Colonne Signification
Resource Nom de la ressource
CPU msec Temps CPU consommé par tick (en ms)
Memory RAM consommée
Streaming Mo d'assets streamés (modèles, textures)
Time Temps total cumulé depuis le démarrage

Seuils à connaître :

  • CPU msec < 0.5ms : OK
  • CPU msec 0.5–1ms : à surveiller
  • CPU msec > 1ms : optimisation nécessaire
  • CPU msec > 3ms : c'est ça qui te ruine les perfs

Étape 3 : Identifier les ressources problématiques

Trier resmon par CPU msec décroissant. Tu verras tout en haut les 2-3 ressources qui consomment le plus.

Souvent :

  • Frameworks (ESX, QBCore) : 0.5-1.5ms — normal car ils sont partout
  • ox_lib ou util : 0.1-0.3ms — OK
  • Une ressource custom à 2-5ms → suspect, à profiler
  • Anticheat : 0.5-1.5ms — normal mais à monitorer

Étape 4 : Profiling fin avec ProfData

Pour aller plus loin que resmon, FiveM expose un profiler plus avancé :

profiler record 1000
# attends 10 secondes de gameplay
profiler view

Génère un dump consultable dans Chrome DevTools (chrome://tracing).

profiler save mongame_profile.json

Tu peux ensuite analyser le profil avec un timeline détaillée des hooks et events.

Étape 5 : Diagnostiquer un memory leak

Si la mémoire d'une ressource grimpe en continu sans jamais redescendre :

  1. Note la valeur Memory de la ressource à T0
  2. Attends 30 minutes de gameplay normal
  3. Recompare

Si elle a doublé sans raison fonctionnelle → leak.

Causes classiques :

  • Event listeners non désouscrits (RegisterNetEvent cumulatif)
  • Tables Lua qui grossissent sans être purgées (logs[#logs+1] = ... jamais vidé)
  • Timers non-clearés (SetTimeout qui tourne en boucle)

Étape 6 : Optimiser une ressource Lua

Quelques techniques courantes pour réduire le CPU usage :

Augmenter le Wait dans les boucles :

-- MAUVAIS : tick chaque frame
CreateThread(function()
    while true do
        Wait(0)
        -- check toutes les 16ms
    end
end)

-- BON : check toutes les 500ms si non critique
CreateThread(function()
    while true do
        Wait(500)
        -- ...
    end
end)

Éviter les recalculs :

-- MAUVAIS : recalcul à chaque appel
function GetNearbyPlayers()
    local players = {}
    for _, p in ipairs(GetActivePlayers()) do
        if #(GetEntityCoords(...) - ...) < 50 then
            table.insert(players, p)
        end
    end
    return players
end

-- BON : cache + refresh régulier
local _cache = {}
CreateThread(function()
    while true do
        _cache = ComputeNearbyPlayers()
        Wait(1000)
    end
end)
function GetNearbyPlayers() return _cache end

Délaisser les events globaux au profit d'events ciblés :

-- MAUVAIS : tout le monde reçoit
TriggerClientEvent('myevent', -1, data)

-- BON : seul le joueur concerné reçoit
TriggerClientEvent('myevent', playerId, data)

Étape 7 : Optimiser une ressource côté natives

Les natives FiveM ne sont pas toutes égales. Quelques gros consommateurs :

  • GetEntityCoords() dans une boucle serrée → cache
  • GetClosestVehicle() → batch en moins fréquent
  • DrawText3D() chaque frame sans condition de distance → guard
-- Guard avant un draw lourd
local plyCoord = GetEntityCoords(PlayerPedId())
local targetCoord = GetEntityCoords(target)
if #(plyCoord - targetCoord) < 20 then
    DrawText3D(...)
end

Étape 8 : Réduire l'usage RAM

Côté Lua :

  • Vide les tables que tu n'utilises plus : myTable = {}
  • collectgarbage('collect') ponctuel après une grosse opération
  • Évite de stocker des entités en table — stocke seulement les IDs

Côté assets :

  • Compresse les YTD via OpenIV
  • Supprime les ressources stream non utilisées (if isnotused then delete)

Étape 9 : Profiling côté serveur

Côté serveur, en console FXServer :

prof start
prof stop

Ou via txAdmin → System Logs → tu vois le CPU server-side par ressource.

Si une ressource consomme >5% CPU server-side en continu, c'est suspect.

Étape 10 : Restarts planifiés

Une ressource bien codée ne devrait pas avoir besoin de restart. Mais en réalité, beaucoup de scripts tiers ont des micro-leaks. Programme des restarts auto :

  • Toutes les 12h via Wisp Schedules (Action : Power → Restart)
  • Annonce in-game 5 min avant via Discord webhook ou broadcast
  • Heure creuse (5h du matin)

Dépannage

resmon n'affiche rien

  • Tu n'es pas admin sur le serveur (parfois requis)
  • F8 mal binding — essaye ~ ou ^

CPU msec énorme sur une ressource mais elle "ne fait rien"

  • Boucle infinie sans Wait quelque part
  • Memory leak qui force le GC en permanence

Le serveur lag mais aucune ressource n'est >1ms

  • Ce n'est pas FiveM le problème : check le hardware (Wisp graphs)
  • Ou network latency, vérifie ping

Commandes utiles

resmon                     # Profile en jeu
profiler record 1000       # Record 1000 ticks
profiler view              # Voir dans navigateur
prof start                 # Profile cote serveur
prof stop                  # Stop server profile
restart <resource>         # Redemarrer une ressource
stop <resource>            # Arret complet (pour test)

Conclusion

resmon = couteau suisse perf. 10 minutes pour identifier les ressources gourmandes, quelques heures pour fixer les pires goulets, et ton serveur passe de "lag à 50 joueurs" à "stable à 100". Combine avec restarts planifiés et tu as une opération propre. Le profiler avancé (profiler record) sert pour les cas où resmon ne suffit pas.

Pour aller plus loin : tests de charge avec bots, monitoring externe via Prometheus exporter custom, optimization en C++ via natives pour les hot paths.

Ressources

Join our Discord community server

For any questions, suggestions, or just to chat with the community, join us on Discord!

900+Members