Skip to content
LinuxHow-To Published Updated 8 min readViews unavailable

Linux zram: Configure Compressed Swap and Read Its Counters

Operate zram as a compressed block device by choosing algorithms, sizing it, integrating swap priority, and interpreting memory and I/O statistics.

zram creates a compressed block device whose data is stored in RAM. It is commonly used as swap, but it can also back selected temporary or cache workloads. It does not create additional physical memory: it trades CPU time and metadata for a workload-dependent reduction in memory pressure. Compression ratios vary with the data, the chosen algorithm, and the system’s workload, so a configured 4 GiB zram device is not a promise of 4 GiB of extra usable RAM.

Treat zram as one component of a memory policy. It can delay disk swapping or reduce pressure for compressible pages, but it cannot fix an unbounded leak, a poor cache policy, or a process that exceeds its cgroup limit. Measure compressed-pool usage, CPU cost, swap activity, latency, and out-of-memory events together. A system that reports a large zram capacity can still run out of memory if the compressed pages and their metadata consume the remaining RAM.

Understand the device lifecycle

A zram device presents a block interface. The kernel compresses data written to it and keeps compressed pages and bookkeeping in memory. When configured as swap, the virtual memory subsystem can move eligible pages to zram and read them back later. The original page contents remain recoverable, but the compression ratio depends on the page contents; encrypted or already compressed data often yields little reduction.

Device configuration is stateful. Select supported algorithms and options before initializing the device size. Once initialized, some attributes cannot be changed until the device is reset. If the device is serving swap or a mounted filesystem, stop its users first; resetting a live device can destroy data or fail with a busy error. A reset is not a maintenance-free way to tune a production system.

The kernel exposes per-device controls and statistics under /sys/block/zramN/. zramctl, provided by util-linux, offers a more convenient management interface, but its options depend on the installed util-linux version. Distribution tools may create and configure devices automatically through systemd units or other services. Inspect the host’s existing configuration before creating a second device or changing a setting that a service will reapply at boot.

Create a bounded swap device

The following uses zramctl to allocate a device, then initializes it as swap. Choose a size based on measured memory pressure and available headroom, not a generic multiplier of installed RAM.

sudo zramctl --find --size 2G
# Example output: /dev/zram0
sudo mkswap /dev/zram0
sudo swapon --priority 100 /dev/zram0
swapon --show
zramctl

The example assumes the kernel module and required privileges are available, the selected device is unused, and no distribution service already manages it. Check zramctl --help for the local util-linux syntax. Record the actual device path returned by --find rather than assuming it is always zram0. mkswap writes swap metadata to that device; swapon activates it with an explicit priority so its relationship to other swap areas is visible.

Swap priority changes selection among active swap areas; it does not change the zram compression ratio or guarantee that disk swap will never be used. Inspect all active areas and the host’s memory policy. A high-priority zram area can be used before a lower-priority disk area, while different systems may also configure multiple swap areas at the same priority. Validate the resulting behavior under representative pressure.

For lower-level configuration, inspect /sys/block/zram0/comp_algorithm for supported choices and the currently selected one. The kernel interface requires algorithm selection before the device is initialized. Write the desired disksize only after selecting options, then create a filesystem or swap signature as appropriate. Do not copy an algorithm name from another kernel without checking the target’s available list.

Select algorithms and size from evidence

Compression algorithms differ in compression ratio, CPU cost, memory use, and implementation availability. A faster algorithm can reduce compression latency but retain more data; a denser algorithm can use more CPU or produce unpredictable results across page types. Benchmark using the actual working set, not a synthetic stream of repeated zeroes. Include interactive latency and CPU contention in the test, since extra compression work can be noticeable on a constrained system.

The zram logical disk size is the maximum uncompressed block address space, not a preallocation of that many physical bytes. The memory consumed grows with stored data and includes metadata. A very large logical capacity can encourage the VM to retain more swapped pages than the system can safely compress. Set a realistic boundary and monitor the device’s memory statistics. If the goal is latency-sensitive service isolation, coordinate with cgroup memory limits and the process’s own cache behavior rather than treating zram as a substitute.

