2374 words
12 min read

Docker Desktop's Performance Odyssey Over a Year of Innovations

By · Docker Captain · CNCF Ambassador · IBM Champion
Docker Desktop performance benchmark dashboard displayed on MacBook Pro workstation

Docker Desktop changed a lot during 2023, and most of it landed where you feel it day to day: how fast the daemon comes up, how fast a bind mount moves bytes, how fast a container reaches the internet, and how much memory the whole thing holds when it is doing nothing. This post is a reading of what Docker published about those releases, with each number attributed to where it came from, plus what I saw on my own Docker Desktop v4.22.0 install while following along.

NOTE

Sources

The measurements in this post are not mine unless the caption says so. They come from two places:

Three screenshots are my own, taken on Docker Desktop v4.22.0 on my Mac, and are labelled as such.

2023: what Docker shipped, release by release#

1. Daemon startup time#

Docker’s 4.21 release post states that launching Docker Desktop on Apple Silicon is at least 25% quicker than previous versions and that, after a fix to a startup bug, Docker starts in four seconds on Apple Silicon. Source: Docker Desktop 4.21 release post, July 2023. I have no per-platform table of my own to add; the earlier version of this post carried one without a source, and it is gone.

2. Container operations with hyperfine#

The runs below are Ajeet Singh Raina’s, comparing Docker Desktop v4.22 against v4.11 with hyperfine. Source: Collabnix, “Docker Desktop for Mac is no longer slow”. Output reproduced as published.

To install hyperfine:

Terminal window
brew install hyperfine

The benchmark command:

Terminal window
hyperfine -i -p 'docker stop ubuntu || :' 'docker run -it --rm ubuntu echo'

What the flags do:

  • -i tells hyperfine to ignore a non-zero exit code from the benchmarked command.
  • -p sets a preparation command that runs before each timing run.
  • The preparation command, docker stop ubuntu || :, stops a container named ubuntu if one is running and otherwise does nothing.
  • The benchmark command, docker run -it --rm ubuntu echo, starts an ubuntu container, runs echo, and removes the container.

Results for Docker Desktop v4.22#

First Attempt:

Terminal window
hyperfine -i -p 'docker stop ubuntu || :' 'docker run -it --rm ubuntu echo'
Terminal window
Benchmark 1: docker run -it --rm ubuntu echo
Time (mean ± σ): 44.3 ms ± 3.3 ms [User: 29.5 ms, System: 12.7 ms]
Range (min … max): 39.7 ms … 49.6 ms 10 runs
Warning: Ignoring non-zero exit code.

Second Attempt:

Terminal window
hyperfine -i -p 'docker stop ubuntu || :' 'docker run -it --rm ubuntu echo'
Terminal window
Benchmark 1: docker run -it --rm ubuntu echo
Time (mean ± σ): 46.3 ms ± 2.3 ms [User: 29.4 ms, System: 12.4 ms]
Range (min … max): 43.1 ms … 52.5 ms 28 runs
Warning: Ignoring non-zero exit code.

Third Attempt:

Terminal window
hyperfine -i -p 'docker stop ubuntu || :' 'docker run -it --rm ubuntu echo'
Terminal window
Benchmark 1: docker run -it --rm ubuntu echo
Time (mean ± σ): 46.5 ms ± 5.3 ms [User: 29.5 ms, System: 12.1 ms]
Range (min … max): 39.0 ms … 63.5 ms 28 runs
Warning: Ignoring non-zero exit code.

The first attempt averaged 44.3 milliseconds, give or take 3.3 milliseconds. So most runs landed between 41.0 and 47.6 milliseconds. Fastest was 39.7, slowest 49.6.

Second attempt: 46.3 milliseconds on average, deviation 2.3 milliseconds. Most runs sat between 44.0 and 48.6 milliseconds. The quickest hit 43.1, the longest 52.5.

