Linux

10 Lightweight Linux Distros for IoT and Old Hardware, Tested

OpenWrt sat at 78 MB of RAM with nothing to do. Fedora IoT needed 324 MB to do the same nothing, and Talos was holding 907 MB before it ran a single workload. Every one of them is sold as a lightweight Linux distro, which tells you how little the label means until you know what the box is for: a router, a sensor gateway, a container host, or a laptop that shipped with Windows Vista.

Original content from computingforgeeks.com - post 172266

So we put ten of them on the same Proxmox host and measured them the same way. Seven target IoT, edge and headless work (OpenWrt, Alpine Linux, DietPi, Ubuntu Core, Fedora IoT, Flatcar Container Linux and Talos Linux), and three target old hardware with a desktop (Tiny Core Linux, antiX and SliTaz). Each distro got three cold boots, an idle memory reading, a disk measurement and a step-down test that kept shrinking the RAM until the system stopped booting. The numbers below come from those VMs, and every failure has a screenshot.

Benchmark results at a glance

“Ready” means the service a real user would reach first: SSH for the headless systems, the LuCI web UI for OpenWrt, the Talos API and the Kubernetes API for Talos, the first-boot setup prompt for Ubuntu Core, and a settled desktop for the three live systems. Boot times are the median of three cold boots. The last column is the smallest memory size that still booted and stayed up, stepping down from 512 MB through 256, 128 and 64 MB. Ubuntu Core failed at 512 MB, so we tried 768 MB, and Talos stepped down from its 2 GB starting point in 512 MB increments.

DistroBuilt forBoot to readyIdle RAM usedDisk usedLowest RAM that booted
OpenWrtRouters, gateways18.3 s (SSH and LuCI)78 MB29 MB128 MB
Alpine LinuxSmall servers, gateways, containers9.6 s162 MB99 MB128 MB
DietPiHome servers on SBCs and old PCs9.8 s217 MB1,031 MB256 MB
Ubuntu CoreSigned, fleet-managed devices40.2 s (setup prompt)134 MB (before setup)1,896 MB768 MB (512 MB failed in firmware)
Fedora IoTAtomic edge boxes18.5 s324 MB1,642 MB512 MB
Flatcar Container LinuxContainer hosts20.5 s304 MB817 MB256 MB
Talos LinuxKubernetes nodes11.5 s API, 49.1 s Kubernetes907 MB (2 GB VM)982 MB1.5 GB (1 GB failed)
Tiny Core LinuxVery old PCs, kiosks12.4 s to desktop175 MBRuns from RAM (42 MB ISO)128 MB
antiXOld laptops that need a full desktop27.4 s to desktop310 MBRuns live (2.3 GB ISO)256 MB
SliTazOld PCs, rescue sticks31.4 s to desktop275 MBRuns from RAM (59 MB ISO)256 MB (128 MB boots to console only)

Two things jump out. Among the headless systems, OpenWrt and Alpine are in a different weight class, both surviving on 128 MB with under 100 MB of disk. And the image-based, update-safe systems (Ubuntu Core, Fedora IoT, Flatcar, Talos) use several times the disk of OpenWrt or Alpine, and all of them except Ubuntu Core use more RAM too. That is a fair trade on a fleet and a bad one on a 256 MB board. Talos is not directly comparable with the rest, because its 907 MB includes a running single-node Kubernetes control plane.

How we tested

All ten ran as KVM guests on one Proxmox VE node with an Intel Core i7-6700 and a ZFS pool. Every VM got 1 vCPU (CPU type host), 1024 MB of RAM, an 8 GB virtio disk and a virtio NIC on the same bridge. Talos got its documented control-plane minimum instead (2 vCPU, 2 GB, 10 GB disk), and Flatcar kept its 12.3 GB disk because its image refuses to shrink. Ubuntu Core and Fedora IoT ran on UEFI (OVMF, q35), since their images do not boot on SeaBIOS.

These are the images we downloaded and booted, with their sizes on disk:

