Skip to content

Gaming optimizations

Overall Garuda is very well optimized for day to day use and gaming. Out of the box it provides solid experience without hiccups. Yet, we can still squeeze more, be it related to performance or latency. Main focus of this wiki page is to improve on gaming performance & latency.

Following is covered:

  • CPU schedulers - LAVD
  • Ananicy rules & how to configure custom per app/game ones
  • Arch advised tuning for latency
  • Split-lock detection / mitigation

LAVD (Latency-criticality Aware Virtual Deadline) is a part of the sched_ext schedulers family. It was created by Changwoo Min (VALVE) for the SteamDeck.

It is initially motivated by gaming workloads. It aims to improve interactivity and reduce stuttering while playing games on Linux. Hence, this scheduler’s typical use case involves highly interactive applications, such as gaming, which requires high throughput and low tail latencies.

Use cases:

  • Gaming
  • Audio Production
  • Latency sensitive workloads
  • Desktop usage
  • Great interactivity under intensive workloads
  • Power saving

In order to have LAVD running we need:

  1. scx-scheds
  2. scx-tools
  3. scx_loader.toml (configuration file)

All the tools needed are available on the ChaoticAUR. To install them simply use pacman:

Terminal window
sudo pacman -Syu scx-scheds
sudo pacman -Syu scx-tools

After installing you should see them on your system:

Terminal window
pacman -Qs scx
local/scx-scheds 1.0.20-1
sched_ext schedulers and tools
local/scx-tools 1.0.20-1
scx_loader: A DBUS Interface for Managing sched_ext Schedulers

To configure LAVD as your CPU scheduler we need to create a config file and run systemctl daemon to have it persistent across reboots.

  1. Create a config file in /etc/scx_loader.toml

    Terminal window
    sudo nano /etc/scx_loader.toml
  2. Paste into the file following configuration

    /etc/scx_loader.toml
    default_sched = "scx_lavd"
    default_mode = "Auto"
    [scheds.scx_lavd]
    auto_mode = ["--performance"]

This will set LAVD as your scheduler, and make sure it’s running always in Gaming mode (Performance).

To turn on the scheduler and have it persistent across reboots we will run it as a daemon via systemctl service.

  1. Run the service

    Terminal window
    systemctl enable --now scx_loader.service
  2. Check if it’s running, you should see it active and in —performance mode

    Terminal window
    systemctl status --now scx_loader.service
    ● scx_loader.service - DBUS on-demand loader of sched-ext schedulers
    Loaded: loaded (/usr/lib/systemd/system/scx_loader.service; enabled; preset: disabled)
    Active: active (running) since Sun 2026-02-22 13:04:38 CET; 1h 40min ago
    Invocation: 4bd9d314ebff4b8b834f570a7ba014b8
    Main PID: 1037 (scx_loader)
    Tasks: 22 (limit: 37314)
    Memory: 86.2M (peak: 184.6M)
    CPU: 1.091s
    CGroup: /system.slice/scx_loader.service
    ├─1037 /usr/bin/scx_loader
    └─1166 scx_lavd --performance
    feb 22 13:04:38 GarudaMokka scx_loader[1166]: }
    feb 22 13:04:38 GarudaMokka scx_loader[1166]: 2026-02-22T12:04:38.637149Z INFO ThreadId(01) scx_lavd: scheds/rust/scx_lavd/src/main.rs:562: capacity bound: 1024 (6.7015705%)
    feb 22 13:04:38 GarudaMokka scx_loader[1166]: primary CPUs: [0]
    feb 22 13:04:38 GarudaMokka scx_loader[1166]: overflow CPUs: [8, 1, 9, 4, 12, 2, 10, 3, 11, 5, 13, 7, 15, 6, 14]
    feb 22 13:04:38 GarudaMokka scx_loader[1166]: 2026-02-22T12:04:38.637160Z INFO ThreadId(01) scx_lavd: scheds/rust/scx_lavd/src/main.rs:562: capacity bound: 15280 (100%)
    feb 22 13:04:38 GarudaMokka scx_loader[1166]: primary CPUs: [0]
    feb 22 13:04:38 GarudaMokka scx_loader[1166]: overflow CPUs: [1, 4, 2, 3, 5, 7, 6, 8, 9, 12, 10, 11, 13, 15, 14]
    feb 22 13:04:39 GarudaMokka scx_loader[1166]: 2026-02-22T12:04:39.608072Z WARN ThreadId(01) scx_utils::libbpf_logger: rust/scx_utils/src/libbpf_logger.rs:12: libbpf: map 'lavd_ops': BPF map skeleton link is uninitialized
    feb 22 13:04:39 GarudaMokka scx_loader[1166]: 2026-02-22T12:04:39.627448Z INFO ThreadId(01) scx_lavd: scheds/rust/scx_lavd/src/main.rs:1031: scx_lavd scheduler is initialized (build ID: 1.0.21-g7298f797 x86_64-unknown-linux-gnu)
    feb 22 13:04:39 GarudaMokka scx_loader[1166]: 2026-02-22T12:04:39.627456Z INFO ThreadId(01) scx_lavd: scheds/rust/scx_lavd/src/main.rs:1035: scx_lavd scheduler starts running.

