Repository navigation
[Windows] Docker VMM: com.docker.sailor.exe holds ~15 GB host memory with a 4 GiB VM and does not return it under sustained memory pressure #724
Description
Bug description
With Docker Desktop 4.93.0 (240920) on Windows using the Docker VMM backend (engine linux/sailor), the VMM process com.docker.sailor.exe holds ~15 GB of host working set, while the Docker VM is configured with only 4 GiB of RAM and the containers inside use ~1.5 GiB.
The memory is never returned to the host, even though the VMM itself detects sustained host memory pressure and continuously tries to reclaim. Its reclaim action only signals the guest to drop page caches, which frees almost nothing (the guest already has ~1.9 GiB free and only ~0.8 GiB of page cache). Only restarting Docker Desktop releases the memory; it then grows back to ~15 GB over several hours of normal use.
The docs state Docker VMM "Returns idle memory to the host when containers aren't active" (https://docs.docker.com/desktop/features/vmm/), so this looks like a bug in the host-side memory reclaim on Windows.
Snapshot (2026-10-04 11:18 local; VMM process started 2026-10-04 01:32)
com.docker.sailor.exe:
- Working set: 14,541 MB (observed range over the day: 14,379–16,919 MB)
- Working set - private: 3,079 MB
- Private bytes (commit): 4,454 MB
- The remainder (~11.5 GB) is shareable working set and is not guest RAM: the VM reports 4,167,532 kB total with
MemFree~1.9 GB andCached~0.8 GB.
Host (32 GB RAM, NVMe SSD):
- Available memory: ~358 MB
- Commit: 51.3 / 63.8 GB
- Pagefile usage: ~5.9 GB
- Sustained hard page faults: ~2,170 pages/s (
\Memory\Pages Input/sec), while disks are otherwise idle (6.6% disk time)
VM / containers:
- VM: 4 GiB RAM (
MemoryMiB=4096), 16 vCPU clickhouse/clickhouse-server: ~1.0 GiBpostgres:17-alpine: ~0.5 GiB- Containers are idle most of the time
Evidence from Docker's own host log
%LOCALAPPDATA%\Docker\log\host\monitor.log* contains 3,676 lines between 2026-10-03 16:07 and 2026-10-04 11:18 local time (roughly one every ~10 s while pressure is active, alternating info/warning):
[2026-10-03T08:07:02.632509100Z] {"component":"sailor","level":"warning","msg":"host memory pressure: signalled guest drop-caches","target":"drop_caches_host","time":"2026-10-03T16:07:02.632509100+08:00"}
[2026-10-04T03:18:21.429501900Z] {"component":"sailor","level":"info","msg":"host memory pressure: signalled guest drop-caches","target":"drop_caches_host","time":"2026-10-04T11:18:21.428746200+08:00"}
The VMM sees the pressure and keeps reclaiming, but the reclaim only reaches guest page cache while ~11.5 GB of host-side shareable working set is left untouched.
Impact
Host available memory drops to a few hundred MB and the machine hard-faults continuously, noticeably slowing down daily work. docker desktop restart fixes it temporarily. There is no user-facing setting to bound this host-side memory.
Reproduction steps
- Windows 10 x64 (build 26300), Docker Desktop 4.93.0, VMM backend selected (Settings > General > Virtual Machine Manager), VM memory at the 4 GiB minimum, 16 CPUs.
- Start a couple of long-running containers (e.g. ClickHouse + Postgres) and use Docker normally for a few hours, on a host under moderate memory pressure (IDEs + browser using most of 32 GB).
- Watch
com.docker.sailor.exein Task Manager (Details) and%LOCALAPPDATA%\Docker\log\host\monitor.log. - The process working set grows to ~15 GB (≈4x the configured VM RAM) and does not shrink despite sustained host memory pressure; the log fills with "host memory pressure: signalled guest drop-caches".
docker desktop restartreleases the memory; it regrows over hours.
Platform
Windows
Version information
docker version:
Client:
Version: 29.8.1
API version: 1.56
Go version: go1.26.8
Git commit: 4a63305
Built: Tue Sep 15 16:28:39 2026
OS/Arch: windows/amd64
Context: desktop-linux
Server: Docker Desktop 4.93.0 (240920)
Engine:
Version: 29.8.1
API version: 1.56 (minimum version 1.40)
Go version: go1.26.8
Git commit: 464cd50
Built: Tue Sep 15 16:25:38 2026
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: v2.3.5
runc:
Version: v1.5.1
docker info (server, trimmed):
Server Version: 29.8.1
Storage Driver: overlayfs
driver-type: io.containerd.snapshotter.v1
Logging Driver: json-file
Cgroup Driver: cgroupfs
Cgroup Version: 2
Kernel Version: 7.0.14-linuxkit [engine: linux/sailor — Docker VMM Beta]
Operating System: Docker Desktop
OSType: linux
Architecture: x86_64
CPUs: 16
Total Memory: 3.879GiB
Name: docker-desktop
Docker Root Dir: /var/lib/docker
Host:
Windows 10 Pro for Workstations, version 26H2, build 26300.9550
32 GB RAM, NVMe SSD, Windows Hypervisor Platform enabled
Activity
CoolZxp commentedon Oct 4, 2026
Dug into this a bit more, since I wanted to know where the memory actually is instead of guessing. I broke down
com.docker.sailor.exe's working set withVirtualQueryEx/QueryWorkingSetEx(the same data VMMap shows). This is 4.93.0, Windows 10 26H2 (26300), VM at 4 GiB:Working set at that moment: 14,272 MB, of which 3,103 MB private.
The 102,028 MB region matches
%LOCALAPPDATA%\Docker\vm-data\DockerDesktop.vhdxexactly, so the whole disk image is mapped into the host process (which also explains its ~110 GB virtual size). ~11 GB of it is resident and file-backed — that's where the memory goes. Not guest RAM: guest RAM is the separate 4 GiB private region with ~3 GB resident.None of it is locked, so in theory it can be trimmed, but it stayed resident for ~19 h while the host sat at 0.3–0.8 GB available (standby under 1 GB), and
monitor.logkept logging "host memory pressure: signalled guest drop-caches" every ~10 s the whole time.To make sure it wasn't somehow pinned, I called
EmptyWorkingSeton the process once (VM left running):12.7 GB came out of the working set in 1.76 s, most of it landing on the standby list (standby grew from 1.7 GB to 12.6 GB). Only ~1.9 GB was back after 5 minutes, so most of it was cold cache that nothing needed. The VM was completely fine — both containers stayed up and Postgres/ClickHouse answered normally. The pressure messages stopped right after, too.
So the pages are clean, unlocked and reclaimable, and trimming them is transparent to the VM. It just doesn't happen on its own: Windows' regular pressure trimming didn't free it, and the VMM's reclaim path only pokes the guest caches.