On the test box, a Toolbx container answered its first command in 0.35 seconds, while the same Fedora image under Distrobox needed 24.4 seconds before it would run anything. That gap is the clearest result of this Distrobox vs Toolbox comparison, and it comes from a design choice rather than from speed: Toolbx expects an image that is already prepared for it, and Distrobox prepares whatever image it is given on the first enter.
Benchmarked September 2026 on Fedora 44 with Distrobox 1.8.2.5 and Toolbx 0.3.
Both tools wrap rootless Podman, mount the home directory, share the host network and PID namespace, and drop the user into a mutable distro shell. The numbers below cover first enter time, cold and warm command latency, disk added per container, idle memory, the distros each tool accepts, and the host integration flags read from podman inspect. The Distrobox and Toolbox install guide covers the everyday workflow; this page is the measured side of the toolbox vs distrobox question.
Distrobox vs Toolbox: measured results
Seven containers were created on one host. Toolbx ran its own Fedora, Ubuntu 24.04 and Arch images. Distrobox ran the same Fedora and Ubuntu Toolbx images, plus the plain Docker Hub ubuntu and archlinux images that most Distrobox guides use. “First enter” is the time from the first run or enter to the command finishing, so it includes any setup the tool does inside the container.
| Container | Image | Create | First enter | Cold run (median) | Warm run (median) | Disk added |
|---|---|---|---|---|---|---|
| Toolbx, Fedora 44 | fedora-toolbox:44 | 1.28 s | 0.35 s | 299 ms | 185 ms | 1 MB |
| Distrobox, Fedora 44 | fedora-toolbox:44 | 2.21 s | 24.4 s | 755 ms | 216 ms | 142 MB |
| Toolbx, Ubuntu 24.04 | ubuntu-toolbox:24.04 | 1.24 s | 0.37 s | 340 ms | 225 ms | 1 MB |
| Distrobox, Ubuntu 24.04 | ubuntu-toolbox:24.04 | 1.99 s | 62.4 s | 449 ms | 222 ms | 606 MB |
| Distrobox, Ubuntu 24.04 | ubuntu:24.04 (Docker Hub) | 0.98 s | 83.8 s | 420 ms | 213 ms | 659 MB |
| Toolbx, Arch | arch-toolbox:latest | 2.38 s | 0.39 s | 344 ms | 194 ms | 1 MB |
| Distrobox, Arch | archlinux:latest (Docker Hub) | 1.80 s | 38.7 s | 461 ms | 212 ms | 1,011 MB |
dnf test.Three conclusions hold across every distro. Toolbx is ready in under 0.4 seconds on first use and writes about 1 MB to the container layer. Distrobox spends 24 to 84 seconds on first enter and adds 142 MB to 1 GB per container. Once a container is running, the two tools are within 40 ms of each other, so the choice between them comes down to distro coverage and features, not everyday speed.
How the test box was set up
The host was a Fedora 44 VM on Proxmox with 2 vCPU (host CPU type), 4 GB of RAM with ballooning pinned, a 40 GB virtio-scsi disk on ZFS, and rootless Podman under a regular user. Both tools came from the Fedora repositories:
sudo dnf install -y distrobox toolbox podman
The package query confirms the three versions under test:
rpm -q distrobox toolbox podman
Fedora 44 ships the current upstream releases of Distrobox and Toolbx, with Podman from the Fedora 5.x line:
distrobox-1.8.2.5-1.fc44.noarch
toolbox-0.3-4.fc44.x86_64
podman-5.8.7-1.fc44.x86_64
Each metric was taken the same way for every container. Create time is toolbox create or distrobox create with the image already in local storage. Cold run is the median of five runs of true after podman stop -t 0. Warm run is the median of 20 runs of true against a running container. The script below produced the create, first enter, cold and warm columns, and it can be repeated on any rootless Podman host. Its podman ps --size field was not used for the disk column, because the size reports from Podman on this rootless overlay store disagreed with du. Disk added was a separate step, shown after the script.
vim ~/dbx-tbx-bench.sh
Paste the benchmark exactly as it ran on the test box:
#!/bin/bash
# dbx-tbx-bench.sh OUTDIR : Distrobox vs Toolbx timings on a rootless podman host (run as the lab user).
# Rows go to OUTDIR/results.jsonl, raw command output to OUTDIR/raw.log.
set -u
OUT=${1:-$HOME/bench}; mkdir -p "$OUT"; RAW="$OUT/raw.log"; RES="$OUT/results.jsonl"
ms() { echo $(( ($(date +%s%N) - $1) / 1000000 )); }
med() { sort -n | awk '{a[NR]=$1} END{print (NR%2)?a[(NR+1)/2]:int((a[NR/2]+a[NR/2+1])/2)}'; }
log() { echo "### $*" >>"$RAW"; }
# name|tool|create args|image
CASES=(
"tbx-fedora|toolbox|--release 44|registry.fedoraproject.org/fedora-toolbox:44"
"dbx-fedora|distrobox|-i registry.fedoraproject.org/fedora-toolbox:44|registry.fedoraproject.org/fedora-toolbox:44"
"tbx-ubuntu|toolbox|--distro ubuntu --release 24.04|quay.io/toolbx/ubuntu-toolbox:24.04"
"dbx-ubuntu-tbximg|distrobox|-i quay.io/toolbx/ubuntu-toolbox:24.04|quay.io/toolbx/ubuntu-toolbox:24.04"
"dbx-ubuntu|distrobox|-i docker.io/library/ubuntu:24.04|docker.io/library/ubuntu:24.04"
"tbx-arch|toolbox|--distro arch --release latest|quay.io/toolbx/arch-toolbox:latest"
"dbx-arch|distrobox|-i docker.io/library/archlinux:latest|docker.io/library/archlinux:latest"
)
runc() { # tool name
if [ "$1" = toolbox ]; then toolbox run -c "$2" true; else distrobox enter -n "$2" -T -- true; fi
}
{ podman --version; toolbox --version; distrobox version; uname -r; cat /etc/fedora-release; } >>"$RAW" 2>&1
for c in "${CASES[@]}"; do
IFS='|' read -r name tool args img <<<"$c"
log "$name pull $img"
t=$(date +%s%N); podman pull -q "$img" >>"$RAW" 2>&1; pull_ms=$(ms $t)
img_mb=$(podman image inspect "$img" --format '{{.Size}}' | awk '{printf "%d", $1/1000000}')
log "$name create"
t=$(date +%s%N)
if [ "$tool" = toolbox ]; then toolbox -y create $args "$name" >>"$RAW" 2>&1
else distrobox create -Y $args -n "$name" >>"$RAW" 2>&1; fi
create_ms=$(ms $t)
log "$name first enter"
t=$(date +%s%N); runc "$tool" "$name" >>"$RAW" 2>&1; first_ms=$(ms $t)
sleep 60
mem_mb=$(podman stats --no-stream --format '{{.MemUsage}}' "$name" | awk '{print $1}')
procs=$(podman top "$name" pid 2>/dev/null | tail -n +2 | wc -l)
size=$(podman ps -a --size --filter name="^${name}\$" --format '{{.Size}}')
cold=(); for i in 1 2 3 4 5; do
podman stop -t 0 "$name" >/dev/null 2>&1
t=$(date +%s%N); runc "$tool" "$name" >/dev/null 2>&1; cold+=("$(ms $t)")
done
warm=(); for i in $(seq 1 20); do
t=$(date +%s%N); runc "$tool" "$name" >/dev/null 2>&1; warm+=("$(ms $t)")
done
cold_med=$(printf '%s\n' "${cold[@]}" | med); warm_med=$(printf '%s\n' "${warm[@]}" | med)
log "$name inspect"
podman inspect "$name" --format 'net={{.HostConfig.NetworkMode}} pid={{.HostConfig.PidMode}} ipc={{.HostConfig.IpcMode}} privileged={{.HostConfig.Privileged}} userns={{.HostConfig.UsernsMode}} secopt={{.HostConfig.SecurityOpt}} ulimits={{len .HostConfig.Ulimits}}' >>"$RAW" 2>&1
podman inspect "$name" --format '{{range .Mounts}}{{.Destination}} {{end}}' >>"$RAW" 2>&1
printf '{"name":"%s","tool":"%s","image":"%s","image_mb":%s,"pull_ms":%s,"create_ms":%s,"first_enter_ms":%s,"idle_mem":"%s","procs":%s,"size":"%s","cold_ms":[%s],"cold_med_ms":%s,"warm_ms":[%s],"warm_med_ms":%s}\n' \
"$name" "$tool" "$img" "$img_mb" "$pull_ms" "$create_ms" "$first_ms" "$mem_mb" "$procs" "$size" \
"$(IFS=,; echo "${cold[*]}")" "$cold_med" "$(IFS=,; echo "${warm[*]}")" "$warm_med" | tee -a "$RES"
podman stop -t 0 "$name" >/dev/null 2>&1
done
Run it as the regular user, not with sudo, and it writes one JSON line per container to ~/bench/results.jsonl. Expect about 20 minutes, most of it Distrobox first enters and image pulls:
bash ~/dbx-tbx-bench.sh ~/bench
For the disk column, read the size of the upper directory of each container from inside the rootless user namespace, where the files are owned by the mapped IDs:
for c in tbx-fedora dbx-fedora tbx-ubuntu dbx-ubuntu-tbximg dbx-ubuntu tbx-arch dbx-arch; do u=$(podman inspect $c --format "{{.GraphDriver.Data.UpperDir}}"); echo "$c writable_layer=$(podman unshare du -sm $u | cut -f1)MB"; done
Why the first Distrobox enter takes 24 to 84 seconds
Distrobox does not require a special image. On the first enter, its init script inspects the container, installs the packages it needs for host integration, and then configures mounts, sockets, sudo and the user account. Every step prints a status line:

The “Installing basic packages” line is where the time goes. On the plain ubuntu:24.04 image, the apt history inside the container shows one apt-get install of 54 requested packages, among them mesa-vulkan-drivers, libgl1, man-db, language-pack-en, openssh-client and sudo. That is the 659 MB the container gained. The same 54-package request ran inside the Toolbx Ubuntu image, which already works as a shell environment, and that container grew by 606 MB. Only the Fedora Toolbx image came close to complete, and Distrobox still added five packages there, including glibc-locale-source, for 142 MB.
Toolbx takes the opposite approach. Its images are built with everything toolbox init-container needs, and the init step creates the user, writes a sudoers drop-in and links host paths into the container. Nothing is downloaded. The container layer stays at 1 MB as a result, and the first run finishes in the same time as any later cold run.
First enter is also network-bound for Distrobox: the 83.8 seconds on Ubuntu includes apt downloads from the Ubuntu mirrors, so a slower link stretches it further. The cost is paid once per container. A Distrobox user who recreates containers often (CI runners, throwaway test boxes) pays it every time, and distrobox create --clone or a custom image with the packages baked in is the fix.
Disk: the image size matters as much as the container
Toolbx keeps each container small by making the image large. The Arch Toolbx image unpacks to 2,164 MB, against 413 MB for the Docker Hub archlinux image, so the Arch totals reverse once the image is counted:
| Setup | Download (compressed) | Image on disk | Container layer | Total for one container |
|---|---|---|---|---|
| Toolbx, Fedora 44 | 374 MB | 1,082 MB | 1 MB | 1,083 MB |
| Distrobox, Fedora 44 (same image) | 374 MB | 1,082 MB | 142 MB | 1,224 MB |
| Toolbx, Ubuntu 24.04 | 207 MB | 583 MB | 1 MB | 584 MB |
| Distrobox, Ubuntu 24.04 (Docker Hub) | 29 MB | 82 MB | 659 MB | 741 MB |
| Toolbx, Arch | 727 MB | 2,164 MB | 1 MB | 2,165 MB |
| Distrobox, Arch (Docker Hub) | 133 MB | 413 MB | 1,011 MB | 1,424 MB |
For a single container, Toolbx is smaller on Fedora and Ubuntu and larger on Arch by 741 MB. The picture changes with several containers from one image, because the image is stored once and only the container layer repeats. Five Ubuntu containers cost 588 MB under Toolbx and about 3.4 GB under Distrobox with the Docker Hub image.
Start time and command latency
Cold runs, where the container has to start first, favour Toolbx by 80 to 456 ms. The Distrobox entrypoint runs its setup script again on every container start, which accounts for the general cold overhead. The Fedora Distrobox container was the slowest at a 755 ms median; the lab did not isolate why Fedora in particular was slower than the Ubuntu and Arch boxes. Warm runs are a different story: 185 to 225 ms for Toolbx and 212 to 222 ms for Distrobox, with the full ranges overlapping (144 to 242 ms against 182 to 249 ms). A shell opened in either tool feels the same once the container is up, and both leave it running after the first enter until podman stop or a reboot.
Idle memory: under 3 MB either way
After a reboot, each container was started with its own tool and left idle for 120 seconds. The cgroup of each container reported 2 MB of anonymous memory for every Toolbx container and under 1 MB for every Distrobox container. The process that stays resident is toolbox init-container for Toolbx (13.9 MB RSS) and a shell entrypoint with a sleep loop for Distrobox (under 4 MB RSS). In the benchmark run, podman stats showed 48 to 75 MB for the three Distrobox containers that installed hundreds of MB of packages (60 seconds after first enter), and 5.8 MB for the Fedora one. After a reboot, the cgroup reading shows the tool itself holds under 1 MB of anonymous memory in those same containers, so idle RAM does not separate the two.
Which distros each tool runs
Toolbx is not Fedora-only, but its list is short. The distro table in the Toolbx source has four entries: arch, fedora, rhel and ubuntu. Any other value for --distro is refused before an image is pulled:

Error: “Distribution debian is unsupported”
Toolbx prints this for any --distro outside its four. Point it at an image instead with toolbox create --image quay.io/toolbx-images/debian-toolbox:13, since --image skips the distro check, or use Distrobox, which takes any OCI image. The Distrobox compatibility list names tested images for AlmaLinux, Alpine, Amazon Linux, CentOS Stream, Debian, openSUSE, Rocky Linux, Wolfi and more, plus the community toolbx-images that suit both tools. Distrobox also runs on Docker or lilipod as well as Podman, and on host distros beyond Fedora, including the Ubuntu hosts covered in the Podman on Ubuntu 26.04 guide.
Toolbx without --distro or --release matches the host, so on Fedora 44 it creates a Fedora 44 container. Existing containers keep their image through an upgrade to Fedora 45; plan to recreate them on the new release rather than upgrade inside them.
Host integration compared
The Podman flags behind both tools are nearly identical. Reading them back from the two Fedora containers:
podman inspect tbx-fedora --format "net={{.HostConfig.NetworkMode}} pid={{.HostConfig.PidMode}} ipc={{.HostConfig.IpcMode}} privileged={{.HostConfig.Privileged}} secopt={{.HostConfig.SecurityOpt}}"
The Toolbx container shares the host network, PID and IPC namespaces and runs privileged with SELinux labelling off:
net=host pid=host ipc=host privileged=true secopt=[label=disable unmask=all]
The same query with dbx-fedora in place of tbx-fedora returns the same set for the Distrobox container, plus an AppArmor opt-out that has no effect on an SELinux host like Fedora:
net=host pid=host ipc=host privileged=true secopt=[label=disable apparmor=unconfined unmask=all]
Neither container is a security boundary. “Privileged” here is still bounded by the rootless user namespace, so a process inside cannot do more than the host user can, but it can read and write everything that user owns. The differences sit in the defaults and the options around them:
| Behaviour (tested unless marked) | Toolbx | Distrobox |
|---|---|---|
| Home directory | Host home, same path | Host home, or a separate one with --home |
| Hostname inside | toolbx | Host hostname (bench01) |
| sudo | Works with no prompt (empty password field in /etc/passwd), but sudo -n fails | Explicit NOPASSWD rule, sudo -n works |
Session D-Bus and /run/host | Shared | Shared |
| Separate network namespace | No option | --unshare-netns (container got its own netns via pasta) |
| systemd as PID 1 | No option | --init (Debian 13 container reported running) |
| Export apps or binaries to the host | No command | distrobox-export --app / --bin |
| Declarative config for many boxes | No | distrobox assemble with an ini file |
| Rootful containers | No flag (runs under sudo, not tested) | --root (from --help, not tested) |
| Container managers | Podman only | Podman, Docker, lilipod (from docs, Podman tested) |
The sudo row matters for scripts. Inside Toolbx, sudo dnf install runs without asking for anything because the container account has an empty password field in /etc/passwd, yet a non-interactive sudo -n true exits with “a password is required”. Distrobox writes "klinsmann" ALL = (root) NOPASSWD:ALL into /etc/sudoers.d/sudoers, so both forms work.
What only Distrobox does
Exporting is the feature Toolbx users most often ask for. distrobox-export --bin writes a small wrapper script on the host that calls distrobox-enter, so a tool installed in an Arch container runs from the Fedora shell like a native command. The Arch fastfetch below reports the Arch userland on the Fedora kernel:

--app takes an application name or a desktop file and exports that desktop entry to the host, so a GUI app from the container shows up in the desktop launcher (this lab was headless, so the app export was not captured). For desktop apps that exist on Flathub, Flatpak is still the cleaner route, because it sandboxes the app and updates it with the rest of the desktop.
The --init flag runs systemd as PID 1 in its own PID namespace. A Debian 13 container created with --init --additional-packages "systemd libpam-systemd" took 63.4 seconds from create to first shell and then reported systemctl is-system-running as running. That suits testing a unit file for another distro. For long-running services on the host itself, Podman Quadlet is the better fit.
distrobox assemble create --file boxes.ini built two containers from one ini file in 2.1 seconds (package installs happen later, on first enter). That makes the full set of dev environments for a team reproducible from a file in the repository, which Toolbx has no equivalent for.
When Toolbx is the better pick
Toolbx wins where its narrow scope is the point. The Toolbx project documents it as installed by default on Fedora Workstation and Silverblue (the workstation-product group on the test box lists toolbox), and on Silverblue it is the standard way to get a mutable dnf environment on an image-based system (see managing packages on Silverblue). Its containers are ready in under half a second with no network access after the pull, and each one adds about 1 MB. For Fedora, RHEL, Ubuntu or Arch shells on a Fedora machine, that is everything most developers need. The Fedora 44 post-install checklist covers where it fits in a new workstation.
Distrobox is the pick for any distro outside those four, for a non-Fedora host, for Docker users, and for anyone who needs exported apps, a separate home, systemd inside the container or a declarative set of boxes. The first-enter cost is the price of that flexibility.
Running Distrobox and Toolbx on the same host
Both packages install side by side, and on the test box they shared one Podman store without conflict. The overlap shows in the listings. distrobox list showed only the containers Distrobox created, but toolbox list also showed every Distrobox container built from a Toolbx image, because those images carry the com.github.containers.toolbox label:
toolbox list
The dbx-fedora, dbx-ubuntu-tbximg and asm-fedora entries are Distrobox containers:
IMAGE ID IMAGE NAME CREATED
6a7833244dbc quay.io/toolbx/arch-toolbox:latest 2 days ago
c67cffe58455 quay.io/toolbx/ubuntu-toolbox:24.04 2 days ago
3bcb3bbccfb2 registry.fedoraproject.org/fedora-toolbox:44 11 hours ago
CONTAINER ID CONTAINER NAME CREATED STATUS IMAGE NAME
fd23d2b9f908 asm-fedora 1 second ago created registry.fedoraproject.org/fedora-toolbox:44
e49b50aee83d dbx-fedora 23 minutes ago running registry.fedoraproject.org/fedora-toolbox:44
970ee37359f1 dbx-ubuntu-tbximg 19 minutes ago running quay.io/toolbx/ubuntu-toolbox:24.04
23447dfd7009 tbx-arch 13 minutes ago running quay.io/toolbx/arch-toolbox:latest
cec13d8678a8 tbx-fedora 24 minutes ago running registry.fedoraproject.org/fedora-toolbox:44
6eca134fb844 tbx-ubuntu 21 minutes ago running quay.io/toolbx/ubuntu-toolbox:24.04
Error: “container dbx-fedora is too old and no longer supported”
Toolbx lists those containers but will not enter them. toolbox run -c dbx-fedora fails with this message and suggests recreating the container with Toolbx 0.0.97 or newer, although the container is minutes old. The check fails because Distrobox creates the container with its own entrypoint instead of toolbox init-container. Nothing is broken: enter those containers with distrobox enter, and give each tool its own container names (the tbx- and dbx- prefixes used here) so that neither listing becomes ambiguous.