I have done the following
Steps to reproduce
I measured a public Postgres workload repeatedly on the same machine against Docker/OrbStack and Apple container.
Environment:
- macOS 26.5.1 (25F80), arm64
- Xcode 26.5 (17F42)
- Apple
container CLI 1.0.0 (release, commit ee848e3)
- MacBook Pro Mac14,7, Apple M2, 16 GB memory
- Docker/OrbStack baseline available on the same machine
Apple workload shape:
- Start Apple
container services.
- For each iteration, create a fresh named volume.
- Run
docker.io/library/postgres:16-alpine with:
POSTGRES_USER=app
POSTGRES_PASSWORD=<benchmark-only-password>
POSTGRES_DB=app
PGDATA=/var/lib/postgresql/data/pgdata
- volume mounted at
/var/lib/postgresql/data
- Wait for
pg_isready.
- Capture:
container stats --no-stream
/proc/1/status inside the container
- cgroup
memory.current, memory.peak, and memory.max
du -sk /var/lib/postgresql/data
- runtime-reported block I/O
- Run a short synthetic SQL loop using
generate_series.
- Stop/delete the container and delete the named volume.
Docker/OrbStack used the same image, fresh volume-per-iteration shape, and the
same process/cgroup/disk probes where available.
Iteration counts:
| Workload |
Docker/OrbStack |
Apple container |
postgres-db-only |
50 |
20 |
| backend-shaped Postgres role |
20 |
10 |
Problem description
For a small Postgres workload, the Postgres process RSS and data footprint are effectively the same between Docker/OrbStack and Apple container, but Apple reports much higher runtime/cgroup memory and higher DB block reads.
DB-only memory:
| Runtime |
Process RSS p50 |
Cgroup current p50 |
Runtime memory p50 |
| Docker/OrbStack |
26.68 MiB |
65.14 MiB |
17.21 MiB |
Apple container |
26.57 MiB |
187.45 MiB |
187.01 MiB |
Backend-shaped DB role memory:
| Runtime |
Process RSS p50 |
Cgroup current p50 |
Runtime memory p50 |
| Docker/OrbStack |
26.65 MiB |
67.33 MiB |
20.09 MiB |
Apple container |
26.57 MiB |
188.45 MiB |
188.15 MiB |
Disk footprint:
| Workload |
Runtime |
Data footprint p50 |
| DB-only |
Docker/OrbStack |
45.70 MiB |
| DB-only |
Apple container |
45.70 MiB |
| Backend DB |
Docker/OrbStack |
45.78 MiB |
| Backend DB |
Apple container |
45.79 MiB |
Block read snapshots:
| Workload |
Runtime |
Block read p50 |
| DB-only |
Docker/OrbStack |
0.00 MiB |
| DB-only |
Apple container |
81.05 MiB |
| Backend DB |
Docker/OrbStack |
3.09 MiB |
| Backend DB |
Apple container |
81.05 MiB |
I expected some overhead from Apple container's one-VM-per-container model, but the process RSS being the same while cgroup/runtime memory is roughly 187-188 MiB makes it hard to tell whether this is:
- expected per-container VM/runtime overhead;
- cgroup accounting that includes runtime/kernel/init memory;
- a tunable default that should be documented for DB/backend workloads;
- or an optimization opportunity.
Could maintainers clarify whether this memory profile is expected, and whether there are recommended flags or runtime settings for small DB containers where the process RSS is much lower than the reported cgroup/runtime memory?
Environment
- OS: macOS 26.5.1 (25F80), arm64
- Xcode: 26.5 (17F42)
- Container:
container CLI version 1.0.0 (build: release, commit: ee848e3)
- Hardware: MacBook Pro Mac14,7, Apple M2, 16 GB memory
Notes
This came from a Compose-adapter feasibility benchmark. The backend-shaped Apple path used documented workarounds in my harness:
PGDATA=/var/lib/postgresql/data/pgdata, because mounting a named volume directly at the Postgres data root exposed lost+found.
- DB-IP targeting instead of Compose-style service-name DNS.
So the backend-shaped result is not being presented as Compose parity. The DB-only result is the narrower signal: same Postgres image, same fresh-volume shape, same process RSS, same data footprint, but much higher Apple cgroup/runtime memory and block-read snapshots.
I have done the following
mainbranch of this projectSteps to reproduce
I measured a public Postgres workload repeatedly on the same machine against Docker/OrbStack and Apple
container.Environment:
containerCLI 1.0.0 (release, commitee848e3)Apple workload shape:
containerservices.docker.io/library/postgres:16-alpinewith:POSTGRES_USER=appPOSTGRES_PASSWORD=<benchmark-only-password>POSTGRES_DB=appPGDATA=/var/lib/postgresql/data/pgdata/var/lib/postgresql/datapg_isready.container stats --no-stream/proc/1/statusinside the containermemory.current,memory.peak, andmemory.maxdu -sk /var/lib/postgresql/datagenerate_series.Docker/OrbStack used the same image, fresh volume-per-iteration shape, and the
same process/cgroup/disk probes where available.
Iteration counts:
containerpostgres-db-onlyProblem description
For a small Postgres workload, the Postgres process RSS and data footprint are effectively the same between Docker/OrbStack and Apple
container, but Apple reports much higher runtime/cgroup memory and higher DB block reads.DB-only memory:
containerBackend-shaped DB role memory:
containerDisk footprint:
containercontainerBlock read snapshots:
containercontainerI expected some overhead from Apple
container's one-VM-per-container model, but the process RSS being the same while cgroup/runtime memory is roughly 187-188 MiB makes it hard to tell whether this is:Could maintainers clarify whether this memory profile is expected, and whether there are recommended flags or runtime settings for small DB containers where the process RSS is much lower than the reported cgroup/runtime memory?
Environment
container CLI version 1.0.0 (build: release, commit: ee848e3)Notes
This came from a Compose-adapter feasibility benchmark. The backend-shaped Apple path used documented workarounds in my harness:
PGDATA=/var/lib/postgresql/data/pgdata, because mounting a named volume directly at the Postgres data root exposedlost+found.So the backend-shaped result is not being presented as Compose parity. The DB-only result is the narrower signal: same Postgres image, same fresh-volume shape, same process RSS, same data footprint, but much higher Apple cgroup/runtime memory and block-read snapshots.