Third attempt was noisier. Average 46.5 milliseconds, but the deviation jumped to 5.3 milliseconds. That spreads the bulk of runs across 41.2 to 51.8 milliseconds. They ranged from 39.0 all the way up to 63.5.

Results for Docker Desktop v4.11#

First Attempt:

Terminal window
hyperfine -i -p 'docker stop ubuntu || :' 'docker run -it --rm ubuntu echo'
Terminal window
Benchmark 1: docker run -it --rm ubuntu echo
Time (mean ± σ): 59.7 ms ± 3.2 ms [User: 36.4 ms, System: 15.6 ms]
Range (min … max): 55.0 ms … 68.3 ms 13 runs
Warning: Ignoring non-zero exit code.

Second Attempt:

Terminal window
hyperfine -i -p 'docker stop ubuntu || :' 'docker run -it --rm ubuntu echo'
Terminal window
Benchmark 1: docker run -it --rm ubuntu echo
Time (mean ± σ): 56.7 ms ± 2.7 ms [User: 36.3 ms, System: 15.3 ms]
Range (min … max): 51.7 ms … 62.5 ms 13 runs
Warning: Ignoring non-zero exit code.

Third Attempt:

Terminal window
hyperfine -i -p 'docker stop ubuntu || :' 'docker run -it --rm ubuntu echo'
Terminal window
Benchmark 1: docker run -it --rm ubuntu echo
Time (mean ± σ): 59.8 ms ± 4.5 ms [User: 36.4 ms, System: 15.3 ms]
Range (min … max): 51.2 ms … 69.5 ms 21 runs
Warning: Ignoring non-zero exit code.

Older version, slower numbers. First attempt averaged 59.7 milliseconds with a 3.2 millisecond deviation, so most runs fell between 56.5 and 62.9 milliseconds. Quickest was 55.0, longest 68.3.

Second attempt came in a bit better: 56.7 milliseconds on average, deviation 2.7 milliseconds. Most runs landed between 54.0 and 59.4 milliseconds. The spread ran from 51.7 to 62.5.

Third attempt averaged 59.8 milliseconds, deviation 4.5 milliseconds. Most runs were between 55.3 and 64.3 milliseconds. Fastest 51.2, slowest 69.5.

Final Results (Docker Desktop 4.11 vs 4.22)#

Docker Desktop v4.11Docker Desktop v4.22
First Attempt55.0 - 68.3 ms39.7 - 49.6 ms
Second Attempt51.7 - 62.5 ms43.1 - 52.5 ms
Third Attempt51.2 - 69.5 ms39.0 - 63.5 ms

Across the three attempts, 4.22 starts and tears down a trivial container roughly 10 to 15 milliseconds faster than 4.11 on the same machine. Those are Ajeet’s numbers; mine are in the rerun section at the end.

3. Resource efficiency#

Resource Saver arrived in 4.21 for CPU and in 4.22 for memory. It watches for the engine sitting idle with no containers for 30 seconds and then drops the VM’s footprint. Docker’s post puts the idle memory reduction at 10x. Source: Unleash Docker Desktop 4.22.

You can watch it happen: start Docker Desktop, run nothing for 30 seconds, and a leaf icon appears in the whale menu and the dashboard footer.

Docker Desktop dashboard footer showing "Engine running in Resource Saver mode", my own Docker Desktop v4.22.0

My own run on Docker Desktop v4.22.0.

Docker’s chart of total idle memory across 4.20, 4.21 and 4.22:

Total idle memory footprint in MiB versus Docker Desktop version, 4.20 to 4.22. Chart by Docker.

Source: Docker, Unleash Docker Desktop 4.22, David Scott, August 2023. Reproduced from the post.

4. File sharing with VirtioFS#

File sharing between the Mac and the Linux VM has been the sore spot of Docker Desktop for years. VirtioFS became the default on macOS 12.5 and later in 4.21, and Docker’s own figure for the effect is that a clean build of redis/redis checked out on the host went from seven minutes on 4.20 to about two minutes on 4.21. Source: Docker Desktop 4.21 release post.

