[GUIDE] Optimizing FiveM Server Performance

Guide: Optimizing FiveM Server Performance

Running a high-performance FiveM server is crucial for providing a smooth and immersive experience for players. Whether you’re managing a small community or a large roleplay server, optimizing your server’s performance can drastically improve gameplay and reduce issues like lag, crashes, or resource overload. This guide will walk you through best practices, tools, and tips for optimizing your FiveM server performance.

1. Optimize Resource Usage

Optimizing resource usage is key to maintaining a high-performance FiveM server. This involves ensuring that all scripts are efficient, minimizing unnecessary event usage, and cleaning up unused resources.

1.1 Script Efficiency

Inefficient scripts can consume more CPU and memory than necessary. Optimizing these scripts reduces the overall load on your server.

Example of an inefficient loop:

Citizen.CreateThread(function()
    while true do
        Citizen.Wait(0) -- Runs every tick, causing unnecessary CPU load
        local playerPed = PlayerPedId()
        -- Code that checks or updates something
    end
end)

Optimized version:

Citizen.CreateThread(function()
    while true do
        Citizen.Wait(500) -- Reduced frequency to once every 500 ms
        local playerPed = PlayerPedId()
        -- Code that checks or updates something less frequently
    end
end)

Tip: Use Citizen.Wait with a higher value where real-time updates aren’t necessary. This prevents the script from running every frame, reducing CPU load.

1.2 Minimize Event Usage

Overusing events, especially with high-frequency triggers, can cause significant performance issues.

Example of high-frequency event usage:

RegisterNetEvent('checkPlayerStatus')
AddEventHandler('checkPlayerStatus', function()
    -- Code to check player status
end)

Optimized with batching or reduced calls:

Citizen.CreateThread(function()
    while true do
        Citizen.Wait(1000) -- Check status every second instead of triggering events frequently
        TriggerServerEvent('batchPlayerStatusCheck')
    end
end)

RegisterNetEvent('batchPlayerStatusCheck')
AddEventHandler('batchPlayerStatusCheck', function(data)
    -- Process all player status data at once
end)

1.3 Remove Unused Resources

Regularly review and remove unused or redundant resources. These can add unnecessary load to your server. Use the resource monitor to identify and disable them:

Example of disabling a resource:
In your server.cfg, comment out or remove unnecessary resources:

#start unused_resource



2. Profile Server Performance

Profiling your server’s performance helps identify which resources are consuming excessive CPU, memory, or network bandwidth.

2.1 Using the resmon Command

The resmon (resource monitor) command provides a real-time view of resource usage. To use it, simply run:

resmon 1

This will display all active resources, along with their CPU and memory usage. Look for any resources that stand out with unusually high values.

2.2 Identifying Performance Bottlenecks

When using resmon, look for resources that consistently use more than 0.3ms per tick. These resources could be causing performance issues, especially during peak times. Depending on what the resource does, this could however be acceptable.

Example:
If you notice a resource like esx_jobs using excessive CPU, dive into its code and look for areas that can be optimized, such as reducing unnecessary loops or calls.

Tip: Use the stop and start commands to isolate and test the performance impact of specific resources:

stop esx_jobs
start esx_jobs

2.3 Advanced Profiling with profiler

For more in-depth profiling, use the profiler tool provided by FiveM. This tool can record detailed information about script execution.

Usage:

profiler record 30

This records 30 seconds of profiling data. After recording, use:

profiler view

Analyze the output to identify which scripts or functions are causing the most strain on the server.




3. Manage Resource Dependencies

Resource dependencies need to be carefully managed to prevent conflicts and ensure smooth loading.

3.1 Proper Dependency Declaration

When creating or using resources that depend on others, declare these dependencies clearly in the fxmanifest.lua file.

Example:

fx_version 'bodacious'
game 'gta5'

author 'Your Name'
description 'A resource that depends on others'
version '1.0.0'

-- Dependencies
dependencies {
    'mysql-async',
    'es_extended'
}

-- Resource files
client_scripts {
    'client/main.lua'
}

server_scripts {
    'server/main.lua'
}

This ensures that the mysql-async and es_extended resources are loaded before your resource, preventing errors and conflicts.

3.2 Handle Conditional Loading

In cases where resources might not always be available, you can conditionally load them to avoid crashes.

Example:

if GetResourceState('some_optional_resource') == 'started' then
    -- Safe to use the resource
    TriggerEvent('some_optional_resource:doSomething')
else
    -- Fallback if the resource isn’t available
    print("Optional resource not found, using default behavior.")
end

3.3 Streaming Optimization

