Back

Blog details

S3 Eventual Consistency vs Strong Consistency Explained

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

Strong consistency means a read right after a write always returns the new data, while eventual consistency allows a short window where that read can still return old data. Amazon S3 used eventual consistency until December 1, 2020, and has been strongly consistent since.

TL;DR:

  • Under eventual consistency, a write succeeds before every reader can see it, so a read or a listing right afterwards may be stale.
  • Since December 1, 2020, S3 gives strong read-after-write consistency for GET, PUT, LIST and metadata changes, automatically and "at no additional cost."
  • Strong consistency doesn't lock keys: concurrent writers get last-writer-wins, there is no atomicity across keys, and bucket settings are still eventually consistent.
  • AIOZ Storage's docs don't state a consistency model, so test read-after-write on your own bucket before you depend on it.

Updated Oct 19, 2026: answer-first opening, question sections, a tighter history, a read-after-write test pointed at AIOZ Storage's endpoint, a list of what our docs don't cover yet, the AIOZ section now names its Reed-Solomon erasure coding, and the test client has the upload settings AIOZ Storage needs.

What is the difference between eventual and strong consistency?

A consistency model answers one question: after data changes, when is every reader guaranteed to see the change? Strong consistency says immediately, every time, while eventual consistency says once the change has propagated, which leaves a window where a read can return stale data even though the write already succeeded.

Neither model is a bug, because making every read, from anywhere, reflect every write at once is a harder distributed-systems problem than allowing a short propagation delay. Eventual consistency trades that guarantee for simpler replication, and your application pays the difference in defensive code.

Is S3 eventually consistent?

Not anymore, although S3 "pioneered object storage in the cloud... with eventual consistency," in AWS's words, and kept that model for its first fourteen years. Under it, a successful write was stored durably, but a GET right afterwards could return an old version or, for a brand-new key, nothing at all. A listing taken moments after a write could miss the new object.

That gap forced real work onto developers. AWS's announcement says teams had to "insert custom code into these applications, or provision databases" to keep objects consistent with changes in S3. Big data and analytics jobs, which AWS says need "access to an object immediately after a write," were hit hardest.

On December 1, 2020, AWS announced that "Amazon S3 now delivers strong read-after-write consistency automatically for all applications." Nobody had to opt in or change code, and AWS says it came "without changes to performance or availability" and "at no additional cost." Every existing bucket got the stronger guarantee on the same day.

Close-up of code displayed on a computer screen

What does S3 strong consistency cover?

AWS states that "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." The guarantee covers "all S3 GET, PUT, and LIST operations, as well as operations that change object tags, ACLs, or metadata," in every region. Listings changed too, so you can now "immediately perform a listing of the objects in a bucket with any changes reflected."

Where strong consistency stops

"Strongly consistent" is easy to over-read, and AWS's consistency documentation is clear about three limits once more than one client touches the same data.

Concurrent writes 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." A read that starts before the second write finishes can return either value. Because network latency can reorder acknowledgments, AWS advises reading after both writes are acknowledged to learn the final value.

Single keys are atomic, but there is no atomicity across keys. A GET during a PUT returns "either the old data or the new data, but never partial or corrupt data." That protects one object, but not a data file and its index that must change together. AWS says "there is no way to make atomic updates across keys" unless you build it into your application.

Bucket configuration is still eventually consistent. A deleted bucket can briefly appear in a bucket list. After you first enable versioning, AWS recommends waiting 15 minutes before writing or deleting objects in that bucket, which matters if your setup script runs both steps back to back.

Handling concurrent writers with conditional writes

Since S3 won't lock a key for you, the fix for lost updates is a conditional write. If-None-Match: * makes a write succeed only if the key doesn't exist yet, which guards against accidental overwrites. If-Match: <etag> makes it succeed only if the current ETag matches the one you send, the compare-and-swap pattern of read, note the ETag, and write back only if nothing changed.

# 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, both headers work with PutObject, CompleteMultipartUpload and CopyObject, and the requests must be signed with Signature Version 4. Know the failure codes 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)

Conditional writes ignore multipart uploads that are still in progress. If another client writes the key while your upload is open, your conditional CompleteMultipartUpload fails with 412, and after a 409 you have to start the multipart upload again. Because these checks compare ETags, read what an ETag really is before you compare values by hand.

How AIOZ Storage handles consistency

