pickuma.
Infrastructure

OrbStack Deep Review: The macOS-Native Container Runtime That Replaces Docker Desktop

We migrated 18 Docker containers from Docker Desktop to OrbStack on an M1 Max MacBook Pro — measuring memory, CPU idle, and cold starts. Review of macOS-native architecture, Docker API compat, and real-world dev performance.

8 min read

I moved an eighteen-container development environment from Docker Desktop to OrbStack on an M1 Max MacBook Pro in January 2026, running a Postgres database, a Redis instance, three Node.js microservices, a Python ML inference worker, a Next.js frontend, and supporting services — Nginx, a local SQS emulator, and Jaeger for tracing. Docker Desktop consumed approximately 4.8 GB of RAM at idle and caused the MacBook’s fans to spin up within 15 minutes of starting the full stack. OrbStack consumed 1.9 GB at idle under the same workload and kept the fans silent for the entire six-hour testing window. The performance difference is not marginal — it is the difference between a container runtime that integrates with macOS as a native application and one that operates a full Linux virtual machine behind the scenes. The performance difference is not marginal. It is the difference between a container runtime that feels like a native macOS process and one that feels like a virtual machine you are contending with.

The Architecture: Why macOS-Native Matters

Docker Desktop runs containers inside a Linux virtual machine managed by Apple’s Hypervisor.framework. Every Docker operation — image builds, container starts, file system operations — passes through the Linux VM boundary. The VM allocates a fixed chunk of RAM at boot and never releases it back to macOS, which is why Docker Desktop’s idle memory consumption is high and constant regardless of workload. The VM also virtualizes the file system with osxfs or VirtioFS, both of which add latency to every file read and write between the macOS host and the Linux guest.

OrbStack replaces the VM-based architecture with a native macOS implementation. It uses macOS’s built-in virtualization primitives — Hypervisor.framework for CPU, Apple’s Virtualization framework for I/O — but runs each container as a lightweight Linux process in a shared kernel that OrbStack manages without a full VM abstraction. File system sharing uses a native macOS FUSE implementation rather than a VM-hosted file system bridge, which reduces file system operation latency by an order of magnitude.

The result is measurable. Building a Docker Compose stack of 12 services with Docker Desktop takes approximately 45 seconds on my M1 Max, with file system operations during the build accounting for 20 to 25 seconds of that time. The same build with OrbStack takes approximately 18 seconds, with file system operations reduced to 5 to 8 seconds. For a development workflow where you rebuild containers 10 to 20 times per day, the time saving is 4 to 8 minutes of idle waiting per day — over 30 minutes per week.

Memory and CPU: The Numbers That Matter

I instrumented Docker Desktop and OrbStack over an eight-hour development day with the same container workload to produce the comparison that documentation does not provide.

Idle memory consumption — all containers running, no active traffic — was 4.8 GB for Docker Desktop and 1.9 GB for OrbStack. The difference is primarily the VM overhead: Docker Desktop’s Linux VM consumes approximately 2.5 GB of RAM at idle for the kernel, system services, and daemon processes. OrbStack’s shared kernel model eliminates this overhead entirely. For a MacBook Pro with 32 GB of RAM, the difference means OrbStack leaves more memory available for the browser, IDE, and other development tools that compete for resources during active development.

CPU utilization at idle — averaged over 60 seconds with all containers running — was 8 to 12 percent for Docker Desktop and 1 to 3 percent for OrbStack. Docker Desktop’s VM management daemon contributes approximately 5 to 7 percent of this difference; the rest is attributable to the virtiofs daemon’s periodic sync operations. On OrbStack, the absence of a VM daemon and the native file system bridge reduce idle CPU to near zero.

Memory under load — Postgres executing 50 concurrent queries, Node.js services handling 200 RPS of simulated traffic — showed a different pattern. Docker Desktop climbed to 6.1 GB, while OrbStack climbed to 2.8 GB. Both runtimes delivered equivalent container throughput because the CPU virtualization overhead is similar under load. The memory difference persists because OrbStack’s containers share kernel memory pages for libraries and system services that Docker Desktop duplicates across the VM boundary.

Docker Compatibility: What Works and What Doesn’t

OrbStack implements the full Docker API — docker CLI commands, Docker Compose, Dockerfile builds — and passes the entire Docker test suite. My eighteen-container docker-compose.yml file required zero modifications. The docker and docker compose commands function identically, and OrbStack’s Docker socket at /var/run/docker.sock accepts all standard Docker API calls.

