Skip to main content

Swap, ZRAM and Memory Tuning on Low-RAM Linux Machines

Media Swap, ZRAM, and Memory Tuning on Low-RAM Machines

 

A Linux computer with limited memory can behave perfectly well—until it suddenly doesn’t.

Open a few more browser tabs.

Start an update.

Run a container.

Compile some software.

Then the system begins to:

lag badly

freeze

thrash the disk

kill applications

become almost impossible to control


On a machine with 2 GB, 4 GB or even 8 GB of RAM, the difference between an unpleasant system and a surprisingly usable one often comes down to how memory pressure is handled.

Three technologies matter most:

RAM
The fast physical memory applications actually use.

Swap
Storage used when Linux needs somewhere to place less-active memory pages.

ZRAM
Compressed memory stored inside RAM and exposed as a swap device.

None of these creates unlimited memory.

The objective is to help Linux cope gracefully with temporary memory pressure rather than immediately freezing or killing something important.

First: Prove Memory Is Actually the Problem

Do not start tuning kernel parameters because the machine “feels slow”.

Run:

free -h

You might see:

total        used        free      shared  buff/cache   available
Mem:            3.8Gi       2.7Gi       180Mi       240Mi       920Mi       680Mi
Swap:           2.0Gi       850Mi       1.2Gi

The important figure is usually:

available

not simply:

free

Linux deliberately uses otherwise idle RAM for filesystem cache.

A machine showing very little completely free RAM is therefore not automatically short of memory.

Look for evidence such as:

very low available memory

sustained swapping

application freezes

Out-Of-Memory kills

high memory pressure


Find the Processes Using the Memory

Start with:

ps aux --sort=-%mem | head -20

Or use:

top

or:

htop

if installed.

You may discover:

web browser consuming 2 GB

database with an oversized cache

runaway Java process

several containers

desktop environment using too much memory


That matters because:

kernel tuning cannot make an inappropriate workload small.

If Chrome is genuinely consuming nearly all the available RAM, changing vm.swappiness from 60 to 20 is not the fundamental solution.

Check Whether the System Is Actively Swapping

Run:

vmstat 1

Pay attention to:

si — swap in
so — swap out

Occasional activity is normal.

Constant significant swap-in and swap-out combined with a sluggish system suggests thrashing.

That means Linux is spending too much time moving pages between memory and storage instead of doing useful work.

Check Linux Memory Pressure

Modern Linux exposes Pressure Stall Information.

Run:

cat /proc/pressure/memory

This can show whether processes are genuinely being stalled while waiting for memory to become available.

That is often more useful than staring at a single RAM percentage.

The goal is not:

“never use swap.”

It is:

“avoid sustained memory pressure that makes useful work stop.”

What Is Swap?

Swap gives Linux somewhere to move less-active memory pages when physical RAM becomes constrained.

Check your current configuration:

swapon --show

and:

free -h

Swap can help with:

short memory spikes

inactive background applications

keeping the desktop responsive

avoiding immediate OOM failures

hibernation in appropriately configured systems


Swap is slower than RAM.

But:

slow memory can still be better than no memory at all.

Don't Disable Swap Just Because You Have an SSD

There is an old tuning myth that swap should always be disabled on SSD-based systems.

I would not recommend that.

A modest swap area can provide valuable breathing room during memory spikes.

Yes, swap writes contribute to SSD writes.

But a modern SSD is generally far preferable to:

application immediately killed because memory briefly ran out.

If the system is continuously writing gigabytes to swap all day, the underlying issue is not that swap exists.

It is that the machine does not have enough memory for its workload.

How Much Swap Do You Need?

There is no universal answer such as:

“swap must equal twice the RAM.”

The requirement depends on:

physical RAM

workload

hibernation

storage performance

zram use


For an ordinary small system, a few gigabytes of disk-backed swap may provide a useful emergency buffer.

For a machine that must hibernate, sizing becomes more complicated because the memory image must be stored appropriately.

Do not assume:

swap file exists = hibernation automatically works.

Resume configuration may also be required.

What Is ZRAM?

Zram creates a compressed block device inside physical memory.

Linux can use that block device as swap.

The kernel documentation describes zram as RAM-backed block devices whose contents are compressed before being stored, providing very fast I/O while saving memory through compression.

That initially sounds contradictory:

“My RAM is full, so I'm using more RAM?”

But compression changes the equation.

Suppose:

1 GB of inactive pages

compresses to:

450 MB

Moving those pages into zram can free approximately:

550 MB

for other work, minus overhead.

Linux has effectively traded:

CPU cycles

for:

additional effective memory capacity.

Why ZRAM Works Particularly Well on Small Machines

Zram is especially useful on:

older laptops