If LAVD is running and working properly, you should be able to see its statistics. To do that simply run following command that will print outputs of the scheduler.

Terminal window
sudo scx_lavd --monitor 0.5
| MSEQ | # Q TASK | # ACT CPU | # SCHED | # PREEMPT | PERF-CR% | LAT-CR% | X-MIG% | # STLEE | BIG% | PC/BIG% | LC/BIG% | POWER MODE | PERFORMANCE% | BALANCED% | POWERSAVE% |
| 1 | 0 | 16 | 42076 | 34 | 100 | 55.4924 | 0 | 0 | 100 | 100 | 55.4924 | performance | 100 | 0 | 0 |
| 2 | 0 | 16 | 49867 | 42 | 100 | 55.9308 | 0 | 0 | 100 | 100 | 55.9308 | performance | 100 | 0 | 0 |
| 3 | 0 | 16 | 58632 | 49 | 100 | 56.3003 | 0 | 0 | 100 | 100 | 56.3003 | performance | 100 | 0 | 0 |
| 4 | 0 | 16 | 67319 | 55 | 100 | 56.3972 | 0 | 0 | 100 | 100 | 56.3972 | performance | 100 | 0 | 0 |
| 5 | 0 | 16 | 43131 | 38 | 100 | 56.4953 | 0 | 0 | 100 | 100 | 56.4953 | performance | 100 | 0 | 0 |
| 6 | 0 | 16 | 51891 | 46 | 100 | 56.4086 | 0 | 0 | 100 | 100 | 56.4086 | performance | 100 | 0 | 0 |

Ananicy is a daemon that automatically adjusts the nice levels of processes.

It consists of two components:

  • ananicy-cpp: daemon for adjusting the nice levels of processes
  • cachyos-ananicy-rules-git: list of rules used to assign specific nice values to specific processes

Ananicy is installed by default only on Dr460nized Gaming, through the performance-tweaks package. And the rule-set for games is being constantly updated. But in case we want to set a game that is not in the rule-set, or we want to set a custom process/game we can do it by creating a custom rule.

The rule-set for games can be found in /etc/ananicy.d/00-default/games/. Specifically for steam games can be found in the steam-native.rules rule-set.

Terminal window
grep portal /etc/ananicy.d/00-default/games/steam-native.rules
{ "name": "portal2_linux", "type": "Game" }

Usually if you do not find your game in already predefined rules, you can very simply create your own rule for a particular game.

To do that you need:

  1. Game process name (or names)
  2. Create a custom rule file

Examples of custom rules ~ Single spawned process

Section titled “Examples of custom rules ~ Single spawned process”

Helldivers 2 custom rule

  1. Create a custom rule with same name as your game attaching the .rules suffix

    Terminal window
    sudo nano /etc/ananicy.d/00-default/games/helldivers2.rules
  2. Set proper name (name for the process) and type (type is always Game)

    /etc/ananicy.d/00-default/games/helldivers2.rules
    # https://store.steampowered.com/app/553850/HELLDIVERS_2/
    { "name": "helldivers2.exe", "type": "Game" }