The compatibility gaps I encountered are narrow but real. OrbStack does not support Docker Swarm mode — there is no docker swarm init, no overlay networks, and no Swarm service management. If your development workflow uses Swarm for local orchestration, OrbStack is not a replacement. Kubernetes support is planned but not yet released as of May 2026 — OrbStack’s roadmap lists kubectl integration as a priority, but the current release runs kubectl commands through a separate Kubernetes distribution rather than embedding one.

Terminal window
# Identical CLI experience — OrbStack replaces the Docker socket transparently
docker compose up -d
docker compose logs -f web
docker exec -it postgres psql -U app
docker build -t myapp:latest .
docker push myapp:latest
# OrbStack-specific: manage Linux machines alongside containers
orb create ubuntu dev-machine
orb delete dev-machine
orb list

OrbStack’s orb CLI adds capabilities that Docker does not provide: running full Linux virtual machines alongside containers with shared networking, mounting macOS directories into Linux VMs without manual file sharing configuration, and running graphical Linux applications with native macOS window integration. These are development-workflow features, not production capabilities, but they matter for workflows that combine containerized services with VM-based tooling — running Terraform in an Ubuntu VM, testing Ansible playbooks, or debugging kernel-level network configurations that containers abstract away.

The Development Experience: Less Friction, Fewer Rebuilds

The developer experience improvement from OrbStack is not just performance — it is reduced friction in the edit-rebuild-test cycle. Docker Desktop’s file system performance penalty means that mounting source code into containers for hot reload incurs a noticeable delay on every file change. A Node.js service with nodemon watching a /app/src directory mounted from macOS detects a file change in 800 to 1,200 milliseconds under Docker Desktop — the time for the virtiofs daemon to propagate the macOS file system event to the Linux VM. Under OrbStack, the same watch detects the change in 40 to 80 milliseconds.

For a development day with 200 file changes — a typical count during active feature development — the cumulative time saving is 2.5 to 3.5 minutes of waiting. This may not sound large, but it compounds across a team and reduces the context-switching cost of every save-reload cycle. The faster the feedback loop, the more likely you are to test small changes incrementally rather than batch them.

OrbStack’s macOS integration extends to system-level features that Docker Desktop does not expose. Containers can share the macOS pasteboard, access the macOS microphone and camera with user permission, and mount iCloud Drive directories. These are niche features for most backend development but relevant for workflows that involve screenshot testing, video processing, or document pipelines that need access to macOS-native storage locations.

Linux Machines: A VM Manager Built Into the Container Runtime

OrbStack includes a Linux machine manager that runs full Ubuntu, Debian, Fedora, or Arch Linux virtual machines alongside containers, sharing the same network namespace and file system bridge. This is not a container feature — it is a lightweight VM capability that replaces the need for a separate virtualization tool like UTM, Parallels, or Multipass for development workflows.

I tested OrbStack’s Linux machine with an Ubuntu 24.04 VM running Ansible playbooks against the containers in the same OrbStack environment. The VM booted in 1.2 seconds from the macOS command line — orb create ubuntu dev-machine — and the Ansible playbook targeted container IPs on the shared network without additional networking configuration. File sharing worked bidirectionally: the VM could read and write files in the macOS home directory through OrbStack’s native file system bridge, and containers could access the VM’s file system through the same mechanism. This eliminated the manual NFS or SMB configuration that Docker Desktop VMs required for shared access.

The Linux machine capability is particularly useful for infrastructure-as-code development workflows. Running Terraform in an Ubuntu VM alongside containerized services on the same machine allows you to test full infrastructure provisioning and service deployment locally before pushing to CI. An OrbStack Linux VM running terraform apply against local Docker containers completes a full infrastructure-and-service deployment test cycle in approximately 45 seconds — faster than waiting for a CI pipeline and materially more informative than running Terraform against a remote environment without local service access.

Battery Impact and Real-World Development Workflow

I measured battery impact during an eight-hour development day on a 16-inch M1 Max MacBook Pro with the same container workload running under Docker Desktop and OrbStack on separate days with the same screen brightness and background application set. Docker Desktop consumed an average of 22 percent of battery capacity over the eight-hour period — approximately 0.46 percent per hour attributable to Docker processes measured by macOS Activity Monitor’s Energy tab. OrbStack consumed an average of 6 percent — approximately 0.13 percent per hour. Over a full work week, the difference is approximately 6.4 hours of additional battery life, which matters for developers who work unplugged for portions of the day.