66M alpine-virt-3.24.2-x86_64.iso
2.3G antiX-26.1_x64-full.iso
265M DietPi_Proxmox-x86_64-Trixie.qcow2.xz
926M Fedora-IoT-raw-44-20260427.0.x86_64.raw.xz
570M flatcar_production_qemu_image.img
348M metal-amd64.iso
13M openwrt-25.12.5-x86-64-generic-ext4-combined.img.gz
59M slitaz-rolling.iso
42M TinyCorePure64-17.1.iso
503M ubuntu-core-26-amd64.img.xz

Boot time is the number of seconds from qm start until the target TCP port accepted a connection (or, for Ubuntu Core, until “Press enter to configure” appeared on the serial console). For the desktop systems a script pressed Enter through the boot menu and declared the desktop ready once the screen stopped changing for 10 seconds.

Idle memory was read 180 seconds after power-on from the virtio balloon driver on the host, as total memory minus MemAvailable. That is the same figure you get from /proc/meminfo inside the guest (we checked on Alpine: 159 MB from the host, 161 MB inside). It is not the “used” column that BusyBox free prints, which uses an older formula and reads much lower. SliTaz’s kernel does not report balloon statistics, so its figure came from free -m inside the guest, using the same total minus available math. The step-down test changed memory with one command per size, for example:

qm set 9401 --memory 128 --balloon 128

A headless distro passed a size if its port came up within 240 seconds and was still up 60 seconds later. Desktop distros were judged by screenshot at 150 seconds. The tests ran on x86_64 because that is what we had on the bench. Most of these distros ship ARM builds too, and the ARM numbers will differ, so treat the table as a relative ranking rather than a promise for a specific board.

1. OpenWrt

The standout for raw footprint. OpenWrt used 78 MB of RAM at idle, 29 MB of disk, and still served both SSH and the LuCI web interface 18 seconds after power-on. It is a router operating system first, so it ships a firewall, DHCP and DNS (dnsmasq), and a web UI, and very little else. For gateways, travel routers and any IoT box whose job is moving packets, nothing else on this list comes close.

LuCI’s own status page agreed with our measurement, showing 70 MiB used on the 1 GB VM:

OpenWrt LuCI status overview showing 70 MiB RAM used on a 1 GB VM

One trap before first boot: the x86 image comes up as a router with a static LAN address of 192.168.1.1 and a DHCP server running. Dropped onto a flat lab network, it will start handing out leases. We neutralised that with a script in /etc/uci-defaults/ on the image, so the VM joined the network as a plain DHCP client. These are the commands from that script. On a running system, run them from the console rather than over the LAN, because the 192.168.1.1 address disappears as soon as the network restarts:

uci set network.lan.proto='dhcp'
uci -q delete network.lan.ipaddr
uci -q delete network.lan.netmask
uci set dhcp.lan.ignore='1'
uci set dhcp.lan.dhcpv6='disabled'
uci set dhcp.lan.ra='disabled'
uci commit
/etc/init.d/odhcpd disable

Inside uci-defaults the changes apply at first boot. On a running system, uci commit only saves them, so apply them with service network restart and service dnsmasq restart, and stop the router advertisement daemon with service odhcpd stop (disabling it only affects the next boot). Then look for the router’s new address in your DHCP server’s lease list.

Current releases replaced opkg with apk, the same package manager Alpine uses. Refreshing the index and installing htop took 9.7 seconds, most of it spent downloading the package lists:

apk update && apk add htop

htop pulled in two dependencies and the whole system grew to 185 packages:

OK: 11241 distinct packages available
(1/3) Installing terminfo (6.4-r3)
  Executing terminfo-6.4-r3.post-install
(2/3) Installing libncurses6 (6.4-r3)
  Executing libncurses6-6.4-r3.post-install
(3/3) Installing htop (3.5.1-r1)
  Executing htop-3.5.1-r1.post-install
OK: 20.0 MiB in 185 packages

