aws s3 sync: Usage, Options & Common CI Errors
Sync a directory to S3 - only the changed files, optionally pruning the rest.
aws s3 sync recursively copies only files that are new or changed between a source and destination. It is the standard way to deploy static sites and artifact trees to S3 in CI.
What it does
aws s3 sync <src> <dst> compares the two locations by size and modification time and transfers only the differences. With --delete it also removes destination objects that no longer exist in the source - making the destination an exact mirror. Either side may be local or an s3:// URI.
Common usage
# Deploy a built site, pruning removed files
aws s3 sync ./dist s3://my-site-bucket --delete
# Sync with exclude/include filters
aws s3 sync ./dist s3://my-site-bucket --exclude "*.map" --include "*.js"
# Long cache for hashed assets, no-cache for index.html
aws s3 sync ./dist s3://my-site-bucket \
--cache-control "max-age=31536000,immutable" --exclude index.html
aws s3 sync ./dist s3://my-site-bucket \
--cache-control "no-cache" --include index.htmlCommon error in CI: --delete wipes more than expected / stale cache
Running aws s3 sync ./dist s3://bucket --delete against the wrong prefix can delete unrelated objects, and forgetting to invalidate CloudFront serves stale files after a deploy. Fix: always scope the destination to a dedicated prefix and double-check it before adding --delete; after syncing, invalidate the CDN (aws cloudfront create-invalidation --distribution-id ID --paths "/*"). sync compares mtime+size, not content hashes - touch-only changes may not re-upload, so rely on content-addressed filenames for cache busting.
Key options
| Option | Purpose |
|---|---|
| --delete | Remove dest files absent from source |
| --exclude / --include | Filter which files sync (order matters) |
| --cache-control | Set Cache-Control on uploaded objects |
| --size-only | Compare by size only, ignore mtime |
| --dryrun | Show what would change, transfer nothing |
| --acl | Canned ACL for uploaded objects |