2230 words
11 min read

Docker Desktop's Performance Odyssey Over a Year of Innovations

By · Solutions Architect · Docker Captain · IBM Champion
Docker Desktop performance benchmark dashboard displayed on MacBook Pro workstation

Docker Desktop changed a lot over the past year. Most of it lands where you feel it day to day: startup time, file-sharing throughput, container-to-host networking. A slow Docker Desktop means more waiting and more context-switching while you work.

So I went through a year of releases and ran the benchmarks myself. Then I pulled out the changes that actually moved the numbers. Here’s what shifted, and by how much.

2023: Docker Desktop’s Performance Revolution#

The 2023 releases are more than a version bump. Here’s what changed, area by area.

1. Docker Daemon Startup Time#

Startup got noticeably faster this year. Some configurations now initialize in just over 5 seconds. You get into your containers without sitting around for the daemon.

Mac amd64Mac arm64Win amd64Linux amd64
Time7.84 s5.24 s19.1 s9.50 s

2. Container Operations with Hyperfine#

I benchmarked Docker across versions with hyperfine. v4.22 beats v4.11 every time. Container operations got faster, plain and simple.

To install Hyperfine you can use the command:

Terminal window
brew install hyperfine

Using the hyperfine Tool#

To benchmark Docker commands, we’ll use the hyperfine tool. Here’s how you can execute it:

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

What the flags do:

  • -i lets hyperfine run the benchmark in interactive mode, so you see results as they come in.

  • -p sets the warmup and benchmark commands for hyperfine.

  • The warmup command, docker stop ubuntu || :, tells Docker to stop the ubuntu container if it’s running. If it isn’t, it just moves on.

  • The benchmark command, docker run -it --rm ubuntu echo, starts the ubuntu container interactively and prints the current date and time.

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

3. Resource Efficiency#

The new Resource Saver is a real win. It watches what Docker is doing and trims usage down to what’s actually needed. Your Mac stays responsive even when the workload spikes.

Want to see it work? Start Docker Desktop and leave it idle for 30 seconds with no containers running. An icon shows up in the whale menu and in the dashboard sidebar. That’s Resource Saver kicking in.

Docker Desktop's Performance Odyssey Over a Year of Innovations - Step 1

Resource Saver tracks container activity. If Docker Desktop sits idle with nothing running for 30 seconds, it drops its memory and CPU usage on its own.

The chart below shows what Resource Saver does to the memory footprint of all Docker Desktop processes. I measured it with the footprint CLI command, which collects memory data for a process or a group of processes.

Docker Desktop's Performance Odyssey Over a Year of Innovations - Step 2

4.1 File Sharing with VirtioFS#

File sharing has always been the sore spot in containerized development. VirtioFS changes that. File I/O is much faster now. Builds finish sooner, data moves quicker, and the whole loop feels less sluggish.

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 and go to the “General” tab. Find “Choose file sharing implementation for your containers” and pick “VirtioFS”. Then click “Apply & Restart”.

Docker Desktop's Performance Odyssey Over a Year of Innovations - Step 3

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

4.2 Evaluating Docker Desktop’s File-Sharing Performance#

Every upgrade is partly about performance. With Docker Desktop, moving between versions isn’t only new features. It’s also tightening what’s already there. The switch from VPNKit to gVisor mattered here. Container-to-host networking on macOS got up to 5x faster, so the things that used to crawl, like package downloads, move quickly now.

In this part I measure how long it takes to build a Redis image from source using Docker Desktop’s file sharing. The source comes in over a bind mount. I time the build inside the container.

Redis Build Process#

Terminal window
# !/bin/bash
rm -rf /tmp/redis
docker run --rm -v /tmp:/tmp alpine sh -c \
'cd /tmp ; apk add git ; git clone https://github.com/redis/redis --depth 1'
docker run --rm -v /tmp/redis:/tmp/redis ubuntu bash -c \
'cd /tmp/redis ; apt update && apt install -y make gcc ; make distclean && time make'