The LuCI package manager exposes the same repository in a browser, with a live disk-space bar. On this image the root partition is only 98 MiB, so that bar matters:

OpenWrt LuCI software page listing apk packages with disk space bar

At 128 MB OpenWrt booted and stayed up, which matches the project’s own 16 MB flash and 128 MB RAM recommendation. At 64 MB it got further than anything else on the list. Userspace started (dnsmasq, dropbear and netifd were all running), then about 68 seconds in the kernel’s OOM killer started taking processes, the firewall loader (nft) among them.

OpenWrt at 64 MB RAM with the OOM killer killing the nft process

Where it falls short: OpenWrt is not a general-purpose server. The package set is built around networking, the root filesystem is deliberately small, and running application workloads on it fights the design. If you want to try it on the same hypervisor we used, our guide to running OpenWrt as a Proxmox VM covers the full setup, including the WAN and LAN bridges.

2. Alpine Linux

If you only pick one general-purpose distro for small hardware, pick Alpine. It reached SSH in 9.6 seconds, idled at 162 MB, and the whole installed system took 99 MB of disk with 59 packages. It is built on musl libc and BusyBox with OpenRC as init, which is why it boots so fast and why it is also the base of so many container images.

The virt ISO is 66 MB, and setup-alpine accepts an answer file, which makes unattended installs easy. Boot the live ISO, log in as root and create the file with vi (the live system has no vim):

vi /root/answers

These are the exact answers we installed with. Replace the SSH key with your own:

KEYMAPOPTS="us us"
HOSTNAMEOPTS="-n alpine"
INTERFACESOPTS="auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp
"
TIMEZONEOPTS="-z UTC"
PROXYOPTS="none"
APKREPOSOPTS="-1"
USEROPTS="none"
SSHDOPTS="-c openssh"
ROOTSSHKEY="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExampleKeyReplaceWithYourOwn [email protected]"
NTPOPTS="-c busybox"
DISKOPTS="-m sys /dev/vda"
LBUOPTS="none"
APKCACHEOPTS="none"

Then run the installer against it. ERASE_DISKS skips the “erase this disk?” prompt, so double-check the device name first:

ERASE_DISKS=/dev/vda setup-alpine -e -f /root/answers && poweroff

The install finished in about 20 seconds. The -e flag leaves root with an empty password. SSH still needs the key, but anyone at the console can log in, so set a password with passwd after the first boot. One more gotcha from the live ISO: if eth0 is not up when udhcpc runs, it fails with “Network is down”. Run ip link set eth0 up first. Also note that -m sys creates a swap partition by default, 1.9 GB on our 8 GB disk, which you may not want on flash storage.

The installed system boots straight through OpenRC to a login prompt with nothing wasted along the way:

Alpine Linux OpenRC boot sequence ending at the login prompt

Package installs are nearly instant. htop installed in 1.36 seconds, with lsof pulled in as a dependency:

apk add htop

Two packages went in and the whole system is still 73.3 MiB (apk info -s htop puts htop itself at 307 KiB):

(1/2) Installing lsof (4.99.6-r0)
(2/2) Installing htop (3.5.3-r0)
Executing busybox-1.37.0-r31.trigger
OK: 73.3 MiB in 61 packages

Alpine stayed up at 128 MB. At 64 MB the kernel panicked about a second into boot with “System is deadlocked on memory”, before it had even finished unpacking its initramfs:

Alpine Linux kernel panic System is deadlocked on memory at 64 MB RAM

Where it falls short: musl. Most software builds fine against it, but prebuilt glibc binaries (some vendor agents, some Python wheels, proprietary drivers) will not run without extra work. Alpine is also a fine Kubernetes base on small hardware. We have a walkthrough for running k3s on Alpine.

3. DietPi

DietPi is Debian with the fat trimmed and a set of menu-driven tools on top. The Proxmox image is built on current Debian stable, reached SSH in 9.8 seconds (essentially tied with Alpine) and idled at 217 MB with only 11 userland processes. It uses Dropbear instead of OpenSSH and keeps /var/log in RAM by default, both choices aimed at SD cards and weak boards. The project publishes images for Raspberry Pi and most other ARM boards, plus x86 and some RISC-V boards.