The file-sharing mechanisms Docker Desktop has used#

Types of File Sharing Mechanism#

File Sharing MechanismDescriptionAdditional Notes
VirtioFSA native file sharing mechanism supported by Docker Desktop. It’s the fastest as it doesn’t need extra software.Default file-sharing mechanism in DD 4.22.
gRPC FUSEUses the gRPC protocol for file sharing. While slower than VirtioFS, it’s faster than other mechanisms.Default option in DD 2.4.0.0 (2020). Consumes less CPU than osxfs, especially with numerous file events on the host.
qemu-grpcfuseUses the qemu hypervisor for file sharing. It’s the slowest mechanism but viable for building Redis images.
hyperkit-grpcfuseEmploys the hyperkit hypervisor for file sharing. Its speed is comparable to qemu-grpcfuse.
osxfsA file system driver bridging macOS file system and the Linux-based system used by Docker containers.Default file-sharing mechanism in Docker for Mac 1.12.x.

Enable VirtioFS#

Open Docker Desktop settings, go to General, find “Choose file sharing implementation for your containers” and pick VirtioFS, then Apply & restart.

Docker Desktop v4.22.0 General settings with VirtioFS selected as the file sharing implementation, my own install

My own Docker Desktop v4.22.0.

A bind-mount throughput test#

The test below, and the two tables that follow it, are Ajeet Singh Raina’s. Source: Collabnix, “Unlocking High Performance with VirtioFS in Docker Desktop” (June 2023) for the 1 GB copy, and Collabnix, “Docker Desktop for Mac is no longer slow” for the 10 GB tables. The output is reproduced as published; the home directory in it is his, not mine.

Steps to Set Up and Test VirtioFS#

Create a directory using the command:

Terminal window
mkdir data

Populate the Directory with a Large Data File (1GB of random data) using the command:

Terminal window
dd if=/dev/zero of=data/data.img bs=1M count=1000

Next, let’s build the Docker Image using the command:

First, create a Dockerfile with the following content:

FROM ubuntu:latest
VOLUME /data
CMD ["bash"]

Then, build the Docker image using the command:

Terminal window
docker build -t virtiofs-demo:latest .

Run the Docker Container using the command:

Terminal window
docker run -it --rm -v "$(pwd)/data:/data" virtiofs-demo

List the Running Containers using the command:

Terminal window
docker ps

Expected output:

Terminal window
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e47eb4731c80 virtiofs-demo "bash" 5 minutes ago Up 5 minutes gifted_lichterman

Next, measure File Copy Time into the Container

Terminal window
time docker cp gifted_lichterman:/data/data.img data/data.img

Expected result:

Terminal window
Successfully copied 1.05GB to /Users/ajeetsraina/july/virt/data/data.img
docker cp gifted_lichterman:/data/data.img data/data.img 0.61s user 1.84s system 36% cpu 6.750 total

Performance Comparison#

Comparing Docker Desktop 4.22 vs 4.11 (without VirtioFS enabled)

Data Size: 10GB Data TransferDocker Desktop v4.11Docker Desktop v4.22
Run #17 min 13.21 s5 min 11.10 s
Run #26 min 47.89 s5 min 04.08 s
Run #37 min 04.75 s5 min 02.08 s

Comparing Docker Desktop 4.22 vs 4.11 (with VirtioFS enabled)

Data Size: 10GB Data TransferDocker Desktop v4.11Docker Desktop v4.22
Run #12 min 18.55 s1 min 04.44 s
Run #22 min 20.23 s1 min 06.21 s
Run #32 min 15.65 s1 min 05.39 s

Docker’s Redis build chart#

redis/redis build time in minutes versus Docker Desktop version: 4.13 default, 4.20 default, 4.21 default with VirtioFS. Chart by Docker.

Source: Docker, Unleash Docker Desktop 4.22, David Scott, August 2023. Reproduced from the post.

The earlier version of this post also carried a Redis build table across four file-sharing modes and a pgbench comparison. I could not find a public source for either, so both are gone.

