Parallel client transfers
Documentation/Native client workflows
Parallel client transfers4 min read

Parallel client transfers

On this page

Uploads and downloads automatically use a bounded pool of session-bound data connections when enough missing chunks are queued. No server setting or format migration is required. Ordinary small transfers keep using the control connection.

Configuration

The default limit is four simultaneous data transfers per client connection. Choose an integer from 1 through 8:

sh
scribe --transfer-jobs 2 sync
scribe --transfer-jobs 1 submit -m "Serial transfer"
SCRIBE_TRANSFER_JOBS=4 scribe sync

The CLI flag overrides SCRIBE_TRANSFER_JOBS, which overrides the default. Invalid values are rejected. The native client uses the same default and reads SCRIBE_TRANSFER_JOBS from its process environment. Set it before launching the native app; there is no new GUI preference. Rust callers can set TcpClientOptions::transfer_jobs directly. scribe diagnostics reports the effective limit.

1 forces serial transfers. Higher values are ceilings, not a promise that all connections will be used or that throughput will multiply by that number. The scheduler selects useful concurrency from the currently queued missing chunks: roughly one lane per 8 MiB, capped by the configured limit and available independent batches. A single object is never split. Cached and locally reusable chunks need no network lane. Connections are opened lazily and reused within the control session; at most the configured number of data connections plus the original control connection exist.

This is scheduling based on available work, not bandwidth autotuning. It does not probe network speed or increase concurrency without a bound. Server admission and per-principal limits still apply. Connection or authorization errors are reported; they are not hidden by a serial retry. Lower the client limit if the server's connection budget or storage calls for it.

Safety and resource bounds

  • All upload identities are durably pinned before any worker transmits bytes. Chunk uploads finish durably before manifests and change sets are published. Metadata acceptance stays on the original connection, after successful upload.
  • Upload workers reread file ranges and verify the original chunk digests. Parallel batches share the existing 1,024-object bound across active lanes (256 per batch with four lanes), with at most 64 MiB of logical content each; payloads stream from disk, rather than being buffered as whole batches.
  • Download workers use the same manifest witnesses and authorization as serial reads. Each worker hands over one bounded chunk at a time through a rendezvous channel. There is no growing queue of downloaded payloads.
  • The caller verifies chunk identities, writes temporary files, publishes cache objects, reports progress, and verifies complete file identities before file replacement. Local-work recovery and journal rules are unchanged.
  • Errors stop new jobs. All started workers finish or fail and are joined before the workflow returns. Cancellation is cooperative; an in-flight durable server publication may complete. Failed streams are discarded before reuse. No automatic retry of an unknown metadata outcome is introduced.
  • Data lanes inherit TLS trust, session binding, compression and cancellation. CLI protocol-byte counters include the pooled connections and handshakes.

Chunk payload memory is bounded by the active producers plus the consuming thread (each chunk is at most 16 MiB), in addition to transport/compression buffers and the existing workflow state. Connections remain pooled until the control session ends. The control connection is silent while the data connections move bytes; the server's inactivity timeout counts the whole session, so a transfer of any length keeps it open for the commit that follows. A gateway replaces its idle upstream connection behind the control connection before using it again. File analysis has its own existing worker bound.

Verification and focused comparison

The ordinary regression suite exercises serial and parallel submit/sync, compression, both test codecs, gateway routing, interrupted transfers, content identity, warm sync, and temporary-file cleanup. Transport tests cover pool reuse, failed-stream replacement, cancellation, and TLS authorization on data lanes.

Run the explicit local comparison separately:

sh
cargo test --release --all-features --locked -p scribe-client --test parallel_transfers compare_serial_and_parallel_transfers -- --ignored --nocapture

It compares one and four lanes in alternating order, twice each, using fresh isolated repositories and 128 MiB of deterministic incompressible files per trial. Submit and sync use separate fresh control sessions; opening their data pools is included in the measured workflows. The OS cache is not forcibly cleared. It checks the resulting file bytes and removes its stores and servers. Reported submit/sync times include complete client workflows, not just network transfer. This loopback comparison does not certify WAN throughput or production capacity. Existing --timings profiling includes transfer.parallel and the per-request upload/download spans; overlapping spans must not be summed as CPU time.

Source docs/parallel-transfers.mdSnapshot 2b8dcccb