AIOZ Storage runs on AIOZ DePIN and stores each object as Reed-Solomon erasure-coded pieces on different nodes, per AIOZ Storage engineering (2026). When a new write to those pieces becomes readable everywhere is exactly what a consistency model describes, and our docs don't say which one applies. You can see one hint in the official Python SDK sample: it calls bucket.wait_until_exists() after the upload, a boto3 waiter that polls until the object shows up. That pattern is safe under either model, so it tells you nothing about which one applies.

The way to find out is a test against your own bucket. The loop below covers the core cases: overwrite then read, write then list, and delete then list. We have not run it against AIOZ Storage yet, so record what you see:

import os
import uuid
import boto3
from botocore.config import Config

s3 = boto3.client(
    "s3",
    region_name="us-east-1",
    endpoint_url="https://s3.aiozstorage.network",
    aws_access_key_id=os.environ["ACCESS_KEY"],
    aws_secret_access_key=os.environ["SECRET_KEY"],
    config=Config(
        request_checksum_calculation="when_required",
        response_checksum_validation="when_required",
        s3={"addressing_style": "path"},
    ),
)
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)

The Config block matters on AIOZ Storage. Current boto3 versions send uploads as aws-chunked streams and address buckets by subdomain, and the endpoint needs a Content-Length on uploads and path-style URLs (checked Oct 19, 2026).

Each pass sends six requests one after another, so a single client stays well under the documented 100 requests per second limit. Zero anomalies over a few hundred passes from one client doesn't prove strong consistency, because rare gaps and multi-client races won't always show. A nonzero count is a real finding, and it is the evidence you want before building a pipeline that assumes read-after-write.

What the docs don't cover yet:

  • Whether reads, overwrites and deletes are strongly consistent right after a write.
  • Whether listings reflect a new or deleted object immediately.
  • Whether conditional writes with If-None-Match and If-Match are supported.

For the client setup used above, see the AIOZ Storage Python SDK guide.

Frequently Asked Questions

When did S3 switch to strong consistency?
On December 1, 2020, when AWS made strong read-after-write consistency automatic for all applications, with no code changes and no extra cost.

Did applications need to change anything to get it?
No, AWS applied it to every existing bucket "without changes to performance or availability," so old retry loops still work but are no longer needed.

What happens if two clients write to the same S3 key at the same time?
The request with the latest timestamp wins, because S3 doesn't lock objects for concurrent writers, so read after both writes are acknowledged to learn the final value.

How do I stop an S3 write from overwriting an existing object?
Send If-None-Match: * with the write, and it fails with 412 Precondition Failed if the key already exists.

Can I update several S3 objects atomically?
No, updates are atomic per key only, and AWS says there is no way to make atomic updates across keys unless your application builds it.

Does AIOZ Storage guarantee strong read-after-write consistency?
Our docs don't state a consistency model yet, so run the read-after-write test above on your own bucket before you depend on it.

References

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

Related Content

blog thumbnail

What Is Distributed Storage? How It Works, With Examples

Distributed storage keeps data on many independent nodes that act as one system. See how it works, replication vs erasure coding, its types and trade-offs.

aioz-storage
6 min readNovember 03, 2026
blog thumbnail

What Are Egress Fees? How Download Charges Work in Storage

Egress fees are charges for data leaving a storage provider's network. See what triggers them, how to estimate them, and what AIOZ Storage's docs say.

aioz-storage
6 min readOctober 30, 2026
blog thumbnail

Object Storage Vector Database: Where AIOZ Storage Fits

An object storage vector database keeps vectors in the storage layer, not a cluster. See how it differs, when to pick it, and where AIOZ Storage fits in.

aioz-storage
10 min readOctober 27, 2026
blog thumbnail

AIOZ Storage Vector Database Pricing: What You Pay For

AIOZ Storage vector database pricing line by line: upload, storage, queries, data searched and data returned, with a worked monthly example you can reuse.

aioz-storage
5 min readOctober 23, 2026
blog thumbnail

How to Create a Bucket and Upload a File on AIOZ Storage

Create a bucket and upload a file on AIOZ Storage in five steps: sign up, set a passphrase, add credits, and upload. Plus what the passphrase cannot recover.

aioz-storage
5 min readOctober 20, 2026
blog thumbnail

AIOZ Storage Rate Limit: Working Within 100 Requests/s

The AIOZ Storage rate limit is 100 requests per second. See what the docs do and don't say, and how to stay under it with boto3 retries and a limiter.

aioz-storage
7 min readOctober 16, 2026