5. Container networking#

The big networking change of the year was 4.19 swapping VPNKit for the TCP/IP stack from the gVisor project on container-to-host traffic. Docker’s statement for that release is that container-to-host networking on macOS became 5x faster. Source: Docker Desktop 4.19 release post, May 2023. The August write-up adds an iperf3 figure on a first-generation M1 Mac mini: about 3.5 Gbit/s on the old stack against 19 Gbit/s on 4.19 and later. Source: Unleash Docker Desktop 4.22.

NOTE

In Docker Desktop 4.19, container-to-host networking performance was boosted by 5x on macOS, achieved by replacing vpnkit with the TCP/IP stack from the gVisor project.

If your containers reach out to external servers, npm install or apt-get pulling packages for instance, this is the speed-up you feel first.

To check which networking stack Docker Desktop is using:

Terminal window
cat ~/Library/Group\ Containers/group.com.docker/settings.json | grep -i network

If you need VPNKit back, add "networkType":"vpnkit" to that file.

The earlier version of this post carried iperf3 scripts and per-platform throughput tables. They were not mine and I could not find their public source, so they are removed rather than attributed.

6. Apple Silicon and Rosetta#

Docker Desktop can run amd64 images on Apple Silicon through Rosetta instead of QEMU, which closes much of the gap between Intel and Apple Silicon machines for images that have no arm64 build. The toggle lives under Features in development in 4.22.

Docker Desktop v4.22.0 Features in development, "Use Rosetta for x86/amd64 emulation on Apple Silicon" enabled, my own install

My own Docker Desktop v4.22.0.

With it on, you can drop the explicit platform flag from commands like:

Terminal window
docker run --platform=linux/amd64

What this means in practice#

Every 2023 release chipped at the same problem: the gap between running a container on your laptop and running it the way production does. On macOS, the gVisor networking switch alone justifies the upgrade from anything before 4.19, and VirtioFS as the default makes bind-mounted builds usable again. Those are Docker’s claims and Ajeet’s measurements, not mine, and the next section is where my own numbers go.

My 2026 rerun#

Three years on, I reran the commands above on my own machine so that this post carries at least one set of numbers that are mine. Raw outputs, the scripts, and every adaptation are published at /benchmarks/docker-desktop-2026-10/.

Machine: Apple M4 Pro, 14 cores, 48 GiB, macOS 26.5.2. Docker Desktop 4.90.0 (engine 29.7.2, Linux kernel 7.0.12-linuxkit, aarch64), VM at 14 CPUs and 7.7 GiB. File-sharing implementation: VirtioFS (a bind mount inside a container reports type virtiofs); the mode was not switched during the run. A five-container Compose stack was running throughout. Each benchmark ran three times; the table gives the median and the range. The hardware and the Docker Desktop versions differ from everything measured in 2023, so the comparison shows direction, not a like-for-like regression test.

BenchmarkMy result, October 2026The 2023 figure it sits next to
Container start, hyperfine … 'docker run -it --rm ubuntu echo'16.2 ms mean (15.9–16.5 ms; 13.4–24.6 ms across 68–81 runs each)44.3–46.5 ms on 4.22, 56.7–59.8 ms on 4.11 (Ajeet Singh Raina, Collabnix)
docker cp of a 1 GB file from a bind-mounted directory5.27 s (5.24–5.32 s)6.75 s on 4.22 (Ajeet Singh Raina, Collabnix)
docker cp of a 10 GB file, same setup54.2 s (52.9–54.6 s)1 min 04–06 s with VirtioFS on 4.22 (Ajeet Singh Raina, Collabnix)
Redis clean build over a bind mount, time make in ubuntu1 min 52.6 s (1 min 51.6 – 1 min 53.1 s)about two minutes on 4.21, seven on 4.20 (Docker, 4.21 release post)
pgbench, scale 10, 10 clients × 10 transactions, PostgreSQL 18.68,470 tps (8,313–8,635)no sourced 2023 figure
iperf3 container → container95.6 Gbit/s (95.0–96.4)no sourced 2023 figure
iperf3 container → host8.73 Gbit/s (8.71–8.74)19 Gbit/s on an M1 Mac mini (Docker, “Unleash Docker Desktop 4.22”); Docker’s post states neither the iperf3 parameters nor the direction, so the two numbers were not measured the same way
iperf3 host → container, published port10.5 Gbit/s (10.4–10.6)no sourced 2023 figure
Engine restart, docker desktop stop then start to first docker info2.27 s (2.24–2.37 s)“four seconds on Apple Silicon” (Docker, 4.21 release post)