Redis Build Performance#

ParameterVirtioFSgRPC FUSEqemu-grpcfusehyperkit-grpcfuse
Redis Build2.78 min3.54 min6.68 min5.19 min

Docker Desktop's Performance Odyssey Over a Year of Innovations - Step 4

Postgres Build Process#

First, the setup. The script below creates a Postgres network, starts a server, and fires off a pgbench client.

Terminal window
# !/bin/bash
IMG=postgres:alpine
NET=postgresnet
TESTDIR=/tmp/postgrestest/data
PGNAME=postgrestest
PGPASS=postgrespass
docker network rm -q $NET &>/dev/null
echo "Setting up postgres network..."
docker network create $NET
rm -rf $TESTDIR
mkdir -p $TESTDIR
echo "Initiating postgres server..."
docker run --name=${PGNAME} -e POSTGRES_PASSWORD=postgrespass --network ${NET} -p 5432:5432 -v ${TESTDIR}:/var/lib/postgresql/data -d ${IMG}
echo "Launching postgres pgbench client..."
docker run --network ${NET} alpine sh -c \
'apk add postgresql ; export PGPASSWORD=postgrespass; \
pgbench --host=postgrestest -U postgres -i -s 10 postgres ; \
pgbench --host=postgrestest -U postgres -c 10 -t 10 postgres'
docker stop ${PGNAME} &>/dev/null
docker rm ${PGNAME} &>/dev/null
docker network rm -q $NET &>/dev/null

Postgres Build Performance#

Scenario4.11.14.22
Postgresql tps (transactions/s)1000 tps2600 tps

Version 4.22 leaves 4.11.1 behind on transactions per second. It hits 2600 tps, more than double the 1000 tps the older build managed.

The file-sharing mechanism you pick really moves build times. For something like a Redis build, VirtioFS is the one to use.

Postgres transactions also improved a lot in 4.22, which points to real work under the hood in this release.

VirtioFS wins on Redis builds, but pick your mechanism around the project. Compatibility and your specific needs come first.

That jump in Postgres throughput from 4.11.1 to 4.22 is the kind of thing that makes the upgrade pay for itself.

5. Container Networking Enhancements#

The 2023 updates leaned hard on networking, especially on macOS. Containers talk to each other more smoothly now. Data moves faster, latency drops, and the whole setup runs tighter.

The big change was swapping VPNKit for gVisor on container-to-host networking. That landed in Docker Desktop 4.19, released in March 2023.

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.

gVisor is a lightweight, sandboxed container runtime that runs in user space. It’s built on the Linux kernel but implemented in user space, which gives it an edge over VPNKit, a kernel-based solution.

If your containers reach out to external servers, say npm install or apt-get pulling packages, this speedup pays off immediately.

Enabling gVisor#

To check that Docker Desktop is on gVisor by default, run:

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

If you want VPNKit back, add “networkType”:“vpnkit” to your settings.json file.

Why gVisor over VPNKit:

  • Performance: gVisor is faster than VPNKit, so containers run quicker.
  • Security: It’s sandboxed, which means better protection against vulnerabilities.
  • Resource Efficiency: It uses fewer resources than VPNKit, so your Mac has more to spare.

Networking Benchmarks#

Container to Container

Benchmarking Tool: iperf3/netperf

Terminal window
# !/bin/bash
IMG=dockerpinata/iperf3:2.1
NET=iperf3net
SERVER=iperf3server
CLIENT=iperf3client
docker rm -f $SERVER &>/dev/null
docker network rm -q $NET &>/dev/null
echo "Creating iperf3 network..."
docker network create $NET
echo "Starting iperf3 server..."
docker run --rm -d --name=${SERVER} --network=${NET} ${IMG} /usr/bin/iperf3 -s -1
echo "Starting iperf3 client..."
docker run --rm --name=${CLIENT} --network=${NET} ${IMG} /usr/bin/iperf3 -c ${SERVER}
docker rm -f $SERVER &>/dev/null
docker network rm -q $NET &>/dev/null
PlatformSpeed
Mac amd6441.5 Gb/s
Mac arm6481.7 Gb/s
Win amd6446.1 Gb/s
Linux amd6456.3 Gb/s