low-cost mini PCs

Raspberry Pi-type systems

thin clients

small VMs

slow eMMC storage

systems using mechanical disks


It avoids much of the latency associated with disk-based swap because compressed pages remain in memory.

The kernel documentation also warns implicitly against treating zram size as unlimited capacity: compression ratios vary, and poorly compressible data still consumes substantial real RAM.

An Easy Way to Configure ZRAM

On systems using systemd-zram-generator, configuration can be very simple.

For example:

[zram0]
zram-size = ram / 2

in:

/etc/systemd/zram-generator.conf

The generator creates and configures the zram device during boot. Its current default behaviour, when enabled without an explicit size, is approximately:

min(ram / 2, 4096 MB)

according to the project documentation.

After configuration, check:

zramctl

and:

swapon --show

Distribution packaging differs, so use the package and configuration method recommended by your Linux distribution rather than copying an arbitrary startup script from an old forum post.

How Big Should ZRAM Be?

For a small desktop, half of physical RAM is a reasonable conservative starting point.

For example:

4 GB RAM → roughly 2 GB zram

Then monitor it.

But don't obsess over a single ratio.

The kernel documentation notes there is generally little value in sizing a zram device beyond roughly twice physical memory because zram still depends on real compression rather than magically creating capacity.

The right size depends on:

compressibility of workload

CPU performance

disk swap availability

memory pressure


Measure rather than blindly maximising it.

Check Whether ZRAM Is Actually Helping

Run:

zramctl

You may see fields showing:

logical data size

compressed size

memory actually consumed


That lets you assess whether compression is worthwhile.

For example:

DATA  1.8G
COMPR 650M
TOTAL 700M

is useful.

Approximately 1.8 GB of logical memory is occupying roughly 700 MB of real RAM.

If the data barely compresses, the benefit will naturally be smaller.

ZRAM Plus Disk Swap Can Work Very Well

You do not necessarily have to choose one or the other.

A sensible low-memory configuration can be:

high-priority zram

then:

lower-priority disk swap

The system first uses compressed RAM because it is fast.

If pressure becomes extreme, disk-backed swap remains available as another safety layer.

Check priorities:

swapon --show

You might see:

NAME        TYPE  SIZE  USED  PRIO
/dev/zram0  disk    2G  700M   100
/swapfile   file    4G    0B    10

That is a perfectly reasonable layered design.

What Is Zswap?

Zswap is related to zram but works differently.

The Linux kernel describes zswap as a compressed cache for swap pages.

Instead of being the swap device itself:

1. Linux decides a page should be swapped out.


2. zswap attempts to compress it into RAM.


3. If the compressed pool becomes full, pages can ultimately be evicted to the normal backing swap device.

 

So:

ZRAM

Compressed RAM is the swap device.

Zswap

Compressed RAM sits in front of real swap as a cache.

For a simple low-RAM desktop, zram is often conceptually easier.

If the distribution already has zswap configured appropriately, however, there is no need to replace it merely because zram is fashionable.

I would not combine:

zram + zswap + several swapfiles

without a clear reason.

More layers can make performance harder to understand.

What Is Swappiness?

Check:

sysctl vm.swappiness

Many Linux systems use:

vm.swappiness = 60

Swappiness influences how Linux balances reclaiming filesystem cache against moving anonymous application memory into swap.

It is not:

percentage of RAM used before swapping

percentage of RAM Linux wants in swap


The current kernel documentation defines the valid range as 0–200, with 100 broadly representing equal I/O cost between swap and filesystem paging.

Why Values Above 100 Can Make Sense With ZRAM

This is one area where older Linux advice is often outdated.

For slow disk-based swap, people frequently recommend:

10

or:

20

With compressed in-memory swap such as zram or zswap, the economics change.

The Linux kernel explicitly says values above 100 can be appropriate for in-memory swap because swap I/O may be cheaper than reclaiming filesystem-backed pages.

So a zram-focused system might sensibly test:

sudo sysctl vm.swappiness=100

or even somewhat higher.

Do not interpret that as:

“150 is the best zram value.”

The kernel itself states that the optimum is workload-dependent.

Change One Setting at a Time

To test temporarily:

sudo sysctl vm.swappiness=100

Check:

sysctl vm.swappiness

Then use the machine normally.

If the result is genuinely better, make it permanent with a file such as:

/etc/sysctl.d/99-memory-tuning.conf

containing:

vm.swappiness = 100

Apply:

sudo sysctl --system

Do not change six VM parameters simultaneously.

Otherwise you will have no idea which one helped—or caused a regression.

Don't Randomly Tune vm.vfs_cache_pressure

You'll often see guides recommending arbitrary changes to:

vm.vfs_cache_pressure

