macOS native: workspace.commit averages 133 ms vs 46–57 ms on Docker/Lima in CLI preset workload

Đang mở
#645 1 bình luận 0 reaction 1 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

@jiangkoumo đang làm issue này rồi.

Từ ngày 10/11/2026.

Đánh giá

Issue này chưa được đánh giá.

Mô tả

Problem

In the CLI-backed LayerFS Connect Studio workload, macOS native workspace.commit is consistently slower than the Docker and Lima paths. The initial measurement averaged 133 ms on native vs 46–57 ms on Docker/Lima, despite broadly comparable workspace.exec times. Native commits are about 2.3–2.9× slower in this observation.

This report concerns command latency and its effect on the native project's execution tail. It does not establish an internal root cause. Related: #578 (macOS flush_export / sync(2) stalls); this may be another manifestation, but that has not been profiled in these runs.

Initial measured comparison

All values are mean milliseconds per actual CLI child, rounded. “Combined” adds the exec and commit means for one authored revision; it excludes mount/unmount and is not the whole build's wall time.

Machine workspace.exec workspace.commit Combined Samples per operation
macOS native 46 ms 133 ms 179 ms 4,512
Docker 54 ms 46 ms 100 ms 3,840
Build VM (Lima) 43 ms 57 ms 100 ms 3,456
Research VM (Lima) 43 ms 57 ms 100 ms 3,264

Native direct file write averaged 38 ms in the same run, compared with approximately 55–56 ms on the three Linux paths. The observed native penalty is therefore concentrated in the mounted-workspace path rather than every native mutation.

Initial run totals: 15,072 workspace commits out of 41,310 authored revisions, 66,542 history CLI calls, 41,640 distinct commits overall. History construction took 708.1 seconds; verified Ready took 765.5 seconds. Full CLI capture and saved graph/file checks passed.

Corroborating run: fresh mount every two commits

We subsequently rebuilt the full workload with 7,536 distinct workspace sessions, each following exactly:

mount → exec → commit → exec → commit → clean unmount

The sandbox stays running and is reused. Every session's recorded child timestamps confirmed this order. The native latency gap persisted:

Machine Commit count Commit p50 Commit p95 Mean commit
macOS native 4,512 118 ms 208 ms 140.1 ms
Docker 3,840 44 ms 85 ms 49.4 ms
Build VM (Lima) 3,456 57 ms 117 ms 77.4 ms
Research VM (Lima) 3,264 56 ms 82 ms 59.8 ms

The native website project was the last project to finish. Its 3,648 workspace commits accumulated 506.0 seconds of CLI child duration, compared with 223.9 seconds in exec, 104.7 seconds in mount, and 93.1 seconds in unmount. These are summed child durations, which can overlap; they must not be added or interpreted as wall-time attribution.

The second run completed 80,986 history commands in 973.3 seconds and reached Ready in 1,019.4 seconds. All 84,996 setup CLI calls succeeded with no truncated capture. All project graphs and 359 saved file checks passed. Eight sandboxes remained running, with zero mounted workspaces after completion.

Environment and workload

  • Host: Apple M3 Max, arm64, macOS 26.4.1 (25E253).
  • LayerFS CLI: 2.0.0; embedded commit identity 1edcf58caec2bf079a07891411a0151c9afa3e80, dirty: true, features machine, postgresql. This is a locally modified, sealed qualification build, not a pristine release comparison. The native CLI and daemon are explicitly pinned; Linux workers use a compatible pinned bundle.
  • Entry point: LayerFS Connect Studio Mixed preset, real CLI operations, four machines / four SQLite stores / eight projects, two projects per machine. No mock execution.
  • Native workspace details report the nfs filesystem route.
  • Actual history CLI process peak: 12. Admission limits: 12 global, 3 per store, 3 per project.
  • One persistent sandbox per project; at most two mounted branch workspaces per project in this recipe. No repeated sandbox creation/close in the revision loop.
  • Exec writes small, changed text/JSON fixture files, followed by a real changed-content commit. Original exec command bodies are at most 817 bytes. Every committed head, publication receipt and final saved file was verified.

Reproduction shape

Use private owned fixture data and the same payload/branch-history shape for each machine when isolating this. With a running sandbox bench belonging to the project and an existing side branch feature:

layerfs workspace mount bench feature --name batch-001
layerfs workspace exec bench:batch-001 "printf '%s' 'revision 1' > docs/probe.txt" --exec-id revision-1 --events
layerfs workspace commit bench:batch-001 --message 'revision 1'
layerfs workspace exec bench:batch-001 "printf '%s' 'revision 2' > docs/probe.txt" --exec-id revision-2 --events
layerfs workspace commit bench:batch-001 --message 'revision 2'
layerfs workspace unmount bench:batch-001

The probe assumes the project's docs/ directory exists. Repeat with unique session names and changed contents, reusing the sandbox, and compare native vs stores/sandboxes placed on Docker and Lima. Preserve same-branch ordering and clean unmounts. For the full current Connect workload, run its tools/demo-fixtures.mjs entry point with --preset studio --execution-mode mixed --state <fresh-private-state> and explicit matching --cli / --daemon pins, or use Presets → Mixed → Build projects in the web preview. The current workload changes are local to the Connect checkout; the generic CLI sequence above does not depend on those changes being published.

Measurement and limitations

Timings come from persisted CLI Activity cli.started.data.started to cli.finished.data.ended, not UI task wrappers. They include CLI process startup, transport and daemon work; they are not daemon-internal commit timings. Admission wait before child start is excluded. Exact planned argv, stdin, results, lifecycle completeness and unique commit heads were independently audited.

These are individual observed runs, not a controlled statistical benchmark. Projects have unequal tiers and different contents/history lengths, and the host/guests share resources and have uncontrolled cache state. The second run also contains long outliers on native and Build VM; median/p95 values are included to avoid relying only on means. The data establishes a reproducible workload symptom to investigate, not a proof of a particular platform implementation defect.

Local evidence retained in layerfs-connect/docs/evidence/preset-controls/:

  • mixed-vs-filesystem-operation-timings.json — initial per-operation/per-machine means and counts.
  • mixed-web-independent-archive-audit.json — first full-build correctness/capture audit.
  • mixed-two-pair-web-independent-archive-audit.json — second run lifecycle audit and per-machine timing distributions.
  • mixed-two-pair-verification.json — final workload and timing summary.

The underlying protected NDJSON and step journal were exported with SHA-256 checks. The filenames above identify local evidence, not uploaded GitHub attachments; the relevant measured tables are included directly in this issue.

Investigation requested

  1. Profile native workspace.commit, separating export/writeback flush, snapshot/diff construction, SQLite transaction and CLI/IPC overhead.
  2. Compare identical small-file/history workloads on native and Linux with controlled concurrency and cache conditions.
  3. Check whether #578's global sync(2) path explains the sustained median/p95 penalty in this lower-per-project-concurrency workload. Consolidate with #578 if confirmed.
  4. Any optimization must retain write visibility/durability and correct committed file contents; skipping flush is not a valid performance fix.
Ngôn ngữ chính
Rust
Star
2.1k
Fork
110
Merge trung bình
23 giờ 52 phút
Pull request đã merge (30 ngày)
138

Chuẩn bị môi trường

Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của Ephemeral-AI-Lab/layerfs

Tất cả issue của Ephemeral-AI-Lab/layerfs

Issue tương tự

Thêm issue về Rust

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.