Examples of custom rules ~ Multiple spawned processes

Section titled “Examples of custom rules ~ Multiple spawned processes”

The Outer Worlds custom rule

  1. Create a custom rule with same name as your game attaching the .rules suffix

    Terminal window
    sudo nano /etc/ananicy.d/00-default/games/theouterworlds.rules
  2. Set proper name (name for the process) and type (type is always Game)

    /etc/ananicy.d/00-default/games/theouterworlds.rules
    # The Outer Worlds https://store.steampowered.com/app/578650
    { "name": "Indiana-Win64-Shipping.exe", "type": "Game"}
    { "name": "TheOuterWorlds.exe", "type": "Game"}

The Arch Wiki has some very nice tips how to improve latency in gaming.

The following kernel parameter changes improve the response time consistency for the realtime kernel as well as other kernels such as the default linux kernel:

  • Proactive compaction for (Transparent) Hugepage allocation reduces the average but not necessarily the maximum allocation stalls. Disable proactive compaction because it introduces jitter according to kernel documentation (inner workings):

    Terminal window
    echo 0 | sudo tee /proc/sys/vm/compaction_proactiveness
  • Reduce the watermark boost factor to defragment only one pageblock (2MB on 64-bit x86) in case of memory fragmentation. After a memory fragmentation event this helps to better keep the application data in the last level processor cache.

    Terminal window
    echo 1 | sudo tee /proc/sys/vm/watermark_boost_factor
  • If you have enough free RAM increase the number of minimum free Kilobytes to avoid stalls on memory allocations. Do not set this below 1024 KB or above 5% of your system’s memory. Reserving 1GB:

    Terminal window
    echo 1048576 | sudo tee /proc/sys/vm/min_free_kbytes
  • If you have enough free RAM increase the watermark scale factor to further reduce the likelihood of allocation stalls. Setting watermark distances to 5% of RAM:

    Terminal window
    echo 500 | sudo tee /proc/sys/vm/watermark_scale_factor
  • Avoid swapping (locking pages that introduces latency and uses disk IO) unless the system has no more free memory:

    Terminal window
    echo 10 | sudo tee /proc/sys/vm/swappiness
  • Enable Multi-Gen Least Recently Used (MGLRU) but reduce the likelihood of lock contention at a minor performance cost:

    Terminal window
    echo 5 | sudo tee /sys/kernel/mm/lru_gen/enabled
  • Disable zone reclaim (locking and moving memory pages that introduces latency spikes):

    Terminal window
    echo 0 | sudo tee /proc/sys/vm/zone_reclaim_mode
  • Disable Transparent Hugepages (THP) at a performance cost. Even if defragmentation is disabled, THPs might introduce latency spikes. The Arch Wiki sets all three values to never:

    Terminal window
    echo never | sudo tee /sys/kernel/mm/transparent_hugepage/enabled
    echo never | sudo tee /sys/kernel/mm/transparent_hugepage/shmem_enabled
    echo never | sudo tee /sys/kernel/mm/transparent_hugepage/defrag
  • Reduce the maximum page lock acquisition latency while retaining adequate throughput:

    Terminal window
    echo 1 | sudo tee /proc/sys/vm/page_lock_unfairness
  • Tweak the scheduler settings. The following scheduler settings are in conflict with cfs-zen-tweaks (AUR) so for each setting choose only one provider. By default the linux kernel scheduler is optimized for throughput and not latency. The following hand-made settings change that and are tested with different games to be a noticeable improvement. They might not be optimal for your use case. Consider modifying them as necessary:

    Terminal window
    echo 0 | sudo tee /proc/sys/kernel/sched_child_runs_first
    echo 1 | sudo tee /proc/sys/kernel/sched_autogroup_enabled
    echo 3000 | sudo tee /proc/sys/kernel/sched_cfs_bandwidth_slice_us
    echo 3000000 | sudo tee /sys/kernel/debug/sched/base_slice_ns
    echo 500000 | sudo tee /sys/kernel/debug/sched/migration_cost_ns
    echo 8 | sudo tee /sys/kernel/debug/sched/nr_migrate