This controls how aggressively Linux reclaims filesystem inode and directory-entry cache.

The default is commonly:

100

Changing it can be useful in very specific workloads.

But I would leave it alone on most low-memory desktops until there is evidence it is part of the problem.

The same goes for random changes to:

dirty_ratio

dirty_background_ratio

overcommit settings


Kernel tuning should solve a measured problem.

Not create a collection of “performance tweaks”.

Used Swap Is Not Automatically Bad

Suppose:

free -h

shows:

Swap: 2.0G  600M  1.4G

even though the system currently has available RAM.

That is not necessarily a problem.

Linux may leave inactive pages in swap because pulling them back into RAM offers no immediate benefit.

That allows physical memory to be used for more useful purposes.

Look at:

current pressure and swap activity

rather than insisting:

Swap Used must always equal zero.

Don't Clear Swap Just to Make the Number Pretty

You may see advice to run:

sudo swapoff -a
sudo swapon -a

This forces swapped pages back towards RAM.

On a low-memory machine, that can create a sudden memory spike and even trigger the OOM killer.

Do it only when you understand why.

A non-zero swap-used figure is not a fault requiring cleanup.

What Is the OOM Killer?

If Linux genuinely cannot satisfy memory demands, the kernel may terminate one or more processes.

You can search for evidence:

sudo journalctl -k | grep -iE "oom|out of memory|killed process"

If the same application repeatedly gets killed, ask why.

Possible answers:

insufficient RAM

memory leak

badly sized database

unconstrained container

runaway browser workload


Adding another kernel tweak may merely postpone the inevitable.

systemd-oomd and Early OOM Handling

Some systems use mechanisms such as:

systemd-oomd

earlyoom


to react to severe memory pressure earlier than the kernel's final OOM response.

That can help keep a desktop responsive because killing one excessive process early may be preferable to allowing the entire machine to freeze.

But these tools need appropriate policy.

You do not want the wrong important workload selected simply because a generic internet configuration said to enable aggressive OOM handling.

Containers Need Memory Limits Too

A Docker or Podman workload can consume enough memory to make the host unusable.

Do not expect zram to protect you indefinitely from an unconstrained application.

Where appropriate, configure:

container memory limits

service limits

application cache limits


Sometimes the best memory tuning is simply:

stop one application from taking all the memory.

A Practical 4 GB Linux Setup

For an ordinary 4 GB lightweight desktop, I would begin with something conceptually like:

RAM: 4 GB

ZRAM: around 2 GB initially

Disk swap: perhaps 2–4 GB as emergency overflow

Swappiness: start with the distribution default, then test around 100 if zram is the primary swap tier

Then monitor:

free -h
swapon --show
zramctl
vmstat 1
cat /proc/pressure/memory

If that creates a smooth experience during normal workloads, stop tuning.

You have achieved the objective.

A 2 GB Machine Needs Realistic Expectations

A 2 GB Linux computer may still be useful for:

lightweight desktop

terminal

small server workloads

modest browsing


But modern browsers can consume most of that memory by themselves.

Zram can help substantially.

It cannot make:

2 GB behave like 16 GB.

On hardware this constrained, the biggest gains may come from:

lighter desktop environment

fewer browser tabs

fewer startup services

lighter applications


rather than another obscure kernel setting.

The Safe Low-RAM Tuning Process

Use this order:

1. Check memory:

 

free -h

2. Check swap:

 

swapon --show

3. Identify large processes:

 

ps aux --sort=-%mem | head -20

4. Observe swap activity:

 

vmstat 1

5. Check actual memory pressure:

 

cat /proc/pressure/memory

6. Check whether zram already exists:

 

zramctl

7. Remove unnecessary memory demand.


8. Make sure sensible swap exists.


9. Add zram conservatively if appropriate.


10. Test swappiness rather than assuming a value.


11. Monitor over several normal work sessions.


12. Make only proven settings permanent.


13. Upgrade RAM or reduce the workload when persistent pressure remains.

 

The key principle is:

Measure pressure first. Add resilience second. Tune last.

How Hamilton Group Can Help

Hamilton Group can help businesses diagnose Linux systems that:

freeze under load

run out of RAM

repeatedly trigger OOM events

swap heavily

become unusably slow


We can assist with:

Linux memory diagnostics

swap

zram

zswap

systemd-zram-generator

container memory limits

service optimisation

server performance

hardware upgrade planning


The objective is not to accumulate as many memory tweaks as possible.

It is to keep the machine responsive, predictable and stable under its real workload.

If the system spends most of every working day under severe memory pressure, however, the correct long-term recommendation may simply be:

install more RAM or move the workload to more appropriate hardware.

Visit hgmssp.com or call 0330 043 0069.