Back

Blog details

Eventual vs Strong Consistency: How S3 Made the Switch

AIOZ Network
10 min readSeptember 14, 2026
aioz-storage
Abstract data visualization with glowing connected points

Eventual vs strong consistency answers a question that sounds academic until it breaks something in production: if you write data and immediately read it back, are you guaranteed to see what you just wrote? For fourteen years, Amazon S3's answer was no, not necessarily, a real, documented limitation of the eventual consistency model every distributed storage system built on. Then, on a single date, AWS changed the answer entirely. This article covers what that older guarantee actually meant in practice, what changed, and why the switch was significant enough that AWS made a dedicated announcement about it rather than a quiet changelog entry.

TL;DR:

  • Eventual consistency means a read immediately after a write isn't guaranteed to see the new data right away, there's a real, if usually brief, window where different requests could see different answers.
  • On December 1, 2020, AWS announced that S3 now delivers strong read-after-write consistency automatically, for every application, "without changes to performance or availability" and "at no additional cost."
  • Strong consistency means exactly what it sounds like: after a successful write, overwrite, or delete, AWS states that "any subsequent read request immediately receives the latest version," no workaround code required.

Eventual vs Strong Consistency: Two Different Promises

A storage system's consistency model is really just an answer to one specific question: after data changes, when is every reader guaranteed to see the change? Strong consistency answers "immediately, always." Eventual consistency answers "eventually, once the change has had time to propagate," which in practice means there's a real window, however short, where a read could return stale data even though a write already technically succeeded. Neither answer is inherently wrong, they're different trade-offs a distributed system makes between guarantees and the engineering cost of providing them.

S3 Eventual Consistency: What It Actually Meant in Practice

For most of S3's history, that was the trade-off it made. In the eventual consistency model, once a write succeeded, the data was durably stored, but there was a window where it wasn't yet guaranteed to be visible to every subsequent GET request across the system. That gap mattered most for a specific, common pattern: an application writes an object and then immediately tries to read it back, only to occasionally get a stale answer, or an old version, or in the worst cases with newly-created objects, nothing at all. AWS's own retrospective on the change is candid about the workaround this forced on developers: teams had to "insert custom code into these applications, or provision databases," purely to paper over that timing gap themselves rather than trusting S3 to guarantee it directly.

December 1, 2020: The Day S3 Changed

AWS's own announcement states the change plainly and precisely dated: as of December 1, 2020, "Amazon S3 now delivers strong read-after-write consistency automatically for all applications." Not a new feature to opt into, not a new storage class or API version, every existing bucket and every existing application got the stronger guarantee automatically. AWS's own language about the switch is specific about what didn't change to achieve it: "without changes to performance or availability" and "at no additional cost," a rare case of a distributed system upgrading a fundamental guarantee without asking anyone to pay for it in speed, uptime, or dollars.

Close-up of code displayed on a computer screen

What Strong Consistency Actually Guarantees Now

The current guarantee is specific and broad at once. AWS states it directly: "after a successful write of a new object, or an overwrite or delete of an existing object, any subsequent read request immediately receives the latest version of the object." That's not limited to simple GET requests either, AWS's own page confirms the same guarantee extends to "all S3 GET, PUT, and LIST operations, as well as operations that change object tags, ACLs, or metadata," across every existing and new object, in every region. List operations specifically were a real, separate gap under the old model, and AWS calls that out directly too: you can now "immediately perform a listing of the objects in a bucket with any changes reflected," rather than a newly-written object potentially missing from a listing taken moments later.

Why the Old Model Existed in the First Place

Eventual consistency wasn't an oversight, it was a genuine engineering trade-off of the era S3 launched into. AWS's own framing acknowledges this directly, noting that S3 "pioneered object storage in the cloud... with eventual consistency" back when that trade-off was considered a necessary cost of building a globally distributed system at that scale. Guaranteeing that every read, from anywhere, immediately reflects every write, from anywhere, is a genuinely harder distributed-systems problem than allowing a brief propagation window, which is exactly why AWS's 2020 announcement was treated as a significant technical achievement industry-wide rather than a routine update.

What This Meant for Applications Built Around the Old Model

The practical upside for anyone building on S3 after December 2020 is that an entire category of defensive code became unnecessary. Big data and analytics workloads specifically, which AWS calls out directly as needing "access to an object immediately after a write," no longer needed custom retry logic, artificial delays, or a separate consistency-tracking database layered in front of S3 just to work around timing gaps that used to be real. That's a meaningful simplification for exactly the kind of pipeline where a write immediately followed by a dependent read is the normal, expected pattern, not an edge case.

What Strong Consistency Does Not Give You

"Strongly consistent" is easy to over-read. AWS's own consistency documentation is explicit about where the guarantee stops, and each limit matters once more than one client touches the same data.