By default running the above commands will not make them persistent. After a reboot all changes made will be back to their defaults. We can make these settings permanent by creating a systemd-tmpfiles file:

  1. Create the systemd-tmpfiles file

    Terminal window
    sudo nano /etc/tmpfiles.d/consistent-response-time-for-gaming.conf
  2. Paste in the settings

    /etc/tmpfiles.d/consistent-response-time-for-gaming.conf
    # Path Mode UID GID Age Argument
    w /proc/sys/vm/compaction_proactiveness - - - - 0
    w /proc/sys/vm/watermark_boost_factor - - - - 1
    w /proc/sys/vm/min_free_kbytes - - - - 1048576
    w /proc/sys/vm/watermark_scale_factor - - - - 500
    w /proc/sys/vm/swappiness - - - - 10
    w /sys/kernel/mm/lru_gen/enabled - - - - 5
    w /proc/sys/vm/zone_reclaim_mode - - - - 0
    w /sys/kernel/mm/transparent_hugepage/enabled - - - - never
    w /sys/kernel/mm/transparent_hugepage/shmem_enabled - - - - never
    w /sys/kernel/mm/transparent_hugepage/defrag - - - - never
    w /proc/sys/vm/page_lock_unfairness - - - - 1
    w /proc/sys/kernel/sched_child_runs_first - - - - 0
    w /proc/sys/kernel/sched_autogroup_enabled - - - - 1
    w /proc/sys/kernel/sched_cfs_bandwidth_slice_us - - - - 3000
    w /sys/kernel/debug/sched/base_slice_ns - - - - 3000000
    w /sys/kernel/debug/sched/migration_cost_ns - - - - 500000
    w /sys/kernel/debug/sched/nr_migrate - - - - 8
  3. After reboot of the system these settings will be applied

Split lock detection is a warning to aid developers, mitigation on the other hand is designed to hinder performance in order to encourage developers to write better code. This results in significantly reduced performance under a myriad of gaming scenarios, including Counter-Strike Source engine games and games using BattlEye anti-cheat.

Since kernel 6.2, a new sysctl tunable of split_lock_mitigate = 1 is available (by default) to enable mitigation, instead of the older split_lock_detect=on kernel parameter.

If an application is split_locking you should see a log similar to this in dmesg or journalctl

Terminal window
sudo journalctl -b --grep "split lock"
sudo dmesg | grep "split lock"
[ 1276.351787] x86/split lock detection: #AC: StreetFighter6./22891 took a split_lock trap at address: 0x15ea6d773
[ 1285.463221] x86/split lock detection: #AC: StreetFighter6./22912 took a split_lock trap at address: 0x15db26f7f
[ 1287.068898] x86/split lock detection: #AC: StreetFighter6./22901 took a split_lock trap at address: 0x159e355b3
[ 1288.242567] x86/split lock detection: #AC: StreetFighter6./22911 took a split_lock trap at address: 0x155d54d8b
[ 1298.766949] x86/split lock detection: #AC: StreetFighter6./22886 took a split_lock trap at address: 0x15d78b585

Upon setting:

Terminal window
echo "kernel.split_lock_mitigate = 0" | sudo tee /etc/sysctl.d/99-disable-splitlock.conf

The kernel will log Steam / Cef lock splitting, but without the sequential access penalty.

kernel.split_lock_mitigate

Is a setting in the Linux kernel that controls the mitigation for split-lock operations, which can negatively impact system performance. To check if it’s enabled or disabled: sudo sysctl -a | grep split

By default, it is enabled to slow down applications that misuse split locks, but it can be disabled by one of these options:

  • Setting it to 0 using the command sysctl -w kernel.split_lock_mitigate=0

  • Add kernel.split_lock_mitigate=0 to a drop-in file like /etc/sysctl.d/99-disable-splitlock.conf

    • ex: echo 'kernel.split_lock_mitigate=0' | sudo tee /etc/sysctl.d/99-disable-splitlock.conf
  • Add some sort of startup script or service to execute the following with elevated privileges: sysctl -w kernel.split_lock_mitigate=0

  • gamemode, user needs to be in the gamemode group

    • sudo usermod -aG gamemode $(whoami)
    • check if group is applied groups $(whoami)
    • log out & log in or newgrp gamemode
    • check if group is active on the current session id
    • ArchWiki Gamemode