First boot can be fully unattended. We set AUTO_SETUP_AUTOMATED=1, SURVEY_OPTED_IN=0 and AUTO_SETUP_SSH_PUBKEY in dietpi.txt on the image’s first partition before importing it, and the VM came up ready for key-based SSH with no console interaction. The headline tool is dietpi-software, a curated installer for common home-server stacks:

DietPi software menu with Dropbear SSH server and RAMlog selected

Because it is Debian underneath, you get the whole Debian archive through apt. htop is already in the image, so we timed tmux instead:

time apt-get install -y tmux

It took 8.2 seconds with a warm package index, the slowest of the package-manager distros but still quick:

Setting up libjemalloc2:amd64 (5.3.0-3) ...
Setting up libevent-core-2.1-7t64:amd64 (2.1.13-stable-1~deb13u1) ...
Setting up tmux (3.5a-3) ...
Processing triggers for debianutils (5.23.2) ...
Processing triggers for libc-bin (2.41-12+deb13u4) ...

real	0m8.204s
user	0m3.541s
sys	0m0.238s

DietPi booted and stayed up at 256 MB. At 128 MB the kernel panicked while unpacking the initramfs with the same “deadlocked on memory” message Alpine showed at 64 MB. Where it falls short: the installed footprint is about 1 GB, ten times Alpine, and it is still a mutable Debian system with no rollback. For a Raspberry Pi running Pi-hole or Home Assistant that is fine. If you are shopping for the board itself, our Raspberry Pi 5 kits and alternatives guide covers the hardware side.

4. Ubuntu Core

Ubuntu Core is the strictest system here. Everything, the kernel included, is a signed snap, updates are transactional with automatic rollback, and Canonical offers up to 15 years of security maintenance. It is built for device makers shipping thousands of identical units, and it behaves like it.

That strictness showed up immediately. The amd64 image took 40.2 seconds to reach its first-boot setup screen, the slowest first prompt in the test (only the Talos Kubernetes API took longer to come up), and the setup tool (console-conf) will not create a local user. It asks for the email address of an Ubuntu One account that already has an SSH key attached, then imports that key:

Ubuntu Core console-conf profile setup asking for an Ubuntu One account email

With the official signed image there is no local fallback. A system-user assertion has to be signed by the brand that owns the model, and Canonical owns this one. We did not link a store account to the lab VM, so our Ubuntu Core figures stop at that prompt: 134 MB of RAM in use and 1,896 MB on disk. Expect memory use to rise once you add application snaps.

The low-memory result was the surprise of the test. Canonical’s system requirements page lists 512 MB as the minimum, but our UEFI VM with Secure Boot keys enrolled and a virtual TPM never got past the firmware at 512 MB. It stopped with this error before the kernel loaded:

Ubuntu Core at 512 MB stopping at Could not install security protocol 0x2 Invalid Parameter

At 768 MB it reached the setup prompt normally. The failure may be specific to OVMF with Secure Boot rather than to Ubuntu Core itself, but it is exactly the configuration full disk encryption requires, so plan for more than the documented floor. Where it falls short: the Ubuntu One dependency for first login, the slowest first prompt here, and the most disk used. For a single hobby device it is the wrong tool. For a fleet that needs signed updates for a decade, it is the right one.

5. Fedora IoT

Fedora IoT is the image-based Fedora for edge devices: an rpm-ostree root that updates atomically, Podman for workloads, and Ignition for first-boot provisioning. It reached SSH in 18.5 seconds and idled at 324 MB, the heaviest of the non-Kubernetes systems. The base image already includes Podman, tmux and NetworkManager, so the 1.6 GB footprint is not wasted, but it is not small either.