Concurrent writes to the same key are last-writer-wins. AWS states that "Amazon S3 does not support object locking for concurrent writers. If two PUT requests are simultaneously made to the same key, the request with the latest timestamp wins." Its documentation walks through three timelines. When both writes finish before a read starts, every read returns the latest value. When a second write hasn't finished before a read starts, that read could return either the old or the new value, though any read that starts after both writes finish returns the newer one. And when two writes overlap, S3 "internally uses last-writer-wins semantics," but the order requests are received and the order clients get acknowledgments can differ because of network latency. AWS's advice is blunt: the best way to determine the final value is to perform a read after both writes have been acknowledged.

Writes to a single key are atomic, but there's no atomicity across keys. A concurrent GET during a PUT returns "either the old data or the new data, but never partial or corrupt data." That protects one object. It doesn't help if your application updates two related objects, say a data file and its index, and needs both changes to appear together. AWS is direct about that too: "there is no way to make atomic updates across keys," unless you design it into your application.

Bucket configuration is still eventually consistent. The strong guarantee covers object operations, not bucket-level settings. AWS lists two examples: after deleting a bucket, an immediate list of buckets might still show it, and after enabling versioning for the first time, the change can take a short while to propagate. AWS recommends waiting 15 minutes after enabling versioning before issuing writes or deletes on objects in that bucket. If you script bucket setup and object writes back to back, this is the gap that bites.

Handling Concurrent Writers with Conditional Writes

Since S3 won't lock a key for you, the practical answer to lost updates is a conditional write. Two headers cover the common cases:

  • **If-None-Match: *** makes the write succeed only if no object with that key exists yet. It's a create-only guard that prevents accidental overwrites.
  • If-Match:makes the write succeed only if the object's current ETag matches the value you send. That's the compare-and-swap pattern: read an object, note its ETag, and write back only if nobody changed it in between.
# create-only: fails if the key already exists
aws s3api put-object --bucket my-bucket --key config/state.json \
  --body state.json --if-none-match "*"

# update only if the object is unchanged since you read it
aws s3api put-object --bucket my-bucket --key config/state.json \
  --body state.json --if-match "6805f2cfc46c0f04559748bb039d69ae"

Per AWS's documentation, both headers work with PutObject, CompleteMultipartUpload and CopyObject, and requests must be signed with Signature Version 4. Failure modes are worth knowing before you write retry logic:

SituationResponse
If-None-Match and the key already exists412 Precondition Failed
If-Match and the ETag doesn't match412 Precondition Failed
Several conditional writes race for the same keyThe first to finish succeeds, the rest get 412
A delete finishes before the conditional write409 Conflict (If-None-Match) or 404 Not Found (If-Match)

One subtlety for large uploads: conditional writes don't consider in-progress multipart uploads, since those aren't fully written objects yet. If another client writes the key while yours is mid-upload, your CompleteMultipartUpload with a condition fails with 412, and after a 409 you have to re-initiate the whole multipart upload.

Conditional writes also lean on the ETag, which is one more reason to read what an ETag really is before comparing values by hand.

Testing Read-After-Write Consistency Yourself

A vendor's documentation is the claim, and a test is the evidence. If you're evaluating any S3-compatible store for a workload that reads right after it writes, a short loop covers the core cases: write then immediately read, overwrite then read, delete then read, and write then list.

import uuid
import boto3

s3 = boto3.client("s3", endpoint_url="https://YOUR-S3-ENDPOINT")  # credentials via env
bucket = "my-test-bucket"
failures = 0

for i in range(200):
    key = f"consistency-test/{uuid.uuid4()}"
    s3.put_object(Bucket=bucket, Key=key, Body=b"v1")
    s3.put_object(Bucket=bucket, Key=key, Body=b"v2")            # overwrite
    if s3.get_object(Bucket=bucket, Key=key)["Body"].read() != b"v2":
        failures += 1                                            # stale read
    listed = s3.list_objects_v2(Bucket=bucket, Prefix=key).get("KeyCount", 0)
    if listed != 1:
        failures += 1                                            # write missing from listing
    s3.delete_object(Bucket=bucket, Key=key)
    if s3.list_objects_v2(Bucket=bucket, Prefix=key).get("KeyCount", 0) != 0:
        failures += 1                                            # deleted key still listed

print("anomalies:", failures)

Zero anomalies over a few hundred iterations from one client doesn't prove strong consistency, since rare propagation gaps and multi-client races won't always show up. A nonzero count is a real finding, though, and it's exactly the evidence you'd want before building a pipeline that assumes read-after-write.

Where AIOZ Storage Fits