Check if kernel.split_lock_mitigate is disabled

Terminal window
sudo sysctl -a | grep split
kernel.split_lock_mitigate = 0
split_lock_detect

Is a kernel parameter in Linux that enables detection of split locks, which occur when atomic operations access data across two cache lines. When enabled, it can help identify performance issues caused by these operations, but it may also lead to kernel panics or application terminations if split locks are detected. To check if it’s enabled or disabled: sudo dmesg | grep "split lock"

It gives the kernel the ability to respond to traps caused by split-lock operations and provides three modes for that response, selectable by the split_lock_detect= command-line parameter:

  • off causes the kernel to behave as it did before. Split-lock operations are not detected and nothing is done when they occur.
  • warn (the default) causes a (rate-limited) warning to go to the system log when a split-lock operation is detected.
  • fatal causes the kernel to immediately kill (with SIGBUS) any process attempting split-lock operations.

By default, it is enabled to slow down applications that misuse split locks, but it can be disabled by system-wide:

  • Adding split_lock_detect=off to your GRUB config (GarudaOS via Garuda-Toolbox to the Kernel parameters)
    • ex: quiet resume=UUID=8dd78827-8cbe-4c44-a410-a36c948cce40 loglevel=3 split_lock_detect=off, do not copy this add the parameter to your own expression

Check if split_lock_detect is disabled after reboot

Terminal window
sudo dmesg | grep "split lock"
[ 0.000000] x86/split lock detection: disabled

Sometimes using the CPU Scheduler can cause unwanted problems with audio such as cracking or static noise. If you are using a CPU scheduler, try to disable it if it will not fix the Audio issues.

In case you have SCX running properly, but do not see any benefit or you see error messages in the log

Failed to write file "/sys/devices/system/cpu/cpufreq/policy5/energy_performance_preference": Device or resource busy
Failed to write file "/sys/devices/system/cpu/cpufreq/policy3/energy_performance_preference": Device or resource busy
Failed to write file "/sys/devices/system/cpu/cpufreq/policy15/energy_performance_preference": Device or resource busy
Failed to write file "/sys/devices/system/cpu/cpufreq/policy1/energy_performance_preference": Device or resource busy
Failed to write file "/sys/devices/system/cpu/cpufreq/policy13/energy_performance_preference": Device or resource busy

This is caused by performance-tweaks rule energy_performance_preference.conf.

Terminal window
bat --style header,snip,changes /usr/lib/tmpfiles.d/energy_performance_preference.conf
File: /usr/lib/tmpfiles.d/energy_performance_preference.conf
w /sys/devices/system/cpu/cpufreq/policy*/energy_performance_preference - - - - performance

You have to mask /usr/lib/tmpfiles.d/energy_performance_preference.conf. Editing or removing the package file does not last, because a package update restores it.

Terminal window
sudo ln -s /dev/null /etc/tmpfiles.d/energy_performance_preference.conf

Otherwise it will interfere with the SCX.

It is not advised to run ananicy game rules together with gamemode. Both of these features adjust niceness, fight over it which can cause its either not working or it behaves odd.

1. Weird performance problems, lowered FPS

Section titled “1. Weird performance problems, lowered FPS”

If for any reason you see unwanted degradation in performance (FPS ~ average, 1% lows), try to disable some or all of the settings. Each of those settings have explanation and their potential impact. To disable a setting you can simply comment it out or remove the whole file and reboot your PC.

1. Weird performance problems, lowered FPS, system performance issues

Section titled “1. Weird performance problems, lowered FPS, system performance issues”

Disabling split lock mitigation system wide may have negative impact on overall system performance. It is therefore suggested to use sysctl to toggle the flag only when necessary.