Getting it running on Proxmox took two fixes. The raw image is UEFI-only, and on SeaBIOS it hangs at “Booting from Hard Disk…” forever. Then Ignition ignored the config we passed through QEMU’s fw_cfg and logged “no config provided by user”, because the image’s boot entry sets ignition.platform.id=metal. Changing that to qemu in /boot/loader/entries/ostree-1.conf on the raw image, before import, made it pick up this config:

{"ignition":{"version":"3.3.0"},"passwd":{"users":[{"name":"core","groups":["wheel"],"sshAuthorizedKeys":["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExampleKeyReplaceWithYourOwn [email protected]"]}]},"storage":{"files":[{"path":"/etc/sudoers.d/core","mode":288,"contents":{"source":"data:;base64,Y29yZSBBTEw9KEFMTCkgTk9QQVNTV0Q6IEFMTAo="}}]}}

The file creates a core user in the wheel group, adds the SSH key, and drops a passwordless sudo rule (the base64 decodes to core ALL=(ALL) NOPASSWD: ALL). On Proxmox it goes in through the VM’s extra QEMU arguments:

qm set 9404 --args "-fw_cfg name=opt/com.coreos/config,file=/root/fedora-iot.ign"

Installing software means layering it onto the image. htop took 63 seconds, most of it refreshing repository metadata, and the change only applies after a reboot:

sudo rpm-ostree install -y htop

rpm-ostree stages a new deployment beside the running one:

Will download: 2 packages (2.4 MB)
Downloading from 'fedora'...done
Downloading from 'updates'...done
Importing packages...done
Checking out packages...done
Running systemd-sysusers...done
Running pre scripts...done
Running post scripts...done
Running posttrans scripts...done
Writing rpmdb...done
Writing OSTree commit...done
Staging deployment...done
Added:
  htop-3.4.1-3.fc44.x86_64
  hwloc-libs-2.14.0-1.fc44.x86_64
Changes queued for next boot. Run "systemctl reboot" to start a reboot

After the reboot htop was there. Rolling back is one command and one more reboot, and it works the same way for a bad OS update:

sudo rpm-ostree rollback
sudo systemctl reboot

After the second reboot htop was gone again, and rpm-ostree status showed the original deployment active with the layered one kept as the fallback:

Deployments:
● fedora-iot:fedora/stable/x86_64/iot
                  Version: 44.20260427.0 (2026-04-27T16:34:26Z)
                   Commit: 35a2e036cdcf8f3067effe5a7a7415993481e9beaaca7eed7eabf53381852192
             GPGSignature: Valid signature by 36F612DCF27F7D1A48A835E4DBFCF71C6D9F90A6

  fedora-iot:fedora/stable/x86_64/iot
                  Version: 44.20260427.0 (2026-04-27T16:34:26Z)
               BaseCommit: 35a2e036cdcf8f3067effe5a7a7415993481e9beaaca7eed7eabf53381852192
             GPGSignature: Valid signature by 36F612DCF27F7D1A48A835E4DBFCF71C6D9F90A6
          LayeredPackages: htop

The download page still serves an April build. A sudo rpm-ostree upgrade --check on first boot found a September build waiting with 204 upgraded packages, so budget for a large first update. Fedora IoT booted at 512 MB and failed at 256 MB. Where it falls short: memory and disk, plus the rpm-ostree workflow, which is slower than a plain package install and needs a reboot for every change. If you want Kubernetes on top of it, MicroShift targets exactly this class of edge box.

6. Flatcar Container Linux

Flatcar has one job: run containers and update itself safely. There is no package manager. Docker and containerd ship as system extensions, /usr is read-only, and updates are written to whichever of two /usr partitions is idle, so a bad update rolls back by booting the other one. It reached SSH in 20.5 seconds and idled at 304 MB.

Like Fedora IoT it expects Ignition on first boot. The config only needs to add an SSH key to the core user:

{"ignition":{"version":"3.3.0"},"passwd":{"users":[{"name":"core","sshAuthorizedKeys":["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIExampleKeyReplaceWithYourOwn [email protected]"]}]}}

