aws s3
file synchronization
cloud storage
data management
command line tools

How does aws s3 sync determine if a file has been updated?

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

aws s3 sync does not compare full file contents by default. Its normal decision process is based primarily on file size and modification time, which makes synchronization fast but also means it is using metadata heuristics rather than a byte-for-byte proof that two files differ.

The Default Comparison Logic

When aws s3 sync compares a source and destination object, it usually asks questions like these:

  • does the destination object exist
  • is the size different
  • is the source newer than the destination

If the answer suggests the destination is missing or stale, the file is transferred.

That is why sync is efficient on large trees. It does not download every object and hash the contents just to decide whether to act.

A Practical Example

Suppose you run:

bash
aws s3 sync ./reports s3://my-bucket/reports

For each local file, the CLI compares local metadata against the object metadata already stored in S3. If a local file is larger, smaller, or more recently modified than its corresponding object, the CLI treats it as changed and uploads it.

If the object does not exist at all, the CLI uploads it as a new file.

Why Checksums Are Not the Default Test

A common misconception is that sync must compare MD5 or ETag values automatically. That is not the general default behavior.

There are good reasons for that:

  • it would be slower for large trees
  • S3 ETags do not always behave like simple MD5 hashes, especially for multipart uploads
  • local checksum calculation adds extra I/O work

So by default, sync prefers a fast metadata-based decision model.

Size and Timestamp in Practice

A small mental model is:

  • different size means changed
  • same size but newer source usually means changed
  • same size and not newer usually means skip

That behavior is normally good enough for deployment assets, backups, and generated build outputs.

But it does mean there are edge cases where the content changed without producing the metadata pattern sync expects.

Useful Flags That Change the Behavior

One important flag is --size-only.

bash
aws s3 sync ./reports s3://my-bucket/reports --size-only

With this flag, the CLI ignores timestamps and uses size comparison only. That is useful when modification times are unreliable across systems but file sizes are still informative.

Another useful flag for understanding what would happen is --dryrun.

bash
aws s3 sync ./reports s3://my-bucket/reports --dryrun

This shows which files the CLI believes need to be transferred without actually moving data.

Timestamps Can Be Tricky

Timestamp-based comparison is convenient, but it is not perfect. Problems can arise when:

  • files are copied in ways that preserve or alter timestamps unexpectedly
  • clock skew exists between environments
  • a tool rewrites a file without changing size in a way that interacts badly with timestamp assumptions

That is why metadata-driven sync is a pragmatic tool, not a cryptographic verifier.

Deletes Are a Separate Concern

sync only decides whether to copy or skip objects unless you also tell it to delete destination files that do not exist in the source.

bash
aws s3 sync ./reports s3://my-bucket/reports --delete

This flag does not change how updates are detected, but it does change the final mirror behavior. Without it, stale destination files may remain even when source files are gone.

When Metadata Heuristics Are Not Enough

If you need a content-verified synchronization strategy, you may need a different workflow:

  • compute and compare checksums yourself
  • store content hashes as metadata
  • use application-level manifest verification

For most operational sync jobs, aws s3 sync is meant to be fast and good enough, not a full content-audit system.

A Good Debugging Pattern

If sync is skipping something you believe changed, test with:

bash
aws s3 sync ./reports s3://my-bucket/reports --dryrun

Then inspect:

  • local file size
  • local modification time
  • object size in S3
  • object LastModified timestamp

That usually reveals why the CLI made its choice.

Common Pitfalls

A common mistake is assuming sync always compares file content hashes. It usually does not.

Another issue is relying on timestamps in workflows where files are copied, restored, or generated in ways that make mtimes unreliable.

Developers also sometimes forget that multipart-upload ETags are not a universal content checksum, so trying to reason about update detection from ETags alone can be misleading.

Finally, do not confuse sync with cp. sync is trying to avoid unnecessary transfers, so its update logic matters much more.

Summary

  • 'aws s3 sync normally decides updates using metadata, especially size and modification time.'
  • It does not perform full content comparison by default.
  • '--size-only and --dryrun are useful when diagnosing sync behavior.'
  • Timestamp-based decisions are fast but not infallible.
  • For strict content verification, you need a workflow beyond the default sync heuristics.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.