If your server uses custom assets, ensure that they are optimized for streaming. Compress textures, use lower LODs, and reduce the size of models where possible.

Example of optimizing streaming files:

files {
    'stream/vehicle1.yft',
    'stream/vehicle1.ytd'
}

data_file 'DLC_ITYP_REQUEST' 'stream/vehicle1.ytyp'

Make sure to test these assets to confirm they don’t cause excessive load times or memory usage.




4. Server Configuration Tweaks

Proper server configuration is crucial for maximizing performance. Tweaking the server’s configuration settings can help you balance between performance, stability, and player experience.

4.1 Set Proper Thread Priorities

In FiveM, certain tasks can be prioritized by setting thread priorities. Critical resources can be given more CPU time, while less important tasks are deprioritized.

Example of adjusting thread priorities:
In the server.cfg, you can adjust thread priorities by using the setr command:

setr sv_priority1 "critical_resource"
setr sv_priority2 "secondary_resource"

This ensures that the critical_resource receives more processing power, while the secondary_resource is handled after the critical tasks are completed.

4.2 Adjust Tick Rates

The server’s tick rate determines how often it processes data and updates. A lower tick rate reduces CPU load but can affect gameplay smoothness. Conversely, a higher tick rate provides a more responsive experience but increases CPU usage.

Default tick rate setting:

set sv_minupdaterate 60
set sv_maxupdaterate 60

Adjusting tick rate for performance:
If your server is struggling with performance, consider reducing the tick rate:

set sv_minupdaterate 30
set sv_maxupdaterate 30

This reduces CPU usage at the cost of some gameplay responsiveness. Testing different rates will help you find the best balance for your server’s needs.

4.3 Network Configurations

Network settings directly impact how data is sent and received between the server and clients. Fine-tuning these settings can reduce latency and improve the overall gameplay experience.

Example of optimizing network settings:

set sv_maxclients 32       # Limits the number of players
set onesync_enabled true   # Enables OneSync for better synchronization
set sv_enforceGameBuild 2189  # Forces a specific game build for consistency
set sv_maxPacketSize 1200  # Adjusts the maximum packet size to reduce latency

These settings help balance the load on your server’s network, especially when dealing with a large number of players.




5. Database Optimization

Databases are a critical part of many FiveM servers, especially those with persistent data like player inventories, economies, and progression. Optimizing your database can lead to faster query times, reduced server load, and overall better performance.

5.1 Efficient Queries

Database queries should be optimized to reduce the time they take to execute. Avoid complex or unnecessary queries that scan large amounts of data, as they can slow down your server.

Inefficient query example:

MySQL.Async.fetchAll('SELECT * FROM users WHERE identifier = @identifier', {
    ['@identifier'] = playerIdentifier
}, function(result)
    -- Process result
end)

Optimized query with indexing:

-- Assuming 'identifier' is indexed
MySQL.Async.fetchAll('SELECT firstname, lastname FROM users WHERE identifier = @identifier LIMIT 1', {
    ['@identifier'] = playerIdentifier
}, function(result)
    -- Process result
end)

By selecting only the necessary columns and using LIMIT 1, the query becomes faster and more efficient.

5.2 Connection Pooling

Connection pooling helps manage database connections more effectively by reusing existing connections rather than creating a new one for each query.

Example configuration in server.cfg:

set mysql_connection_string "mysql://user:password@host/dbname?charset=utf8mb4&connection_limit=100"

This setting allows up to 100 simultaneous connections, reducing the overhead associated with constantly opening and closing connections.

5.3 Data Caching

Frequently accessed data, such as player stats or server settings, can be cached to reduce database queries.

Example of simple data caching in Lua:

local playerCache = {}

RegisterServerEvent('getPlayerData')
AddEventHandler('getPlayerData', function(playerId)
    if playerCache[playerId] then
        -- Return cached data
        TriggerClientEvent('sendPlayerData', playerId, playerCache[playerId])
    else
        -- Fetch data from database
        MySQL.Async.fetchAll('SELECT * FROM users WHERE identifier = @identifier', {
            ['@identifier'] = playerId
        }, function(result)
            playerCache[playerId] = result[1] -- Cache the result
            TriggerClientEvent('sendPlayerData', playerId, result[1])
        end)
    end
end)

This approach minimizes database calls by using the cache, improving performance, especially during peak times.




6. Monitor and Manage Player Impact

Managing how players interact with your server and the resources they use is vital for maintaining stability and performance, especially as your server population grows.

6.1 Player Slots

The number of player slots should be configured based on your server’s hardware capabilities. More players mean more strain on CPU, memory, and network bandwidth.

Adjusting player slots in server.cfg:

set sv_maxclients 64

If your server struggles with performance, consider reducing the number of slots until you can optimize or upgrade your hardware.

6.2 Anti-Cheat and Moderation

Exploits, cheats, or malicious behavior can cause performance issues. Implementing lightweight anti-cheat systems helps maintain server stability.

Example of basic anti-cheat implementation:

RegisterServerEvent('checkPlayerHealth')
AddEventHandler('checkPlayerHealth', function()
    local playerHealth = GetEntityHealth(source)
    if playerHealth > 200 then -- Arbitrary limit for health
        DropPlayer(source, "Cheating detected: Health exceeded limit.")
    end
end)

Regularly update your anti-cheat measures to address new exploits and vulnerabilities.

6.3 Managing Resource Load by Players

Players can sometimes cause resource overload by triggering heavy events or running certain scripts. You can implement safeguards to prevent this.

Example of rate-limiting player requests:

local requestCount = {}

RegisterServerEvent('heavyTask')
AddEventHandler('heavyTask', function()
    local playerId = source
    requestCount[playerId] = (requestCount[playerId] or 0) + 1

    if requestCount[playerId] > 5 then -- Limit to 5 requests per minute
        DropPlayer(playerId, "Request limit exceeded.")
    else
        -- Handle heavy task
        -- Reset count after 1 minute
        Citizen.SetTimeout(60000, function()
            requestCount[playerId] = 0
        end)
    end
end)

By managing and limiting heavy requests, you can prevent any single player from causing server-wide performance issues.

Remember to continuously iterate and test these configurations, as each server environment is unique and may require tailored adjustments.




7. Regular Maintenance and Updates

Regular maintenance and updates are essential to keep your server running smoothly. By staying on top of updates and performing routine checks, you can prevent issues before they impact your server’s performance.

7.1 Server Maintenance Schedule

Set up a regular maintenance schedule to apply updates, clean up resources, and check for issues. Consider scheduling maintenance during off-peak hours to minimize disruption.

Example of a Maintenance Checklist:

  • Weekly: Review and remove unused or outdated resources, apply minor updates, restart the server to clear memory leaks.
  • Monthly: Audit all running scripts for efficiency, check database performance, update any external dependencies (e.g., MySQL, Redis).
  • Quarterly: Perform a full backup of server files and databases, review server configuration settings, and update server hardware if needed.

7.2 Keeping Up with FiveM Updates

FiveM regularly releases updates that include performance improvements, bug fixes, and new features. Always keep your server updated to the latest stable version to benefit from these improvements.

Example of a simple update process:

  1. Backup your server files before applying any updates.
  2. Download the latest FiveM server binaries from the official website.
  3. Replace the old server binaries with the new ones.
  4. Test the server to ensure compatibility with your current resources.

7.3 Hardware Monitoring

Continuously monitor your server’s hardware usage (CPU, RAM, Disk I/O) to ensure it can handle the current load. If you notice consistent high usage, consider upgrading your server hardware or optimizing your configurations.

Example tools for monitoring:

  • htop (Linux): Provides a detailed view of CPU, memory, and process usage.
  • Task Manager (Windows): Offers a basic overview of system resource usage.
  • Prometheus + Grafana: A more advanced setup for real-time monitoring and alerting.



8. Community Feedback and Testing

Actively involving your community in the feedback and testing process can lead to better server performance and player satisfaction. Players often notice issues that may not be immediately apparent to administrators.

8.1 Gathering Player Feedback

Regularly solicit feedback from your players about their experience on the server. This can be done through surveys, forums, Discord channels, or in-game forms.

Example feedback questions:

  • Have you experienced any lag or performance issues?
  • Are there any specific scripts or features that seem to cause issues?
  • Do you notice any slowdowns during peak hours?

8.2 Beta Testing New Features

Before rolling out significant updates or new resources, conduct a beta test with a smaller group of players. This allows you to identify and fix performance issues before they affect your entire player base.

Example of setting up a beta server:

  1. Clone your main server’s configuration and resources.
  2. Set up a separate server instance with the cloned configuration.
  3. Invite a select group of players to test the new features.
  4. Gather feedback and monitor performance during the test.

8.3 Implementing Feedback

Once feedback is collected, prioritize issues based on their impact on performance and gameplay. Implement fixes or optimizations based on this feedback.

Example prioritization matrix:

Issue Impact Level Urgency
Resource causing occasional lag High High
Minor UI glitch Low Low
Feature request for new job system Medium Medium



9. Consider VPS or Dedicated Hosting

Your server’s hosting environment plays a crucial role in its overall performance. Choosing the right hosting option—whether VPS, dedicated, or cloud-based—can make a significant difference, especially as your server grows.

