# veilor-os โ€” memory-pressure tuning for zram-only swap # # Rationale: veilor-os ships zram swap with NO disk swap (see THREAT-MODEL.md # ยง"Lost or stolen laptop"). The kernel's default vm.* knobs assume a slow # spinning disk and refuse to swap until physical RAM is nearly exhausted. # Under a zram-only stack that policy is wrong on two axes: # # 1. zram is RAM-fast โ€” there is no penalty for swapping early, only a # small CPU cost for zstd compress/decompress. # 2. Once zram fills, there is no overflow (no disk swap by design), so # the kernel falls through to OOM. With default knobs the OOM trigger # is slow and reactive: by the time it fires, the system has spent # minutes in thrash (compositor/input frozen, mouse stuck) and the # kernel picks a victim by oom_score which is often plasmashell or # the terminal โ€” i.e. the user's session goes down, not the runaway. # # What these knobs do: # # vm.swappiness = 180 # Tell the kernel to prefer evicting anonymous pages to (zram) swap # over reclaiming file-backed pages. Fedora's zram-generator upstream # recommends 180 for zram-only systems. Default 60 is tuned for HDD # swap and leaves zram unused until too late. # # vm.watermark_scale_factor = 125 # Start kswapd reclaim earlier (~1.25% of RAM headroom vs default # 0.1%). On a 32 GiB box that's ~400 MiB head start before allocations # would otherwise stall in direct-reclaim. Trades a tiny amount of # usable RAM for much smoother latency under bursty allocators # (Chromium/Electron tab spawns, language server warm-up). # # vm.page-cluster = 0 # Read one page per swap-in instead of the default 8. Read-ahead is a # win on rotational media because seeks dominate; on zram the seek # cost is zero and grabbing 7 extra pages just wastes decompress # cycles and CPU cache. Setting to 0 is the documented zram tuning. # # Companion: systemd-oomd is enabled in the same change so PSI-based # pre-OOM kills land on the right cgroup before the kernel OOM reaper # fires. Without it, even with these knobs the system can still wedge # briefly while the kernel waits for the global watermark. vm.swappiness = 180 vm.watermark_scale_factor = 125 vm.page-cluster = 0