AIOZ Storage's own documentation doesn't state a consistency model anywhere, confirmed directly against its concept-definitions page, no mention of consistency, eventual consistency, strong consistency, or read-after-write guarantees at all. That's a genuinely open question worth taking seriously rather than assuming resolved either way, and arguably a more relevant one for AIOZ Storage than it would be for a single-datacenter system: AIOZ Storage's own documented redundancy mechanism is replication across independent DePIN nodes, and propagating a write to every replica before it's readable everywhere is precisely the kind of distributed-systems challenge that consistency models exist to describe. Nothing in AIOZ's documentation confirms how it handles this today, worth testing directly for any workload where reading immediately after writing matters, rather than assuming S3-compatibility implies an identical consistency guarantee underneath.

Frequently Asked Questions

What's the difference between eventual and strong consistency?
Strong consistency guarantees a read immediately after a write always sees the latest data. Eventual consistency allows a real window where a read right after a write might still return stale or missing data, until the change finishes propagating.

When did S3 switch to strong consistency?
December 1, 2020. AWS announced that S3 delivers strong read-after-write consistency automatically for all applications, with no changes needed to existing code and no additional cost.

What operations does S3's strong consistency guarantee cover?
GET, PUT, and LIST operations, plus changes to object tags, ACLs, and metadata, across all existing and new objects in every AWS region, per AWS's own documentation.

Did applications need to change anything to get the new consistency guarantee?
No. AWS states the switch happened automatically, "without changes to performance or availability," for every existing application already using S3.

Why did S3 originally use eventual consistency instead of strong consistency?
Because guaranteeing that every read from anywhere immediately reflects every write from anywhere is a genuinely harder problem at global, distributed scale. AWS's own framing describes eventual consistency as the trade-off S3 launched with as a pioneer of cloud object storage.

What workaround did developers use before strong consistency existed?
Custom application code or separate databases layered in front of S3, purely to track which writes had actually propagated and avoid reading stale data immediately after a write, per AWS's own description of the pre-2020 pattern.

What happens if two clients write to the same S3 key at the same time?
Last-writer-wins. AWS states that S3 doesn't support object locking for concurrent writers, and the request with the latest timestamp wins. The order requests arrive and the order acknowledgments return can differ because of network latency, so read after both writes are acknowledged to learn the final value.

Is everything in S3 strongly consistent?
Object operations are. Bucket configuration is still eventually consistent: a deleted bucket can briefly appear in a bucket list, and AWS recommends waiting 15 minutes after first enabling versioning before writing or deleting objects in that bucket.

How do I prevent overwriting an existing object in S3?
Add the If-None-Match: * header to the write, which fails with 412 Precondition Failed if the key already exists. For safe updates, use If-Match with the ETag you last read, so the write only succeeds if the object hasn't changed since.

Can I make atomic updates across multiple S3 objects?
No. Updates are key-based, and AWS states there's no way to make atomic updates across keys unless you design that into your application.

Does AIOZ Storage guarantee strong read-after-write consistency?
Not documented. AIOZ Storage's own documentation doesn't state a consistency model, which is a real open question given its replication-based architecture across independent nodes, worth testing directly rather than assuming either way.

References

We only send updates when meaningful changes ship, and you can unsubscribe anytime

Related Content

blog thumbnail

AIOZ Storage Super Intelligence Memory: Record and Recall

AIOZ Storage Super Intelligence Memory gives AI agents memory: Record a statement, Recall it by meaning, with no embeddings or vector index to manage yourself.

aioz-storage
7 min readSeptember 29, 2026
blog thumbnail

Static Website Hosting on AIOZ Storage: Full Setup Guide

Static website hosting on AIOZ Storage turns any bucket into a live site with a custom domain. Here is the full setup, from bucket to DNS verification.

aioz-storage
4 min readSeptember 25, 2026
blog thumbnail

What Is an Embedding Model? How AI Turns Text Into Vectors

An embedding model turns text, images, or audio into vectors so similar meanings land close together in space. Here is how embedding models actually work.

aioz-storage
5 min readSeptember 24, 2026
blog thumbnail

What Is Retrieval-Augmented Generation (RAG)? Explained

Retrieval-augmented generation (RAG) grounds an LLM answer in your own data, not its training set. Here is how the retrieval and generation steps work.

aioz-storage
5 min readSeptember 22, 2026
blog thumbnail

How to Build an MCP Server for AIOZ Storage, Step by Step

AIOZ Storage has no official MCP server yet. Here is a working MCP server for AIOZ Storage, built with the official Python SDK and boto3, tools included.

aioz-storage
6 min readSeptember 19, 2026
blog thumbnail

What Is an MCP Server? How AI Agents Access Storage

What is an MCP server: a standard letting AI agents like Claude use tools and data through one protocol. How MinIO and Azure apply it to object storage.

aioz-storage
6 min readSeptember 16, 2026