aws s3 sync --delete: Mirror a Directory to S3
aws s3 sync transfers only new or changed files between a source and S3, and with --delete removes destination objects that are not in the source.
sync is the incremental transfer that powers most S3-backed deploys and caches. It skips unchanged files, and --delete turns it into an exact mirror, which is what a static-site bucket usually wants.
What it does
aws s3 sync recursively copies files that are new or changed (by size and modification time). With --delete it also deletes destination objects that no longer exist in the source, producing an exact mirror. --exclude and --include filter which keys are considered.
Common usage
aws s3 sync ./dist s3://my-bucket/site --delete
# cache dependencies, excluding logs
aws s3 sync ./cache s3://my-bucket/cache --exclude "*.log"
# long cache for hashed assets, short for html
aws s3 sync ./public s3://www-bucket --delete \
--cache-control "max-age=31536000" --exclude "*.html"Options
| Flag | What it does |
|---|---|
| --delete | Remove destination objects not present in the source |
| --exclude / --include <pattern> | Filter which files are synced |
| --exact-timestamps | Require exact mtime match (downloads) to skip |
| --size-only | Compare by size only, ignoring modification time |
| --cache-control <value> | Set Cache-Control on uploaded objects |
| --dryrun | Show planned actions without performing them |
In CI
Use --delete for static-site deploys so old assets are purged, then invalidate CloudFront separately. --delete needs s3:DeleteObject, which plain uploads do not, so widen the role only where required. Run --dryrun in review builds to log deletions before they happen. --size-only avoids re-uploads when checkout resets mtimes.
Common errors in CI
"(AccessDenied) ... DeleteObject" when --delete is set means the role lacks delete permission. "(NoSuchBucket)" is a wrong bucket or region. A sync that re-uploads everything each run compared timestamps that changed on checkout; add --size-only. "(SignatureDoesNotMatch)" or "(RequestTimeTooSkewed)" point at a wrong secret or a drifted runner clock; fix the key or NTP.