Flatcar reads it from a different fw_cfg key than Fedora does:

qm set 9406 --args "-fw_cfg name=opt/org.flatcar-linux/config,file=/root/flatcar.ign"

Don’t try to fit it on a small virtual disk. The QEMU image’s virtual size is 12.3 GB, and Proxmox refuses to resize it down with “shrinking disks is not supported”. Its partition layout shows the A/B scheme clearly:

lsblk -o NAME,SIZE,PARTLABEL /dev/vda

USR-A is mounted and USR-B waits for the next update:

NAME     SIZE PARTLABEL
vda     12.3G
|-vda1     1G EFI-SYSTEM
|-vda2     2M BIOS-BOOT
|-vda3     2G USR-A
| `-usr 1016M
|-vda4     2G USR-B
|-vda6     1G OEM
|-vda7    64M OEM-CONFIG
`-vda9   6.2G ROOT

Docker is ready on first boot. The first run of an Alpine container returned in 6.8 seconds:

docker run --rm alpine echo hello-from-flatcar

Flatcar booted at 256 MB and panicked at 128 MB while decompressing its initramfs. Where it falls short: you cannot install anything on the host, so every tool you want (even a debugger) has to run in a container or ship as a sysext, and our QEMU image could not be shrunk below 12.3 GB. On bare metal the installer writes to any disk and the root partition grows to fill it, so that limit is specific to the prebuilt VM image. We cover the full install in running Flatcar on Proxmox VE.

7. Talos Linux

Talos is the most radical design here. It has no shell and no SSH. You manage it only through an API with talosctl, and it exists to run Kubernetes. It is the heaviest system in the table, but the comparison is unfair: the others are idling an empty OS, while Talos is idling a complete single-node Kubernetes control plane with etcd, the API server, the scheduler, CoreDNS and Flannel. How it fares against Flatcar and Fedora CoreOS as a dedicated Kubernetes node is covered in the container OS comparison for Kubernetes.

We gave it the documented control-plane minimum of 2 vCPU and 2 GB. The Talos API answered 11.5 seconds after power-on, and the Kubernetes API followed at 49.1 seconds. Setup runs from a workstation: generate the configs, push the control-plane config to the node, point talosctl at it, bootstrap etcd, and fetch a kubeconfig:

talosctl gen config tiny-talos https://192.168.1.50:6443 --install-disk /dev/vda
talosctl apply-config --insecure -n 192.168.1.50 --file controlplane.yaml
export TALOSCONFIG=$PWD/talosconfig
talosctl config endpoint 192.168.1.50
talosctl config node 192.168.1.50
talosctl bootstrap
talosctl kubeconfig ./kubeconfig
export KUBECONFIG=$PWD/kubeconfig

Run bootstrap too soon after apply-config and it answers “bootstrap is not available yet”. Wait until the node has rebooted into its installed system, then run it again. We also hit two errors trying to patch the generated config. A JSON6902 patch failed with “JSON6902 patches are not supported for multi-document machine configuration”, and a strategic patch that set allowSchedulingOnControlPlanes failed with “.cluster.allowSchedulingOnControlPlanes is already set in v1alpha1 config”. Current Talos splits the machine config into many small documents, and the control-plane taint now lives in a KubeNodeConfig document. Leave it alone and a single-node cluster runs its own system pods but nothing you deploy: our test nginx pod sat in Pending, and removing the taint with kubectl taint did not stick because Talos put it back within a minute. The fix that worked was a patch against that document. Save it as untaint.yaml:

vim untaint.yaml

The whole file is four lines. It clears every taint in that document, which on a default single node is only the control-plane taint. If you have added taints of your own, nest $patch: delete under the node-role.kubernetes.io/control-plane key instead:

apiVersion: v1alpha1
kind: KubeNodeConfig
taints:
  $patch: delete

Apply it to the running node. Talos reported “Applied configuration without a reboot”, the taint was gone 30 seconds later, and the pending pod started:

