Skip to contentAdd me on Discord for a faster response@chasedevz
CHASEDEVELOPMENTS
Performance

How to optimize FiveM scripts without breaking your city

A practical FiveM optimization workflow: profile real gameplay, reduce unnecessary work, check database calls, and verify changes under load.

A script can look quiet while a server is empty and become a problem the moment players use it. Good FiveM optimization starts with the action that feels slow: opening a garage, loading a character, processing a payment, or standing in a busy area. Measure that action, find the work behind it, and change one thing you can explain.

Build a repeatable test before changing code

Write down the conditions that produce the issue. Include the client hardware, server artifact, game edition, resource versions, player count, location, and steps. A five-minute recording of an actual problem is more useful than a screenshot of an idle resource monitor. Separate a slow interface from a server hitch or a streaming problem; they may feel similar to a player while having different causes.

Choose a small route through the feature and repeat it. For a garage, that could mean opening the menu, loading a long vehicle list, spawning a vehicle, storing it, and repeating after a reconnect. Capture the first visit as well as the second, because caching can hide work that new players still encounter. Keep a copy of the starting configuration so the comparison stays fair.

Use the profiler for the version you actually run

Cfx's profiler documentation describes capturing client and server activity and inspecting resource threads. For Legacy, its guide uses commands including profiler record, profiler status, and profiler saveJSON. The July 15, 2026 Enhanced development update describes a different tracing backend, Perfetto, and profiler save for exporting traces. Use the instructions for your installed edition instead of mixing commands from different generations.

Keep the trace alongside your reproduction notes. Look for work that lines up with the reported pause, then inspect its callers. A function that appears frequently deserves investigation, but frequency alone does not make it the cause. The most useful question is whether removing unnecessary work there improves the same player action in the next capture.

Make idle features cheaper

Cfx's Citizen.Wait reference explains that Wait(0) yields until the next game tick and is appropriate for work required every frame. It also advises avoiding expensive natives on every tick where possible. Increasing every wait value blindly can therefore break drawing or input handling. Decide what must run per frame and what can run only when a feature is active.

For a clothing store, divide the work into entering the area, opening the menu, editing an item, and leaving. Most of that flow has clear transitions. A closed menu should not continually rebuild its catalogue. A camera that only exists during customization should have an explicit cleanup path. Cache values where their lifetime is understood, and refresh them when the character, job, or relevant configuration changes.

Follow the data through the whole feature

List every database request and browser message produced by one interaction. Repeated queries for the same menu, whole-table reads for a single character, and repeated delivery of unchanged data are useful places to investigate. Record query duration and result size before proposing a cache or index. A cache also needs an invalidation rule, otherwise a faster interface may show stale money, outfits, or permissions.

Treat network traffic as part of the same review. Ask who needs each update and when. A personal preview should not trigger citywide updates merely because broadcasting was convenient to implement. Keep authoritative decisions on the server: Cfx's event security guidance recommends server-side validation of values such as money, inventory, position, and permissions. Performance work must preserve those checks.

Report results someone else can reproduce

Repeat the original test after each meaningful change. Check the feature with several players, with long saved lists, after a reconnect, and after a resource restart on staging. Watch for duplicate rewards, missing data, unclosed menus, and a slow first interaction. Those failures can disappear from a short showcase while still affecting a live city.

A useful optimization handover explains the original symptom, the measured cause, the change, and the remaining limits. Include the test conditions with any performance numbers. Chase Developments' optimization service fits into a broader city build that includes scripts, infrastructure, and database work; a clear reproduction and current resource list are a strong starting point for that conversation.

  • Keep before and after traces from matching conditions.
  • Test normal use, repeated use, failure, and reconnects.
  • Document the configuration and a working rollback path.

Sources & further reading

Back to the journal