The mem_limit control can bound memory used by a device, subject to the semantics of the target kernel. Treat a configured limit as an operational guardrail, not an exact reservation; understand what happens when the bound is reached and whether the kernel can write back or reject additional compressed pages. Validate the behavior on the target release and observe allocation failures and swap-in latency.

Read statistics instead of relying on capacity labels

Use zramctl for a human-readable overview and inspect the documented sysfs counters when you need detailed evidence. The mm_stat and I/O statistics expose information about original data, compressed data, memory usage, and operations, but field names and presentation can vary across kernel releases. Read the matching kernel documentation before automating a parser; avoid hard-coding field positions without a version strategy.

Compare original data size with compressed data and total memory usage to understand the achieved ratio and metadata cost. Track reads, writes, failed I/O, and any writeback activity over time. These counters can explain why a zram device uses nearly as much memory as its logical capacity or why a workload incurs unexpected CPU cost. Capture the counters before and after a controlled workload so a static snapshot is not mistaken for a trend.

Correlate zram statistics with /proc/pressure/memory, cgroup memory events, swap-in/swap-out rates, CPU utilization, and application tail latency. A high compression ratio is not automatically a successful configuration if the compressor consumes a saturated CPU or causes user-visible stalls. Conversely, modest compression may still be useful when it prevents slower disk I/O for a latency-sensitive workload.

Treat writeback as a separate storage policy

Some kernels support zram writeback to a backing block device for selected pages. This extends the device’s behavior beyond keeping every stored page in compressed RAM, but it introduces real storage I/O, device failure modes, and additional latency. The backing device and writeback attributes must be configured using the kernel’s documented lifecycle and restrictions. Do not assume writeback is enabled just because a zram device is active.

If using writeback, monitor its counters and test readback after restart or device errors as the kernel documentation requires. Choose a backing device with an appropriate endurance and durability profile; the workload may write frequently. A zram swap device with a backing device is not identical to ordinary swap on that device, and writeback policy affects when data leaves the compressed pool. Keep the recovery plan clear before changing either device while memory pressure is high.

Do not confuse zram with zswap. Zram is a compressed block device, often configured as a swap area. Zswap is a compressed cache in front of a backing swap device. They have different interfaces, sizing behavior, and data paths; using both without a specific reason can add complexity and make memory accounting harder to interpret.

Change or remove a device safely

Before changing an initialized device’s algorithm or size, deactivate every user. For swap, inspect active areas and turn off only the intended device after confirming enough memory and alternative swap capacity exist. For a filesystem, unmount it cleanly. Then reset the zram device through the supported tool or interface, reconfigure it, initialize it again, and activate it. The reset operation discards the device contents.

sudo swapoff /dev/zram0
sudo zramctl --reset /dev/zram0

Do not run this blindly under memory pressure: swapoff needs to bring swapped pages back into memory and can fail or trigger an out-of-memory event if the host lacks headroom. Verify swapon --show before and after, retain a usable fallback swap area where appropriate, and check the device is no longer busy before resetting. If a distribution manager owns zram, change its configuration rather than leaving an unmanaged runtime state that will be recreated differently on the next boot.

Validate under realistic load

Test with the workload’s real page mix, memory limits, and concurrency. Include compressible and incompressible data, sustained memory pressure, CPU contention, swap-in bursts, and restart behavior. Observe p95 and p99 application latency as well as memory reclaimed. Ensure the host remains responsive enough to recover and that the OOM policy remains understood if zram reaches its configured boundary.

Use a bounded test and a rollback plan. Record kernel and util-linux versions, selected algorithm, logical size, memory limit, swap priority, backing-device settings, and before/after counters. Test the persistence mechanism used by the distribution, then confirm that only one manager owns the device. Avoid running unbounded stress tests on production systems simply to force a compression ratio.

Zram is most useful when its measured CPU and memory tradeoff matches the workload. Configure it before initialization, keep capacity and physical memory distinct, read its counters alongside pressure and latency, and reset it only after its users have been stopped safely.

Related:

Sources:

Comments