talosctl patch mc --patch @untaint.yaml

Skip this patch on a real control plane that has separate workers.

Once healthy, the node reports itself as a Ready control plane:

kubectl get nodes -o wide

Note the containerd runtime and the Talos kernel in the output:

NAME            STATUS   ROLES           AGE    VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE          KERNEL-VERSION          CONTAINER-RUNTIME
talos-dgk-7s8   Ready    control-plane   158m   v1.37.0   192.168.1.50    <none>        Talos (v1.14.1)   6.18.51-talos (amd64)   containerd://2.3.5

The console shows a live dashboard instead of a login prompt, which is the only local interface you get:

Talos Linux console dashboard showing a healthy control plane node

At 1.5 GB the control plane still came up and stayed up. At 1 GB the kubelet reported healthy but the Kubernetes API never stayed reachable, which lines up with the Talos requirements of 2 GB for a control plane and 1 GB for a worker. Where it falls short: no shell means no quick poking around, and the RAM floor rules out the small boards in this roundup unless the device is only a worker. If you are weighing Talos against the lighter Kubernetes distributions, our k0s vs k3s vs MicroK8s comparison covers the other side, and the Talos cluster guide goes multi-node.

8. Tiny Core Linux

The 64-bit TinyCorePure64 ISO is 42 MB and boots to a graphical desktop in 12.4 seconds, the fastest desktop here by a wide margin. The whole system loads into RAM and runs from there. It idled at 175 MB with the desktop up. (The 32-bit TinyCore ISO is even smaller at 26 MB. On the same VM it reached the desktop in 10.3 seconds and idled at 151 MB, but the table uses the 64-bit build so all ten are compared on x86_64.) Applications come as .tcz extensions you load on demand with tce-load, and nothing persists across reboots unless you configure a persistence location on disk.

The default desktop is spare: a FLWM window manager, a dock, and not much else:

Tiny Core Linux 64-bit live desktop with the wbar dock

The desktop came up at 128 MB. At 64 MB the 64-bit build panicked with “VFS: Unable to mount root fs” and the 32-bit build with “No working init found”, both of which contradict the 46 MB minimum in the Tiny Core FAQ. That figure predates current kernels. The FAQ’s own 128 MB recommendation is the one to trust. With piCore builds for the Raspberry Pi on top of its x86 images, it is also the most portable of the three desktop options.

Where it falls short: our VM’s virtual mouse never registered on its desktop, and you build every capability yourself from extensions. It is excellent for a kiosk, a thin client or reviving a very old PC for one task. As a daily desktop it asks for a lot of assembly.

9. antiX

antiX is the one to hand to someone who wants a normal desktop on an old laptop. It is Debian-based with no systemd (runit is the default init, with sysVinit, dinit and s6 as options), uses IceWM, and still ships 32-bit builds. The full live ISO reached a settled desktop in 27.4 seconds with far more applications preinstalled than the 671 MB core ISO, which ships without a desktop.

The Conky panel on the desktop showed 197 MB used, while our measurement said 310 MB. Both are right. Conky’s “used” leaves out cache, but on a live system the root filesystem sits in RAM, and the kernel cannot hand that memory back. So it counts against what is available:

antiX live desktop with Conky showing runit init and RAM usage

At 256 MB the desktop still appeared, with Conky reading 174 MB used of 210 MB and the CPU pinned at 96% while it finished loading. At 128 MB the kernel could not mount its live root filesystem and panicked. Installed to disk it should need less, because the filesystem would no longer live in RAM, though we only measured the live session. Where it falls short: the live x64-full image boots an older long-term kernel by default, so very new Wi-Fi and GPU hardware may need the newer kernel entry offered at boot. On the 2010-era laptops antiX is aimed at, that rarely matters. For newer machines with more RAM, our roundup of the best Linux desktop distributions has heavier options.

10. SliTaz

SliTaz packs a graphical desktop and its own package manager (tazpkg) into a 59 MB ISO that runs entirely from RAM. It took 31.4 seconds to settle on its desktop, and a terminal inside the guest showed 275 MB unavailable out of 1,007 MB.