Container to Host

Benchmarking Tool: iperf3/netperf

Terminal window
# !/bin/bash
IMG=dockerpinata/iperf3:2.1
# This can be used to remove previous hanging iperf3 servers
# pkill iperf3
echo "Starting iperf3 server..."
iperf3 -s -1 &
IPERF3_SERVER_PID=$!
echo "Starting iperf3 client..."
docker run --rm ${IMG} /usr/bin/iperf3 -c host.docker.internal
kill $IPERF3_SERVER_PID &>/dev/null
PlatformSpeed
Mac amd64686 Mb/s
Mac arm641.50 Gb/s
Win amd64596 Mb/s
Linux amd641.62 Gb/s

Host to Container

Benchmarking Tool: iperf3/netperf

Terminal window
# !/bin/bash
IMG=dockerpinata/iperf3:2.1
SERVER=iperf3server
docker rm -f $SERVER &>/dev/null
echo "Starting iperf3 server..."
docker run --rm -d -p 5201:5201 --name=${SERVER} ${IMG} /usr/bin/iperf3 -s -1
echo "Starting iperf3 client..."
iperf3 -c localhost
docker rm -f $SERVER &>/dev/null
Scenario4.11.14.22
Container to Container60 Gb/s72 Gb/s
Host to Container420 Mb/s1.4 Gb/s
Container to Host/internet930 Mb/s18 Gb/s

6. Hardware Compatibility: Embracing Apple Silicon and Rosetta#

Docker added a Rosetta feature, and it’s a smart move. It closes the gap between Intel and Apple Silicon, so you get the same experience whatever hardware you’re on.

Docker Desktop's Performance Odyssey Over a Year of Innovations - Step 5

That means you can drop this command:

Terminal window
docker run --platform=linux/amd64

Like with VirtioFS, Rosetta brought speedups too. Someone in our community clocked a 7x boost, most of it on a DB migration that used to crawl.

What this means in practice#

Every release this year 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. It brought up to 5x faster container-to-host networking.

Still on an older version? The gap isn’t cosmetic anymore. You can read it in the build and startup numbers above. Update, push your own workload through it, and compare against what you had before.

Happy coding, and until next time, keep containerizing!


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
    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.
  2. 2
    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.
  3. 3
    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.
  4. 4
    I Tested an AI Agent on My Live Systems. Here Is the Blast Radius Assessment Every Engineer Is Skipping.
    Opinion & Culture · Everyone is buying Mac Minis and installing AI agents. I tested one in isolation. Here is the architectural framework for deployment that the Instagram hype does not include.

Random Posts

Random
  1. 1
    Configure AWS CLI
    DevOps & Cloud · Learn how to configure AWS CLI with IAM credentials. Step-by-step guide for setting up secure access, managing keys, and running AWS commands via terminal.
  2. 2
    Configure Exchange Server 2010
    SysAdmin & IT Pro · Complete guide to configuring Exchange Server 2010. Learn mailbox setup, certificates, DNS, email policies, and secure mail delivery—step by step.
  3. 3
    I Tested an AI Agent on My Live Systems. Here Is the Blast Radius Assessment Every Engineer Is Skipping.
    Opinion & Culture · Everyone is buying Mac Minis and installing AI agents. I tested one in isolation. Here is the architectural framework for deployment that the Instagram hype does not include.
  4. 4
    DevOps and Platform Engineering Dynamics
    DevOps & Cloud · Explore the comprehensive impact of DevOps and Platform Engineering on software development, detailing key strategies, technological innovations, and future trends shaping the industry.
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
License
CC BY-NC-SA 4.0