Problem
The current openalice project transfer path is correct and safe, but too slow for a real AliceProject and cannot yet serve as a usable directional sync workflow.
A real Default AliceProject transfer to the retained Railway SSH host completed successfully, but 212.3 MiB took almost eleven minutes. That makes migration feel stalled and makes repeated local-to-remote synchronization impractical.
This is separate from the Railway deployment/lock work: the deployed Runtime, retained Volume, migrated Project, external Agent Runtime, restart, and hard-kill recovery all work. The transfer data plane needs its own focused redesign rather than more patches in the deployment path.
Real-world evidence
Observed during the Railway acceptance after #1281; the transfer implementation is unchanged on dev at e34e726e.
- Portable payload: 10,702 files / 212.3 MiB (
222,635,304 bytes)
- Full apply command: 650.506 seconds (~10m 50s)
- Effective throughput: ~0.33 MiB/s
- Same SSH route, raw 32 MiB stdin-to-
/dev/null: 5.46 seconds (~5.86 MiB/s)
- Current migrated tree sample: 10,327 of 10,742 files (96%) are <=64 KiB; 6,327 (59%) are <=4 KiB
- A 1,000-file temporary write comparison did not show
/data as an obvious standalone bottleneck
- CLI apply prints the reviewed plan and then stays silent until completion
The source was quiescent and the destination was new. The transfer completed with the expected receipt and published the exact file/byte totals.
Current hot path
The transport correctly uses one SSH process, not one connection per file. The avoidable cost is inside the custom framed data plane:
packages/cli/src/project-transfer.ts: the planner walks and hashes entries serially.
packages/cli/src/project-transfer-stream.ts: the sender re-opens, re-reads, and re-hashes every file while streaming.
packages/cli/src/project-transfer-stream.ts: the receiver serially performs per-entry mkdir / open / write / close / checksum / chmod operations.
packages/cli/src/project-transfer-ssh.ts: the raw framed stream is sent without a bulk archive/compression layer.
packages/cli/src/project-command.ts: the non-TUI apply path does not expose aggregate transfer progress, throughput, or ETA.
The 18x gap between raw SSH capacity and effective transfer throughput, together with the small-file-heavy Project shape, points to under-utilization in this per-entry pipeline rather than an unavoidable Railway/network limit.
Proposed product boundary
Treat this as directional AliceProject sync, not bidirectional live replication.
Keep the existing control and safety plane:
- reviewed plan and explicit consent;
- source-quiescence and destination preflight;
- portable-file allowlist/exclusions;
- machine-local Runtime/install/auth/Session state excluded;
- credentials carried separately and re-sealed at the destination;
- normalized paths, entry types, symlink containment, size bounds, and checksums;
- owner-private staging, retry/cancel semantics, exact receipt, and atomic publication.
Replace the slow data plane cleanly:
- Build a bounded bulk bundle/archive stream from the reviewed manifest, including transformed portable bytes.
- Compress and transfer that stream through the existing authenticated SSH channel.
- Extract only into private staging; do not let archive metadata become path authority.
- Walk and verify the staged tree against the exact manifest before atomic publication.
- Emit phase-level progress (
planning, packing, uploading, verifying, publishing), bytes/sec, and ETA at a bounded refresh rate.
- After the full-snapshot path is fast, add manifest-based repeat sync that skips unchanged content. Do not add two-way conflict resolution in this issue.
Avoid treating ssh -C, arbitrary concurrency, or a collection of per-file caches as the complete fix. Those may be implementation details, but the acceptance boundary is a bulk, measurable data path with the current safety properties intact.
Acceptance criteria
Why deferred
The live Railway deployment is usable now. Fixing this well requires a separate transport design and representative performance fixture; coupling it to the completed Railway lifecycle/update-authority work would expand risk and encourage incremental patches to the wrong abstraction.
Related
Problem
The current
openalice project transferpath is correct and safe, but too slow for a real AliceProject and cannot yet serve as a usable directional sync workflow.A real Default AliceProject transfer to the retained Railway SSH host completed successfully, but 212.3 MiB took almost eleven minutes. That makes migration feel stalled and makes repeated local-to-remote synchronization impractical.
This is separate from the Railway deployment/lock work: the deployed Runtime, retained Volume, migrated Project, external Agent Runtime, restart, and hard-kill recovery all work. The transfer data plane needs its own focused redesign rather than more patches in the deployment path.
Real-world evidence
Observed during the Railway acceptance after #1281; the transfer implementation is unchanged on
devate34e726e.222,635,304bytes)/dev/null: 5.46 seconds (~5.86 MiB/s)/dataas an obvious standalone bottleneckThe source was quiescent and the destination was new. The transfer completed with the expected receipt and published the exact file/byte totals.
Current hot path
The transport correctly uses one SSH process, not one connection per file. The avoidable cost is inside the custom framed data plane:
packages/cli/src/project-transfer.ts: the planner walks and hashes entries serially.packages/cli/src/project-transfer-stream.ts: the sender re-opens, re-reads, and re-hashes every file while streaming.packages/cli/src/project-transfer-stream.ts: the receiver serially performs per-entrymkdir/open/write/close/ checksum /chmodoperations.packages/cli/src/project-transfer-ssh.ts: the raw framed stream is sent without a bulk archive/compression layer.packages/cli/src/project-command.ts: the non-TUI apply path does not expose aggregate transfer progress, throughput, or ETA.The 18x gap between raw SSH capacity and effective transfer throughput, together with the small-file-heavy Project shape, points to under-utilization in this per-entry pipeline rather than an unavoidable Railway/network limit.
Proposed product boundary
Treat this as directional AliceProject sync, not bidirectional live replication.
Keep the existing control and safety plane:
Replace the slow data plane cleanly:
planning,packing,uploading,verifying,publishing), bytes/sec, and ETA at a bounded refresh rate.Avoid treating
ssh -C, arbitrary concurrency, or a collection of per-file caches as the complete fix. Those may be implementation details, but the acceptance boundary is a bulk, measurable data path with the current safety properties intact.Acceptance criteria
Why deferred
The live Railway deployment is usable now. Fixing this well requires a separate transport design and representative performance fixture; coupling it to the completed Railway lifecycle/update-authority work would expand risk and encourage incremental patches to the wrong abstraction.
Related
plans/remote-project-fleet.md,docs/remote-access.md