SliTaz desktop terminal showing release, kernel version and free memory

Look at the second line of that terminal. The current rolling ISO still boots a 3.16-series kernel, which is more than a decade old. The project news talks about moving to a newer kernel and toward a new stable release, but the published ISO has not caught up. That is the reason SliTaz sits last: old kernels mean missing drivers for newer hardware and no security fixes. At 256 MB the desktop came up. At 128 MB SliTaz skipped X and dropped to a text login, which is still useful as a rescue system.

Also considered

Several popular names did not make the test, for reasons worth knowing before you download them. Bodhi Linux has not had a stable release since October 2023. Damn Small Linux 2024 never left release candidate, and the last RC dates from June 2024. Void Linux is actively maintained, but its live images were about 20 months old when we checked. Bottlerocket no longer ships bare-metal Kubernetes variants, and there is no generic ISO or QEMU image to boot. Raspberry Pi OS is ARM-only (the old x86 Desktop edition is long stale), so it could not run on this bench. Linux Lite is not light any more: its site now recommends 4 GB of RAM.

Two more nearly made it. Puppy Linux is alive, but it is hard to tell which of the many builds on its mirrors are official releases and which are CI output. We would rather test it once that is clearer. SUSE Linux Micro is a credible transactional edge OS, but it fills the same slot as Fedora IoT, and one image-based RPM distro was enough for this comparison. Buildroot and Yocto belong in any embedded conversation, but they are build systems that produce a custom image for your hardware, not distributions you download and boot.

Match the distro to the hardware

Start from what the device does and how much RAM it has, not from which distro looks lightest in a chart:

  • It routes, filters or bridges traffic: OpenWrt. It is the lightest thing we tested, and nothing else gives you a firewall, DHCP and a web UI in 29 MB.
  • It runs a few services on 128 to 512 MB: Alpine Linux. Fastest to boot, smallest general-purpose install, and apk makes changes near-instant.
  • It is a Raspberry Pi or old PC running home-server apps: DietPi. You keep Debian’s package archive and get guided installers for the usual stacks.
  • It runs containers and must update itself without you: Flatcar with 256 MB or more, or Fedora IoT with 512 MB or more if you want to layer RPMs and use Podman.
  • It is one of many identical devices that need signed updates for years: Ubuntu Core, with at least 768 MB of RAM in our testing and an Ubuntu One account for first login.
  • It joins a Kubernetes cluster: Talos, with 2 GB for a control plane or 1 GB for a worker.
  • It is an old laptop that someone will use every day: antiX. The live session reached its desktop at 256 MB.
  • It is a very old PC with one job (kiosk, thin client, terminal): Tiny Core, from 128 MB up.

SliTaz is not on that list on purpose. It is still a clever 59 MB rescue system, but until the published ISO moves off its decade-old kernel, Tiny Core does the same job on current code.

Keep reading

Upgrade Ubuntu 24.04 to Ubuntu 26.04 LTS (Step by Step) Ubuntu Upgrade Ubuntu 24.04 to Ubuntu 26.04 LTS (Step by Step) UFW Firewall Commands with Examples on Ubuntu 26.04 / 24.04 Security UFW Firewall Commands with Examples on Ubuntu 26.04 / 24.04 PHP2Shell (CVE-2026-109618, CVE-2026-109619): Check and Patch PHP Php PHP2Shell (CVE-2026-109618, CVE-2026-109619): Check and Patch PHP Install Lutris, Heroic and GE-Proton on Fedora 45 / 44 Fedora Install Lutris, Heroic and GE-Proton on Fedora 45 / 44 Fedora 45 kmscon Console: Fonts, Keymaps and Reverting to fbcon Fedora Fedora 45 kmscon Console: Fonts, Keymaps and Reverting to fbcon KVM How To extend KVM Virtual Machine disk size

Leave a Comment

Press ESC to close