What had to change to run this in 2026: the iperf3 image is networkstatic/iperf3, since Docker’s internal dockerpinata/iperf3:2.1 is not public; postgres:alpine now resolves to PostgreSQL 18, which refuses a data volume at /var/lib/postgresql/data, so the volume sits at /var/lib/postgresql and the client runs from the server image; the Redis clone lives under my home directory rather than /tmp; startup is timed from docker desktop start to the first successful docker info because the 2023 table named no method.


Vladimir Mikhalev

Docker Captain  ·  IBM Champion  ·  AWS Community Builder

The Verdict — production-tested analysis on YouTube.

The Verdict

Inconvenient truths about shipping in the AI era

Container security, platform engineering, and the agentic shift — tested in production, argued without the hype. The verdict reaches your inbox the moment there's one worth sending.

Related Posts

Same category
  1. 1
    Merge Debt: The 2026 Bill Your Parallel AI Agents Are Running Up
    Opinion & Culture · Three agents finish in parallel. Main takes one landing at a time. METR's perception gap, the rebase tax, and why Merge Debt is the number nobody plots.
  2. 2
    Your Knowledge Is a Depreciating Asset. Judgment Compounds.
    Opinion & Culture · AI made reproducible knowledge free, so technical expertise is now a depreciating asset. Judgment is the one that compounds. Here is how to move your weight.
  3. 3
    The Senior Engineer Signal: The 2026 Risk Your Velocity Metrics Hide
    Opinion & Culture · Juniors get the biggest boost from AI; seniors trust it least. That split is your earliest read on engineering risk, and on the talent you're about to lose.
  4. 4
    Agent Sprawl: The 2026 Engineering Risk Your Auditor Hasn't Named Yet
    Opinion & Culture · Unknown numbers of AI coding agents run in parallel — no audit trail, no isolation, no per-team measurement. By 2026 that's an audit finding.

Random Posts

Random
  1. 1
    Agent Sprawl: The 2026 Engineering Risk Your Auditor Hasn't Named Yet
    Opinion & Culture · Unknown numbers of AI coding agents run in parallel — no audit trail, no isolation, no per-team measurement. By 2026 that's an audit finding.
  2. 2
    Amazon Project Dawn Cut 30,000 Jobs — Including the Head of AWS Community Builders. Here's What It Means.
    Opinion & Culture · Amazon laid off Jason Dunn, architect of the AWS Community Builders program. The signal: community must prove production value, not engagement metrics.
  3. 3
    watsonx.governance Enforcement Tracking — Sampled Compliance and the Unevidenced Run
    AI & MLOps · EU AI Act Article 12 wants a per-event record. Enforcement Tracking evidences thresholds on a schedule. What that gap costs, and the join key that closes it.
  4. 4
    Top 10 DevOps Tools for 2025 — Must-Have for Developers and Engineers
    DevOps & Cloud · Explore the top 10 DevOps tools for 2025 to optimize workflows, enhance security, and streamline CI/CD, GitOps, and Kubernetes.
Docker Desktop's Performance Odyssey Over a Year of Innovations
https://heyvaldemar.com/docker-desktops-performance-odyssey-over-a-year-of-innovations/
Author
Vladimir Mikhalev
Published
2023-08-16
Updated
2026-10-11
License
CC BY-NC-SA 4.0