9.1 VPS vs. Dedicated Hosting

  • VPS (Virtual Private Server): A VPS is a virtual machine that shares physical hardware with other VPS instances. It’s a cost-effective option for smaller servers but may experience performance degradation during peak times due to shared resources.
  • Dedicated Server: A dedicated server provides physical hardware exclusively for your use, offering more consistent performance. This is ideal for larger communities or resource-intensive servers.

9.2 Cloud-Based Hosting

Cloud-based hosting (e.g., AWS, Google Cloud, Azure) offers flexibility and scalability, allowing you to dynamically adjust resources based on demand. However, it can be more complex and costly than traditional VPS or dedicated hosting.

9.3 Choosing the Right Hosting Provider

When choosing a hosting provider, consider the following:

  • Location: Choose a data center location that provides low latency for your target player base.
  • Hardware Specifications: Ensure the server has sufficient CPU, RAM, and SSD storage for your needs.
  • Scalability: Select a provider that allows you to easily upgrade resources as your server grows.

Example server specs for a medium-sized FiveM server:

  • CPU: 4 vCPUs (high-frequency)
  • RAM: 8 GB
  • Storage: 120 GB SSD
  • Network: 1 Gbps bandwidth

9.4 Geolocation and Latency

Geolocation plays a vital role in player experience. Hosting your server closer to your player base reduces ping and improves responsiveness.

Example of latency improvement:
If your player base is primarily in Europe, hosting in a European data center can reduce latency by 50-100 ms compared to a US-based server.


5 Likes

Thanks for the detailed guide.

Where did you find information on the server config vars like:

  • sv_priority1
  • sv_priority2
  • sv_minupdaterate
  • sv_maxupdaterate
  • sv_maxPacketSize

I can’t find anything on these anywhere and it looks like they are not defined nor have a default in CitizenFX. When I search I can’t find any references to them except this post and source engine changing tick rate, but this obviously isn’t CS Source.

I set these and they seemingly made no difference to server tick rate/frame speed/frames per second or packet MTU.

Curious if they actually have a tangible effect, are documented anywhere or are just vars being set with no effect. I searched through the docs and CitizenFX Github but found nothing on these. All I can find is this post indexed by google.

Cheers!

For the love of God, don’t use that guide.
If you really wanna known how to optimize your scripts, use that:
https://manason.github.io/effective-fivem-lua/

Welcome addition, however the guide above isn’t limited to Lua stuff - even I found things in this guide that I never cared to know about :laughing:

Seems to me like part of this information may come from an AI (ChatGPT probably)?

1.1. Optimizing threads by “upping” the Wait value is not always a good thing. There are many natives that need to run each frame (e.g. markers or vanilla input checks).
1.2. The “non optimized” example doesn’t make any sense.

2.1. Okay, makes sense.
2.2 is the same thing, just more detailed.
2.3. Yes, profiler is probably the best thing to use, but linking to the docs would probably help. The classic FiveM Server owner will not be able to interpret that data without a guide.

3.Dependencies don’t help with performance at all. They prevent resource starting errors, yes. But that’s it.
3.1. Multi dependencies are not covered (e.g. if a script is compatible with ESX and QB)
3.2. This remedies 3.1 and is a valid point.
3.3. That example makes no sense here. The tip above is fine though, however this doesn’t explain how to do it.

4.1. Never heard of that at all. setr can set arbitrary “replicated” values (which means the client gets them as well). I don’t know of any valid “default” values that can be overwritten using that.
4.2. Never heard of that either. And it uses just set, which is not replicated to the client. So it would be only a server setting. And the default server tick rate is 20 (50ms/tick), not 60. If this were a client setting, you would lose a whole lot of players setting that even below 100, let me tell you that.
4.3. Apart from max clients none of these offer better performance… and maxPacketSize is not a thing as far as I’m aware. There are 2 or 3 for state bags and maybe some for events, not exactly sure what their names are right now.

5.Most of these actually make sense.
5.3. Is something to be really careful about. Caching data can lead to a whole lot of work to ensure consistency between data in the database and in the cache. Especially when working with a lot of resources that might access that data.

6.1. Makes sense, but already mentioned in 4.3.
6.2. Makes sense, but doesn’t necessarily offer better performance. Might just be offloading from client to server in your example. Anticheats usually make performance worse unless implemented correctly.
6.3. this is actually worth depending on the use case, yes. I’ve used it myself when client button presses directly correlate to event usage.

(feel free to correct me on the above, I might be wrong here and there)

2 Likes

What in the ChatGPT is this, lol?

1 Like

OP request