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

ColonneSignification
ResourceNom de la ressource
CPU msecTemps CPU consommé par tick (en ms)
MemoryRAM consommée
StreamingMo d'assets streamés (modèles, textures)
TimeTemps 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

Rejoignez notre serveur communautaire Discord

Pour toute question, suggestion ou simplement pour discuter avec la communauté, rejoignez-nous sur Discord !

900+Membres