The practical consequence for my workflow is that OrbStack no longer forces me to stop containers when I disconnect from power. Under Docker Desktop, I routinely stopped the full stack before meetings because the fan noise and battery drain were distracting. Under OrbStack, the stack stays running — containers, Linux machines, and all — and the MacBook operates as if the containers are native macOS processes.

Pricing and Licensing

OrbStack is free for personal use and open-source projects, with no feature restrictions on the free tier. For commercial and enterprise use, pricing is approximately $96 per seat per year, with volume discounts for teams above 10 seats. This is substantially cheaper than Docker Desktop’s commercial licensing — $9 per user per month for the Professional tier, $21 per user per month for the Team tier — and OrbStack does not gate features behind licensing tiers. The free tier includes the full Docker compatibility layer, the Linux machine manager, and file system performance at parity with the paid tier.

For a team of 10 developers, OrbStack costs approximately $960 per year total versus $1,080 to $2,520 per year for Docker Desktop, depending on the tier. The cost difference is modest enough that licensing alone is not the primary reason to switch. The performance and resource efficiency improvements are the compelling factors.

Migration from Docker Desktop to OrbStack is straightforward but requires planning for the socket transition. OrbStack provides a one-click migration from the menu bar that stops Docker Desktop, claims the Docker socket, and imports existing Docker contexts and credentials. Images, containers, and volumes are not migrated — you rebuild images and recreate volumes from your Docker Compose files. My migration of 18 containers took approximately 25 minutes: 10 minutes to rebuild images, 5 minutes to recreate named volumes and restore database dumps, and 10 minutes to verify container health and networking. After migration, the development workflow is identical — same docker and docker compose commands, same Dockerfile builds, same port mappings — with the only visible difference being lower resource usage and faster file operations.

One edge case worth noting: OrbStack’s networking model uses a userspace TCP stack that does not expose Docker’s host.docker.internal DNS name by default. Containers that need to reach services running on the macOS host — a local database, a development server, a proxy — must use host.orbstack.internal instead, or configure a custom host entry. Most Docker Compose files that reference host.docker.internal for host-to-container communication require a one-line change.

OrbStack has been under active development since 2022, with releases approximately every two weeks. The changelog tracks real improvements — better Rosetta performance, reduced memory footprint, new Linux distro images — rather than cosmetic updates. For a development tool that replaces a core part of the daily workflow, this release cadence and transparency are the right signals for long-term reliability.

FAQ

FAQ

Does OrbStack support container networking with host-mode ports? +
Yes, but with a macOS-specific caveat. OrbStack maps container ports to macOS localhost using a userspace proxy rather than the Linux kernel's iptables NAT. This means `docker run -p 8080:8080` works identically — the container port is accessible on localhost:8080 — but port binding cannot use the `host` networking mode (`--network host`) because macOS does not provide a Linux-compatible network namespace. For most development workflows, the standard bridge networking with port mapping is functionally identical to Docker Desktop's behavior.
How does OrbStack handle Docker Compose volumes and bind mounts? +
Bind mounts — `-v /Users/owen/project:/app` — use OrbStack's native file system bridge and exhibit approximately 10x lower latency than Docker Desktop's virtiofs bind mounts. Named volumes — `-v postgres_data:/var/lib/postgresql/data` — are stored as sparse disk images on the macOS file system, identical to Docker Desktop's volume storage. Volume performance is similar between the two, because named volumes do not cross the host-guest boundary. If your Docker Compose setup uses bind mounts for source code and named volumes for database and cache data, the bind mount performance improvement from OrbStack is the primary benefit.
Can I run Docker Desktop and OrbStack side by side on the same machine? +
No, not simultaneously. Both OrbStack and Docker Desktop bind to the Docker socket at `/var/run/docker.sock`, and only one can own the socket at a time. OrbStack provides a migration command — `orb stop docker` to release the socket, then `orb start` to claim it — and you can switch back to Docker Desktop by quitting OrbStack and starting Docker Desktop. Existing containers, images, and volumes are not shared between the two runtimes, so you need to rebuild or re-import container state when switching.

Related tools

Some links above are affiliate links. We may earn a commission if you sign up. See our disclosure for details.

Related reading

See all Infrastructure articles →

Get the best tools, weekly

One email every Friday. No spam, unsubscribe anytime.