Benchmarks

The numbers behind "no daemon".

cardinal's pitch is measurable: one small binary, nothing running when you aren't using it. Here's what the project ships and how to verify it on your own host in five minutes.

Metric cardinal Docker Podman
Binary size~5 MB static~100+ MB client + daemon~50 MB + optional service
Idle processes0 — nothing runs until invokeddockerd + containerd + runc0 (per-command), optional podman service
Idle listening ports0dockerd socket0 (rootless, per-user)
Start a containerunshare + overlayfs, one binaryclient → daemon → containerd → runcconmon + runc
The size and idle-process claims are properties of the design, not marketing: a ~5 MB static binary that spawns only when invoked. Everything else depends on your kernel, disk and image — measure it.
Methodology

Measure it yourself.

This script sizes the binaries, counts idle processes, and times pulling and starting the same image under cardinal and Docker on the same host:

bench.sh
#!/bin/bash
set -e

echo "== binary size =="
ls -lh $(command -v cardinal) | awk '{print "cardinal:", $5}'
ls -lh $(command -v dockerd) | awk '{print "dockerd: ", $5}'
ls -lh $(command -v podman) | awk '{print "podman:  ", $5}'

echo
echo "== idle footprint (nothing running) =="
echo "cardinal processes:  $(pgrep -c cardinal || echo 0)"
echo "docker processes:    $(pgrep -c dockerd || echo 0) dockerd + $(pgrep -c containerd || echo 0) containerd"

echo
echo "== container start (cold, same image nginx:alpine) =="
/usr/bin/time -f "cardinal: %e s, %M KB peak" cardinal run --rm nginx:alpine echo ok > /dev/null
/usr/bin/time -f "docker:   %e s, %M KB peak" docker run --rm nginx:alpine echo ok > /dev/null

echo
echo "== steady-state memory with one container =="
cardinal run -d -n bench-cardinal -p 8081:80 nginx:alpine
docker run -d --name bench-docker -p 8082:80 nginx:alpine
sleep 2
echo "cardinal web RSS: $(ps -o rss= -C unshare | awk '{s+=$1} END {print s/1024 " MB"}')"
echo "docker processes RSS: $(ps -o rss= -C dockerd,containerd | awk '{s+=$1} END {print s/1024 " MB"}')"

cardinal stop bench-cardinal && cardinal rm bench-cardinal
docker stop bench-docker > /dev/null && docker rm bench-docker > /dev/null
Interpretation

What the difference is.

size

Why 5 MB matters

A static Go binary with no runtime dependencies can live on any VPS, in a cron job, in a rescue system — anywhere a 100 MB+ daemon is overkill. It also means fewer attack-surface code paths and faster cold starts on small disks.

idle

Why zero idle matters

No daemon means no always-on process, no listening socket, no background memory. On a small VPS that's real RAM and real security surface — cardinal exists only while you use it.

See the full feature comparison → Install and measure it yourself