Incremental sync
cargoship sync keeps an S3 archive in step with a local directory by uploading only the files that are new or have changed since the last run. The first sync uploads everything (like cargoship upload); every sync after that reads the previous manifest, compares it against the current filesystem, and transfers just the differences — then writes a new manifest that references the prior one. The exhaustive flag list lives in the command reference.
cargoship sync SOURCE_DIR s3://BUCKET/PREFIX/How change detection works
A file is re-uploaded when either
- its size differs from the manifest, or
- its modification time is newer than the manifest.
This is quick because it never re-reads file contents.
cargoship sync ./my-data s3://my-bucket/backups/Content is not hashed, so one case is not detected
An edit that preserves both size and modification time is not detected. That happens in practice with files restored from backup with their mtime preserved, some rsync modes, and in-place edits that happen to keep the same length.
There is no content-comparison mode today. --checksum was supposed to be it, but was never implemented and now fails with an error rather than silently doing nothing (#678).
When you need certainty for a tree whose timestamps you do not trust, use --force to re-upload everything and let the manifest chain record a fresh baseline.
Previewing a sync
Run with --dry-run to see exactly what would transfer without uploading anything. This is the safe way to sanity-check a large sync before committing to the bandwidth and cost:
cargoship sync ./my-data s3://my-bucket/backups/ --dry-runComparing ./my-data against previous manifest...
new: 42 files (1.2 GB)
changed: 7 files (318 MB)
unchanged: 9,914 files (skipped)
Would upload 49 files (1.5 GB) across 10 shards. No changes made (--dry-run).Tracking deletions
By default, sync is additive: files removed locally stay in the archive so old manifests remain fully restorable. Add --track-deletes to record local deletions in the new manifest, keeping it a faithful mirror of the source tree:
cargoship sync ./my-data s3://my-bucket/backups/ --track-deletesDeletions are recorded, not purged
--track-deletes marks files as deleted in the new manifest so restores from it won't include them. It does not delete chunk data from S3 — earlier versions in the chain still reference those chunks.
Reclaim storage with dataset prune, not age-based expiration
To free space, use reference-aware garbage collection:
cargoship dataset prune s3://my-bucket/backups/ --dataset-id <id> --keep-last 5dataset prune deletes only objects that no retained version still references (see dataset versioning). Do not apply an age-based S3 lifecycle expiration rule to an active dataset's uploads/ prefix: because an incremental version reuses unchanged objects from older versions, expiring objects by age can make a currently-retained version unrestorable. S3 lifecycle is still appropriate for storage-class transitions (e.g. Standard → Glacier) of still-live data — just not for deletion.
Forcing a full re-sync
If a manifest is missing or you want a clean baseline, --force ignores the previous manifest and uploads everything, just like a first run:
cargoship sync ./my-data s3://my-bucket/backups/ --forceSharding, compression & storage class
Sync accepts the same tuning knobs as upload:
cargoship sync ./my-data s3://my-bucket/backups/ \
--shard-count 16 --shard-strategy size \
--compression-level 9 \
--storage-class GLACIER_IR--shard-count— number of parallel shards, 1–100 (default 10). Unlikeupload,syncdoes not auto-select the count.--shard-strategy—round-robin(default),hash,size,type,directory. See Sharding.--compression-level— Zstandard 1–22. Passing it overrides content-aware per-chunk selection and pins every chunk to that level; omit it to keep automatic selection. See Compression.--storage-class—STANDARD(default),GLACIER_IR,DEEP_ARCHIVE, etc. See Lifecycle & storage classes.-q/--quiet— minimal output for cron and scripts.-r/--region— AWS region (defaultus-west-2); match your bucket.
sync vs. upload --incremental
Both do incremental transfers. Reach for sync when you want a repeatable directory-mirroring workflow that manages the manifest chain for you. Reach for upload --incremental when you already hold a specific previous manifest and want to layer one incremental pass on top of it.
Best practices
TIP
- Always
--dry-runfirst on a new sync target — confirm the new/changed counts look sane before spending bandwidth. - Use
--forcewhen mtimes can't be trusted (restored trees, CI,rsync): there is no content-comparison mode, so a full re-upload is the only way to re-baseline. - Add
--track-deletesonly when you want the archive to mirror the source; leave it off when you want an append-only history. - Pin
--region(or setAWS_REGION) so scheduled syncs never guess wrong. - Run quiet in cron: add
-qand check the exit code.
See also
- Uploading data — one-shot uploads and the
--incrementalflag. - Resuming interrupted uploads — recover a sync that was cut off.
- Concepts: upload & manifest — what a sync produces.
- Reference: Uploading & sync commands.
