22
33Smart dynamic swap management for Linux, written in Rust.
44
5- ## Overview
5+ Automatically detects hardware, selects the best swap strategy, and tunes the
6+ kernel for optimal memory management — no manual configuration required.
67
7- ` systemd-swap ` automatically configures the best swap strategy for your system:
8+ ## How It Works
89
9- - ** Auto-detection** : Smartly chooses between Zswap and Zram based on your filesystem.
10- - ** Zswap + SwapFC** : (Default for Btrfs/Ext4/XFS) Uses compressed RAM cache + dynamic swap files. Most efficient for desktops.
11- - ** Zram** : (Default for others) Uses compressed RAM block device. Good for systems without disk swap support.
12- - ** Dynamic Scaling** : Creates swap files on-demand, starting small and growing as needed.
10+ ### Swap Modes
11+
12+ | Mode | Primary | Secondary | Selection |
13+ | ------| ---------| -----------| -----------|
14+ | ` auto ` | Auto-detected | Auto-detected | ** Default** — recommended |
15+ | ` zram+swapfile ` | Zram (RAM) | Swap files (disk) | btrfs / ext4 / xfs with free space |
16+ | ` zswap+swapfile ` | Zswap (kernel) | Swap files (disk) | Large disk, SSD/NVMe |
17+ | ` zram ` | Zram (RAM) | None | LiveCD, low disk, tmpfs |
18+ | ` manual ` | Explicit flags | Explicit flags | Advanced users |
19+ | ` disabled ` | — | — | Service exits cleanly |
20+
21+ ### Auto-Detection Logic
22+
23+ In ` auto ` mode, the daemon checks:
24+
25+ 1 . ** LiveCD?** (tmpfs/squashfs/overlay root) → ` zram ` only
26+ 2 . ** Filesystem supports swap files?** (btrfs/ext4/xfs) → if no, ` zram ` only
27+ 3 . ** Free disk ≥ RAM?** → if no, ` zram ` only
28+ 4 . ** Otherwise** → ` zram+swapfile ` (zram primary + disk overflow)
29+
30+ ### Zram Pool Architecture
31+
32+ The daemon manages a ** dynamic pool of zram devices** that expands and
33+ contracts based on demand:
34+
35+ - ** Initial pool** : one device per CPU core (max 8 devices)
36+ - ** Expansion** : adds a device when pool utilization exceeds 85%
37+ - ** Contraction** : removes idle devices when utilization drops below 20% for 120s
38+ - ** Monitoring interval** : 5 seconds
39+
40+ Each zram device uses:
41+ - ** Algorithm** : zstd (level 3) — best ratio-to-speed balance
42+ - ** Disksize** : 150% of RAM (virtual/uncompressed size)
43+ - ** No mem_limit** : prevents write errors that block kernel fallback to disk swap
44+ - ** Priority** : 32767 (maximum — kernel uses zram before disk swap)
45+
46+ Physical RAM usage is naturally limited by the kernel's memory watermarks
47+ and the daemon's free-RAM guard (adaptive check before each expansion).
48+
49+ ** Compression ratios** (typical):
50+ - Desktop workloads: 3–4x
51+ - Server / text-heavy: 5–10x
52+ - Incompressible data (media, encrypted): ~ 1x
53+
54+ ### Swap Files (Overflow)
55+
56+ In ` zram+swapfile ` mode, swap files provide emergency overflow:
57+
58+ - ** Size** : 512MB each, created on demand
59+ - ** Maximum** : 28 files (14GB total capacity)
60+ - ** Priority** : -1 (kernel only uses when zram is full)
61+ - ** NOCOW** : enabled on btrfs (prevents deadlock under pressure)
62+ - ** Created when** : free RAM < 20% or free swap < 40%
63+ - ** Removed when** : free swap > 70%
64+
65+ ### Zswap Mode
66+
67+ In ` zswap+swapfile ` mode, the kernel's zswap handles compression:
68+
69+ - Compresses pages before writing to disk swap
70+ - Shrinker moves cold compressed pages to disk automatically
71+ - Pool limited to 45% of RAM
72+ - Requires disk-backed swap files as backing storage
73+
74+ ## Recommended Kernel Tuning
75+
76+ The following kernel parameters are ** not applied by the daemon** — they are
77+ recommendations for optimal performance with zram/zswap. Configure them
78+ via ` /etc/sysctl.d/99-swap.conf ` or your distribution's tuning service.
79+
80+ ### Memory Management
81+
82+ | Parameter | Value | Purpose |
83+ | -----------| -------| ---------|
84+ | ` vm.swappiness ` | 120 (zram+swapfile) / 180 (zram only) | Prefer swap over file cache (zram is in-memory, so swapping is fast) |
85+ | ` vm.min_free_kbytes ` | 3% of RAM (max 512MB) | Emergency reserve — gives kswapd headroom before OOM |
86+ | ` vm.watermark_scale_factor ` | 150 (1.5%) | Gap between min/low/high watermarks for kswapd headroom |
87+ | ` vm.vfs_cache_pressure ` | 75 | Balance between VFS cache retention and anonymous page reclaim |
88+ | ` vm.dirty_ratio ` | 10 | Max dirty pages before blocking writes (reduces memory pressure) |
89+ | ` vm.dirty_background_ratio ` | 3 | Start background writeback early |
90+ | ` vm.page-cluster ` | 0 (zram) / 2 (zswap) | Pages read per swap-in. 0 = page-at-a-time (optimal for zram) |
91+
92+ ### Memory Compaction
93+
94+ | Parameter | Value | Purpose |
95+ | -----------| -------| ---------|
96+ | ` vm.compaction_proactiveness ` | 20 | Background defragmentation level. Lower avoids CPU waste with zram-heavy workloads |
97+ | ` vm.watermark_boost_factor ` | 15000 | Boosts watermarks after fragmentation events for compaction recovery |
98+ | ` vm.extfrag_threshold ` | 300 | Eagerness to compact vs reclaim. Lower = more willing to compact |
99+
100+ ### Transparent Huge Pages
101+
102+ | Parameter | Value | Purpose |
103+ | -----------| -------| ---------|
104+ | THP enabled | ` madvise ` | Only apps requesting huge pages get them — avoids compaction stalls |
105+ | mTHP 64kB | ` madvise ` | 64kB folios via madvise — reduces swap I/O overhead |
106+
107+ ### MGLRU (Multi-Gen LRU)
108+
109+ | Parameter | Value | Purpose |
110+ | -----------| -------| ---------|
111+ | ` min_ttl_ms ` | 1000 | Pages younger than 1s are never reclaimed — protects working set from thrashing |
13112
14113## Installation
15114
16- ### Arch Linux / BigLinux / Manjaro...
115+ ### Arch Linux / BigLinux / Manjaro
116+
17117``` bash
18118cd pkgbuild
19119makepkg -si
20120```
21121
22122### Manual Build
23- Requirements: Rust 1.70+, ` btrfs-progs ` , ` util-linux `
123+
124+ Requirements: Rust 1.70+, ` util-linux `
24125
25126``` bash
26127cargo build --release
@@ -30,46 +131,126 @@ sudo systemctl enable --now systemd-swap
30131
31132## Usage
32133
33- Check status:
134+ ### Check Status
135+
34136``` bash
35137systemd-swap status
36138```
37139
38- Reload configuration:
140+ Shows zram pool stats (compression ratio, utilization, device count),
141+ swap file details, and memory breakdown.
142+
143+ ### Show Recommended Config
144+
145+ ``` bash
146+ sudo systemd-swap autoconfig
147+ ```
148+
149+ Displays the auto-detected configuration for the current hardware.
150+
151+ ### Restart
152+
39153``` bash
40154sudo systemctl restart systemd-swap
41155```
42156
157+ ### View Logs
158+
159+ ``` bash
160+ journalctl -u systemd-swap -f
161+ ```
162+
43163## Configuration
44164
45- Configuration is located at ` /etc/systemd/swap.conf ` .
165+ Configuration files (in order of priority):
166+
167+ 1 . ` /usr/share/systemd-swap/swap-default.conf ` — defaults (do not edit)
168+ 2 . ` /etc/systemd/swap.conf ` — user overrides
169+ 3 . ` /etc/systemd/swap.conf.d/*.conf ` — drop-in fragments
170+
171+ All options support ` ${NCPU} ` and ` ${RAM_SIZE} ` variables, plus simple
172+ arithmetic with ` $(( expr )) ` .
46173
47174### Common Options
48175
49- ** Change Swap Mode:**
176+ ** Change swap mode:**
177+ ``` ini
178+ swap_mode =zram+swapfile # or: auto, zram, zswap+swapfile, manual, disabled
179+ ```
180+
181+ ** Customize zram size:**
50182``` ini
51- # Modes: auto, zswap+swapfc, zram, manuall
52- swap_mode =auto
183+ zram_size =200% # Virtual disksize (% of RAM)
53184```
54185
55- ** Customize Zram Size :**
186+ ** Customize swap file location :**
56187``` ini
57- zram_size =50%
188+ swapfile_path =/mnt/data/swapfile
58189```
59190
60- ** Customize Swap File Location :**
191+ ** Adjust anti-thrashing protection :**
61192``` ini
62- swapfc_path =/mnt/data/swapfile
193+ mglru_min_ttl_ms =3000 # Higher = more protection, less reclaim
63194```
64195
65- See ` /usr/share/systemd-swap/swap-default.conf ` for all available options and defaults.
196+ ** Customize zram pool behavior:**
197+ ``` ini
198+ zram_expand_threshold =90 # Expand pool above this utilization %
199+ zram_contract_threshold =15 # Contract pool below this utilization %
200+ ```
201+
202+ ### Full Option Reference
203+
204+ See ` /usr/share/systemd-swap/swap-default.conf ` for all available options
205+ with descriptions.
206+
207+ ## Architecture
208+
209+ ```
210+ systemd-swap (Rust daemon)
211+ ├── main.rs — CLI (clap), mode dispatch, kernel tuning, THP/MGLRU
212+ ├── lib.rs — Module declarations, global SHUTDOWN flag
213+ ├── config.rs — Config parser (key=value, ${VAR} expansion, arithmetic)
214+ ├── autoconfig.rs — Hardware detection, recommended config generation
215+ ├── zram.rs — Dynamic zram pool (expansion, contraction, monitoring)
216+ ├── swapfile.rs — Dynamic swap file management (NOCOW, loop-backed)
217+ ├── zswap.rs — Zswap kernel module configuration
218+ ├── meminfo.rs — /proc/meminfo parser, effective swap calculation
219+ ├── systemd.rs — Systemd unit generation, sd-notify
220+ └── helpers.rs — Shared utilities (parse_size, fs detection, logging)
221+ ```
222+
223+ ### Data Flow
224+
225+ ```
226+ Memory pressure (free RAM < threshold)
227+ → MGLRU protects working set (pages < 1s old)
228+ → Kernel swaps cold anonymous pages:
229+ ├─ zram: compress with zstd level 3 → store in RAM
230+ │ ├─ Pool utilization > 85% → daemon adds zram device
231+ │ └─ All disksize consumed → kernel falls back to swapfiles
232+ └─ zswap: compress in kernel pool → shrinker writes back to disk
233+
234+ SwapFile monitor (1s interval):
235+ ├─ free_ram < 20% → create 512MB swap file
236+ ├─ free_ram < 5% → emergency: create immediately
237+ └─ free_swap > 70% → remove unused swap file
238+
239+ ZramPool monitor (5s interval):
240+ ├─ utilization > 85% → add zram device (up to 8)
241+ └─ utilization < 20% (120s stable) → remove idle device
242+ ```
66243
67244## Features
68245
69- - ** Zero Configuration** : Works out of the box for most systems.
70- - ** Sparse Files** : Swap files use zero disk space until data is actually written (when using Zswap).
71- - ** MGLRU Support** : Integrates with Multi-Gen LRU (Kernel 6.1+) to prevent thrashing.
72- - ** Zram Writeback** : Can offload cold pages from Zram to disk.
246+ - ** Zero configuration** : works out of the box for any system
247+ - ** Dynamic scaling** : creates/removes swap resources on demand
248+ - ** MGLRU integration** : protects working set from premature eviction (kernel 6.1+)
249+ - ** mTHP support** : 64kB folios for efficient zram swap I/O
250+ - ** Zswap disabled for zram** : prevents double compression per kernel docs
251+ - ** NOCOW swap files** : safe on btrfs under memory pressure
252+ - ** Adopt on restart** : reuses existing zram devices and swap files without swapoff
253+ - ** Graceful shutdown** : restores all kernel parameters on stop
73254
74255## License
75256
0 commit comments