What is eventual consistency - the S3 promise, honestly

Logeshwaran.C

No — Amazon S3 has not been "eventually consistent" since December 1, 2020. Every PUT, GET, DELETE, and LIST against an S3 object is now strongly consistent, in every AWS Region, at no extra cost. The counterintuitive part: that flip happened more than five years ago, and yet half the blog posts, YouTube tutorials, and even some certification study guides still floating around today describe S3 with the old eventual-consistency caveats — because whoever wrote them either wrote it before 2020 and never went back, or copied someone who did.

⚡ Quick Answer

Object reads and writes (GET, PUT, DELETE, LIST) → strongly consistent since December 1, 2020. What you write is what the next read returns, immediately, every time.

Bucket-level settings (versioning, bucket creation/deletion, ListBuckets) → still eventually consistent. Give these up to 15 minutes before you write to the bucket.

Cross-Region Replication → asynchronous by design, not instant, even with S3 Replication Time Control turned on.

Full breakdown of what's covered, what isn't, and what still trips people up: jump to the honest list.

Jake found this out the expensive way. He runs a small phone repair and resale shop, and about two years ago he built a little app that photographs every trade-in phone the second it arrives, uploads the photo straight to S3, and then immediately re-reads that photo to stamp it onto a customer receipt PDF. Somewhere on a forum, he'd read that S3 "might not show you the file right away," so he built in a five-second delay before the re-read — on every single trade-in, all day, every day. Multiply that by a few thousand trade-ins and Jake had quietly cost himself hours of dead time waiting on a problem that stopped existing back in 2020.

What makes this worth a whole post, rather than a one-line correction, is that the honest answer isn't a flat "yes" or "no." S3 genuinely did change its promise in a way that eliminated an entire category of bugs. But the change wasn't total — a few real corners of S3 are still eventually consistent today, on purpose, and knowing exactly where those corners are is the difference between confidently deleting Jake's five-second delay and confidently leaving the parts of his automation that still need to wait.

What "eventual consistency" actually means

Before we get into what S3 does today, it's worth pinning down what this term even means, because it gets thrown around loosely.

"Consistency" here is talking about a promise a storage system makes about when a change becomes visible. When you save a file, that data has to physically land somewhere — usually copied across several machines, sometimes several data centers, so that if one machine dies, your file survives. Think of it like a shop with three cash registers that are all supposed to show the same total sales figure. If a sale rings up on register one, and you can walk straight to register three and see the updated total instantly, that's strong consistency — every point of access agrees, immediately, all the time. If register three might still show yesterday's total for a few seconds until the numbers "catch up," that's eventual consistency — it will become correct, eventually, just maybe not the instant you look.πŸ’‘

Recommended AWS Foundations Reading

    Master the core building blocks of AWS infrastructure, networking, and security:

    Neither one is "the good one" in the abstract. Eventual consistency exists because keeping every copy of your data in perfect lockstep, everywhere, all the time, is hard and can slow a system down or make it less resilient to failures. Systems that promise it are usually trading a small, temporary blind spot for speed and durability. Strong consistency is the harder promise to keep, and for a long time, engineers assumed you simply could not get it at S3's scale without giving something else up.

    ‍♂️ Jake's Reality Check

    "So which one is S3? Every article I read gives a different answer."

    Both — depending on which part of S3 you're touching. Object data (the actual files) is strongly consistent. Bucket-level configuration is still eventually consistent. That split is the whole honest answer, and almost nobody states it that plainly.

    The old S3 promise: what it actually said, caveats included

    For its first fourteen years, S3's documented consistency model had a genuinely confusing shape, and it's worth walking through exactly what it said, because a lot of the myths still in circulation come from people half-remembering this.

    The old rule was: a brand-new object — a key that had never existed before — was read-after-write consistent for PUT. Write it, read it back immediately, you get it. But there was a sharp edge right next to that promise. If you did a GET or HEAD request against that key before it existed (checking "does this file exist yet?"), and got a 404, and then created the object, S3 only promised eventual consistency for that specific sequence — the system might keep telling you "not found" for a short window even after the object existed.

    The bigger trap was overwrites and deletes. If you PUT new content on top of an existing key, or DELETE an existing key, the old model made no read-after-write promise at all. A GET immediately afterward could return the old data, the new data, or (for deletes) still return the deleted object, until the change finished propagating across S3's internal replicas. Bucket listings had the same gap: write a new object and immediately LIST the bucket, and the new object might not show up yet.

    Operation Before December 1, 2020 Since December 1, 2020
    PUT of a brand-new key Read-after-write consistent (with the pre-existence-check caveat above) Strongly consistent
    PUT overwriting an existing key Eventually consistent — old or new data possible on a read right after Strongly consistent
    DELETE of an object Eventually consistent — object could still appear briefly Strongly consistent
    LIST of bucket contents right after a write Eventually consistent — new object might not appear yet Strongly consistent
    Object tags, ACLs, metadata (HEAD) Eventually consistent Strongly consistent

    That gap between "new object" and "overwrite or delete" was exactly the kind of detail that sounds like nitpicking until it costs you money. Big-data and analytics teams — the ones running Hadoop or Spark jobs directly against S3 — got burned by it constantly, because those jobs write a file and then immediately try to list or read it as part of the same pipeline. To work around the gap, Amazon EMR built a whole separate feature called EMRFS Consistent View, and the open-source Hadoop community built a similar tool called S3Guard. Both did the same thing under the hood: they kept a second, strongly consistent database (usually DynamoDB) sitting in front of S3, tracking which files should exist, purely to paper over the eventual-consistency gap in the storage layer underneath.

    That's worth sitting with for a second: companies were standing up an entire extra database, solely to compensate for a gap in a file storage system. That's how real the old problem was.

    December 1, 2020: the day the promise flipped

    During AWS re:Invent 2020, Amazon announced that S3 now delivered strong read-after-write consistency automatically, for every application, with no configuration and no extra charge. The change applied immediately to every existing and new object, in every AWS Region. Specifically: every GET, PUT, and LIST operation, plus any operation that changes an object's tags, ACLs, or metadata, became strongly consistent, effective that day.

    The mechanics behind that flip aren't publicly documented in detail, and this post won't pretend otherwise — Amazon's own announcement doesn't walk through the internal engineering, so neither will we. What is documented is the outcome: after a successful write of a new object, or an overwrite or delete of an existing object, any read request immediately gets the latest version. You can update the same object hundreds of times a second and every read still returns the most recent write. A list operation performed right after a write reflects that write accurately.

     What changed between versions

    • Before December 1, 2020: new-object PUTs were read-after-write consistent (with the pre-check caveat above); overwrites, deletes, and listings were eventually consistent everywhere.
    • Since December 1, 2020: GET, PUT, DELETE, and LIST — plus tag, ACL, and metadata changes — are strongly consistent for every object, in every Region, automatically, at no extra cost.
    • What that means for you: any code you or a vendor wrote before 2020 to work around this — polling loops, artificial delays, a shadow database of "what should exist" — is very likely dead weight today.

    Two things about that change are easy to miss. First, it wasn't a new feature you had to turn on — there's no setting, no checkbox, no "enable strong consistency" toggle anywhere in the S3 console. If your bucket existed before 2020, it got upgraded in place, silently, along with every other bucket on the platform. Second, Amazon extended the exact same guarantee to S3 on AWS Outposts — the version of S3 that runs on hardware physically installed in your own data center — a year later, in November 2021. So the "strongly consistent" promise isn't limited to the regional cloud service; it follows S3 wherever AWS ships it.

    ✅ Why this is worth trusting without re-testing it yourself

    This isn't a "usually works" behavior you need to defensively code around with retries just in case. It's an unconditional, documented guarantee that AWS backs across every Region, at no additional cost, with no opt-in required. Treat it the way you'd treat any other hard platform guarantee — build on it directly instead of insuring against a failure mode that no longer exists.

    What "strongly consistent" covers, precisely

    It helps to be precise here instead of just saying "S3 is consistent now" and moving on, because the guarantee is specific about what it covers.

    Every GET, PUT, DELETE, and LIST request against an object is strongly consistent. That covers new objects, overwritten objects, and deleted objects — the exact three cases that used to have gaps. It also covers reads on S3 Select (S3's feature for running simple SQL-style queries directly against a file stored in S3, instead of downloading the whole thing first), object ACLs (the older, key-by-key permission system), object tags (labels you can attach to a file for cost tracking or automation), and object metadata retrieved through a HEAD request (a lightweight request that returns a file's details without downloading the file itself).

    There's also a separate guarantee that's easy to conflate with consistency but is actually about something else: atomicity. Updates to a single key are atomic, meaning if you PUT to an existing object from one thread while another thread does a GET on the same key at the same moment, you will get either the fully old version or the fully new version — never a half-written, corrupted, or partial file. That's a guarantee about not getting garbage data; strong consistency is the separate guarantee about which of those two whole versions you'll see, and when.

    The parts of S3 that are still eventually consistent..

    This is the part that makes "the S3 promise, honestly" more than a marketing recap. The strong-consistency upgrade applies to object data — the files themselves and their tags, ACLs, and metadata. It does not extend to every corner of S3. Bucket-level configuration still runs on an eventual consistency model, and AWS's own documentation says so plainly.

    Bucket creation and deletion

    When you delete a bucket, S3 doesn't remove it the instant you click delete. It queues the bucket for deletion, and because that deletion has to propagate across a distributed system, you can still see the bucket in the console, or get it back in a ListBuckets API response, for some time afterward. Until it's fully gone, you can't do anything else with it, but it may still be visible. The same applies in reverse: if you delete a bucket and then immediately try to create a new bucket with the exact same name, that attempt can fail for a while, because the old bucket hasn't fully finished disappearing from the system's bookkeeping yet.

    Enabling Versioning for the first time

    The first time you turn on S3 Versioning (the feature that keeps every past version of an object instead of overwriting it) on a given bucket, AWS's own guidance says it can take up to 15 minutes for that change to fully propagate across the system. During that window, GET requests for objects created or updated right after you flip versioning on can come back with a 404 "no such key" error, even though the object exists. AWS's direct recommendation is to wait 15 minutes after enabling versioning before you run any PUT or DELETE operations against objects in that bucket.

    ⚠️ What this actually breaks

    Automated deployment scripts are the usual victim here. A script that creates a bucket, turns on versioning, and immediately starts uploading files as one continuous sequence can hit spurious "object not found" errors that look like a code bug but are actually this exact 15-minute propagation window. If your infrastructure-as-code pipeline does this, build in a deliberate pause — or a retry loop with backoff — between enabling versioning and the first write.

    Cross-Region Replication: asynchronous by design, not a bug

    This is the single most common place people assume strong consistency should apply and it genuinely doesn't. S3 Replication — including Cross-Region Replication, where objects get copied from a bucket in one AWS Region to a bucket in another — is an inherently asynchronous process. AWS's own troubleshooting documentation states that most object replication finishes within 15 minutes, but for large objects, high object counts, or objects with AWS KMS encryption (which adds extra throttled steps), replication can take up to 48 hours.

    If your workflow needs a predictable, bounded replication time instead of "usually fast, occasionally not," AWS sells that as a separate, paid feature: S3 Replication Time Control (S3 RTC). Turning it on gets you a documented target of replicating 99.99% of new objects within 15 minutes of upload, backed by a service-level agreement guaranteeing 99.9% of objects replicate within 15 minutes across a full billing month. RTC also unlocks replication metrics through Amazon CloudWatch (AWS's monitoring service, which collects numbers like "how many objects are still pending replication" so you can watch them on a dashboard instead of guessing), so you can actually verify how a replication run is going in near real time.

    Replication mode Typical time Guaranteed by SLA?
    Standard S3 Replication (default, no RTC) Most objects within 15 minutes; can stretch to 48 hours for large or high-volume transfers, or KMS-encrypted objects No
    S3 Replication Time Control (RTC, paid add-on) 99.99% of objects within 15 minutes; majority within seconds Yes — 99.9% within 15 minutes per billing month

    Notice that even the SLA-backed version isn't "instant." RTC narrows the delay and puts a number on it; it does not turn replication into strong consistency. If a disaster recovery plan or a compliance requirement assumes your replica bucket is byte-for-byte current the moment you write to the source bucket, that assumption is wrong even with RTC turned on, and it's worth saying so plainly rather than letting a compliance officer find out during an actual incident.

    How this actually plays out in real workflows

    Ethan walked Jake through where this shows up in practice, past the theory.

    "Your receipt app," Ethan said, "the one with the five-second sleep before it re-reads the photo — kill that delay entirely. Upload, then read, back to back, no wait. It'll work every time now, because the read-after-write gap you were coding around doesn't exist anymore."

    "That feels wrong," Jake said. "I built that delay because a forum post from a few years back told me to."

    "That forum post was probably right when it was written," Ethan said. "It's just from before the change. That's the trap — a piece of advice can be completely correct on the day someone posts it and completely wrong five years later, and nothing about the text itself tells you which one you're reading."

    Beyond a small phone shop's receipt app, this matters most in a handful of recognizable patterns:

    1. Data lakes and big-data pipelines. Anything built on Apache Spark, Hadoop, or Presto that writes intermediate files to S3 and then immediately reads them back as part of the same job no longer needs a workaround layer. This was the exact use case the December 2020 change targeted.
    2. CI/CD pipelines that publish and immediately fetch build artifacts. Upload a build artifact to S3, trigger the next stage, and have that stage download the artifact right away — this now works reliably without a polling loop checking "is it there yet."
    3. Static websites and content pipelines. Publish a new page or image, and a visitor hitting the site moments later gets the new version, not a stale one — as long as you're not also relying on a CDN cache in front of S3, which has its own, completely separate caching behavior that strong consistency doesn't touch.
    4. Log aggregation. A process that writes a log file to S3 and a second process that immediately lists the bucket to pick up new logs for processing no longer has to worry about the file being invisible to the LIST call.

    That static website caveat in item three deserves its own callout, because it's a genuinely common point of confusion.

    ‍♂️ Jake's Reality Check

    "I updated a product photo on our site and it took twenty minutes to change for customers. I thought you said S3 fixes that instantly now?"

    S3 fixed the storage layer — not your CDN's cache. If Amazon CloudFront, or any other content delivery network, sits in front of your bucket, it's caching a copy of that photo on edge servers around the world, on its own separate schedule, completely independent of S3's consistency guarantee. That delay is a caching behavior, not an eventual-consistency issue, and the fix is invalidating the CDN cache, not waiting on S3.

    A short diagnostic: does your own code still need a workaround?

    Jake's next question was the practical one: how does he know, for sure, which parts of his own setup still need a wait, and which parts he can safely rip out? Ethan's answer was to walk through it as a short checklist rather than guessing.

    1. Is the operation touching an object, or the bucket itself? A PUT, GET, DELETE, or LIST against a specific file is covered by strong consistency. A bucket creation, bucket deletion, or a first-time versioning toggle is not — those are still eventually consistent, and any delay logic protecting those should stay.
    2. Is a second AWS Region involved? If your workflow reads from a different bucket than the one it wrote to — because of Cross-Region Replication — you're outside the strong-consistency guarantee entirely, RTC or not. Read from the source bucket if the workflow can tolerate it, or check replication status before trusting the replica.
    3. Is a CDN or cache sitting in front of the bucket? CloudFront, a browser cache, or a third-party CDN all cache independently of S3. If the delay you're seeing is at the eyeball, not the API, it's a caching problem, not a consistency problem, and needs a cache invalidation instead.
    4. Could two processes be writing to the exact same key? Strong consistency tells you what a read returns after a write completes — it says nothing about which of two simultaneous writers wins. If that's a real risk in your workflow, that's a job for conditional writes or an external lock, covered next, not a wait-and-hope delay.
    5. Does the workflow need two different objects updated as one unit? If so, no amount of waiting fixes that, because S3 has no concept of a multi-key transaction. That needs a database, not a timer.

    Run your own workaround code through that list, one item at a time, and most legacy "just in case" delays fall into either "safe to delete" (item one, for pure object reads and writes) or "still needed, but now precisely scoped" (items two through five) rather than staying as one big, vague, defensive sleep statement scattered through the codebase.

    S3 conditional writes: the native answer to "what if two writers collide?"

    Strong consistency answers "will my read see the latest write." It does not answer "who wins if two writes happen at almost the same time." AWS's documentation on preventing object overwrites covers exactly that second question, through a feature called conditional writes, using two HTTP headers you can attach to a PUT request: If-None-Match and If-Match.

    An HTTP header, for anyone who hasn't worked with raw web requests before, is just a small labeled instruction attached to a request — like a sticky note clipped to the front of a package telling the delivery person "only drop this off if nobody's home," rather than something buried in the package's actual contents.

    If-None-Match, set to the asterisk character, tells S3: only accept this write if no object already exists under this exact key name. If something is already there, the write fails outright, instead of silently overwriting it. That turns a plain PUT into a genuine "create, but only if this doesn't already exist" operation — useful any time you want the first writer to win and every later writer to get a clean rejection rather than quietly clobbering the first one's data. AWS's documentation notes this header requires the standard s3:PutObject permission and can be used with the PUT, multipart-upload completion, and copy operations.

    If-Match works the other direction: you supply the ETag (a short fingerprint value S3 attaches to every object, letting you tell two versions of the same file apart without downloading and comparing them byte for byte) of the version you last read, and S3 only accepts your write if the object still has that exact ETag. If someone else changed the object in between your read and your write, the ETag will have changed too, and your write gets rejected instead of overwriting their change. That's the classic "read, modify, write back only if nothing else changed" pattern — engineers call it optimistic concurrency, and it's the same idea behind editing a shared spreadsheet that warns you "this has changed since you opened it" instead of just saving over the top of someone else's edit.

    Header What it checks Use it for
    If-None-Match: * Fails the write if any object already exists under that key "Only the first writer should succeed" — a lightweight, storage-native lock, with no extra database
    If-Match: <etag> Fails the write if the object's current ETag doesn't match the one you supply "Only overwrite if nothing changed since I last read this" — safe read-modify-write on a single key

    Two things worth flagging honestly here. First, AWS's documentation notes that If-None-Match applies only to the current version of an object in a versioned bucket, so the exact behavior can shift slightly depending on whether versioning is on. Second, this still doesn't give you atomicity across two different keys — conditional writes protect a single key against a single race, not a multi-object transaction. For that, you're still looking at a proper database sitting alongside S3, as covered next.

    Myths still floating around, and why they persist

    Search around and you'll still find a surprising amount of content — including some AWS certification study material and interview-prep guides — that describes S3 as offering "read-after-write consistency for new objects, eventual consistency for overwrites and deletes." That's not a fabrication or bad research; it's simply describing the pre-December-2020 model, unlabeled with a date, sitting on the internet next to material that's current. Neither the reader nor, often, the writer, has any way to tell which one they're looking at unless the page happens to mention the date.

    The second myth is the mirror image of the first: assuming that because object reads and writes are strongly consistent, everything about S3 now behaves the same way — bucket settings, replication, even other AWS services entirely. That assumption is exactly what trips people up on the versioning-propagation delay and the replication-timing questions covered above.

    A third myth, more of a half-truth: that strong consistency means you no longer need to think about concurrency at all. It doesn't. Strong consistency tells you which version of an object a read will return relative to a completed write. It says nothing about what happens when two writers are racing to update the same key at the same moment — that's what conditional writes exist to solve, separately.

    Where eventual consistency still shows up elsewhere in AWS

    Part of why S3's consistency status gets muddled is that "eventual consistency" is a phrase that shows up all over AWS, describing genuinely different services with genuinely different behavior. It's worth separating S3 from its neighbors.

    Service / area Consistency behavior today
    S3 object data (GET/PUT/DELETE/LIST) Strongly consistent since December 2020
    S3 bucket configuration (create/delete, versioning enablement) Still eventually consistent
    AWS IAM (permission and policy changes) Changes are not always immediately visible everywhere; propagation delay is expected behavior
    AWS CloudTrail (trail and event data store configuration changes) Documented as eventually consistent; changes may take time to fully propagate
    Amazon DynamoDB (default reads) Eventually consistent by default; strongly consistent reads are available as an explicit option you request per read

    The DynamoDB row is the one people trip over most, because it's an inversion of how S3 works. On S3, strong consistency is now the automatic, free, always-on default, and you can't opt back into the old eventual model even if you wanted to. On DynamoDB, eventual consistency is still the default, and strong consistency is something you have to explicitly ask for on each read, and it typically costs more. Two AWS storage services, two opposite defaults — which is exactly the kind of detail that makes "I already know how AWS eventual consistency works" a dangerous assumption to carry from one service to another.

    IAM's behavior deserves a specific mention because it can look like an S3 problem when it isn't. If you just attached a new permissions policy allowing a role to read from a bucket, and the very next API call using that role gets an access-denied error, that's very likely IAM's own propagation delay — not S3 misbehaving. Waiting a short time and retrying, rather than assuming the bucket policy is wrong, is usually the right first move.

    How to design around the parts that are still eventually consistent

    Since the remaining eventual-consistency gaps are narrow and well-defined, the fixes are equally narrow. You don't need a general-purpose "just in case" retry-everything strategy anymore — you need targeted handling for the specific spots that are still async.

    1. After creating a bucket and enabling Versioning, pause before writing. AWS's own guidance is to wait up to 15 minutes before the first PUT or DELETE against objects in that bucket. In an automated deployment, build that wait — or a retry loop that backs off and tries again — directly into the pipeline rather than discovering the failure in production.
    2. Don't assume a deleted bucket name is instantly reusable. If your automation deletes a bucket and immediately tries to recreate one with the same name, add a retry with backoff rather than failing hard on the first attempt.
    3. Treat replication as "eventually," not "immediately," even with RTC. If a workflow genuinely needs to read from the replica bucket right after a write to the source, check the replication status of the object, or design the workflow to read from the source bucket, rather than assuming the replica is already caught up.
    4. Use conditional writes instead of a homemade lock for single-key races. If two processes might write the same key, an If-None-Match or If-Match header solves it at the storage layer, with no additional database, queue, or lock manager.
    5. Never rely on cross-key atomicity — S3 doesn't offer it. If you need "update file A and file B together, or neither," S3 alone cannot guarantee that; that's a job for a database with transaction support, such as DynamoDB Transactions, sitting alongside your S3 storage.
    6. Separate CDN caching problems from consistency problems. If a change to an object isn't showing up for end users but the object itself updated correctly in the bucket, the delay is very likely a CloudFront (or other CDN) cache, and needs a cache invalidation — not a wait on S3.

    Edge cases worth knowing about

    Two writers racing for the same key, without conditional writes

    If you don't set up an If-Match or If-None-Match header, S3's default behavior hasn't changed: it does not lock objects against concurrent writers. If two plain PUT requests land close together, the one with the later timestamp wins, and the earlier write is simply overwritten with no error and no warning to the losing writer. Conditional writes are opt-in, not automatic — you have to deliberately add the header for the protection to apply.

    No atomic updates across keys

    Every consistency and conditional-write guarantee S3 makes is per-key. There is no built-in way to make an update to one object depend on, or happen together with, an update to a different object. If your application logic needs "these two files must always be updated as one unit," that has to be designed at the application layer or handled by a transactional database sitting next to S3 — it is not something the storage layer will do for you, conditional writes included.

    Object Lock and legal holds

    S3 Object Lock lets you configure an object to be unmodifiable and undeletable for a set period, or indefinitely — useful for compliance requirements around retaining records. Because it's a distinct feature from the core read/write consistency model and the newer conditional-writes feature, if your workflow depends on a lock or legal hold being enforced against a delete attempt happening at almost the same instant, don't assume that race is resolved the same way — read S3 Object Lock's own documentation for your exact scenario rather than extrapolating from the general guarantees covered in this post.

    Frequently asked questions

    Is Amazon S3 still eventually consistent?

    For object data — GET, PUT, DELETE, and LIST requests, plus tag, ACL, and metadata changes — no. Those have been strongly consistent in every AWS Region since December 1, 2020. Bucket-level configuration, like enabling Versioning for the first time or deleting a bucket, is still eventually consistent.

    When exactly did S3 become strongly consistent?

    December 1, 2020, announced during AWS re:Invent that year. The change applied immediately and automatically to every existing and new S3 object, in all Regions, with no migration step required from customers.

    Does strong consistency cost extra?

    No. AWS delivers it automatically for all applications, at no additional cost, with no change to performance or availability.

    Do I still need EMRFS Consistent View or S3Guard?

    Almost certainly not for consistency reasons. Both tools existed specifically to paper over the pre-2020 eventual-consistency gap for big-data workloads reading objects immediately after writing them. Since S3 itself now guarantees that behavior, the workaround layer is redundant for that purpose; check whether your specific setup uses either tool for anything else before removing it.

    Is bucket creation and deletion still eventually consistent?

    Yes. Deleting a bucket queues it for removal rather than deleting it instantly, and it can still appear in the console or in a ListBuckets response for a period afterward. Trying to reuse the exact same bucket name immediately after deletion can also fail until the old bucket has fully finished propagating out of the system.

    How long does S3 Versioning take to fully enable?

    AWS's own guidance says up to 15 minutes for the change to fully propagate. During that window, GET requests for objects created or updated right after enabling versioning may return a 404 error. AWS recommends waiting the full 15 minutes before doing any writes on objects in that bucket.

    Is Cross-Region Replication strongly consistent?

    No. S3 Replication, including Cross-Region Replication, is an asynchronous process by design. Most objects replicate within 15 minutes, but replication can take up to 48 hours depending on object size, volume, and whether KMS encryption is involved.

    What is S3 Replication Time Control (RTC), and does it fix the delay?

    RTC is a paid add-on to S3 Replication that provides a documented target of replicating 99.99% of new objects within 15 minutes, backed by a service-level agreement guaranteeing 99.9% of objects replicate within 15 minutes across a billing month. It shrinks and bounds the delay; it does not make replication instant or strongly consistent.

    What happens if two people PUT to the same key at the same time?

    By default, S3 does not lock objects against concurrent writers. If two plain PUT requests hit the same key close together, the request with the later timestamp wins, and the earlier write is silently overwritten with no error. If your application can't tolerate that, S3's conditional-write headers, If-None-Match or If-Match, let you reject a write instead of silently losing data, without needing a separate database.

    Can I update two different S3 objects atomically?

    No. Every S3 consistency and conditional-write guarantee is scoped to a single key. There's no built-in way to make an update to one object depend on, or complete together with, an update to another object. That kind of coordination has to be handled by your application or by a transactional database sitting alongside S3.

    What are S3 conditional writes, and can they prevent overwrite collisions?

    Conditional writes are HTTP headers you attach to a PUT request. If-None-Match rejects the write if an object already exists under that key, useful for "only the first writer should succeed." If-Match rejects the write if the object's current version doesn't match the version you last read, useful for safely updating a file only if nobody else changed it first. Both work at the storage layer, with no extra database required.

    Does strong consistency apply to S3 on Outposts?

    Yes. AWS extended the same automatic strong consistency to S3 on Outposts — the version of S3 that runs on hardware installed in your own facility — starting in November 2021.

    Is IAM eventually consistent too, and does that affect S3 access?

    IAM permission and policy changes aren't always immediately visible everywhere, and that propagation delay is expected, documented behavior — separate from S3's own consistency model. If you just changed a bucket policy or IAM role and immediately get access-denied on an S3 call, a short propagation delay is a more likely explanation than S3 misbehaving.

    Do I need to change my application code now that S3 is strongly consistent?

    If your code contains artificial delays, polling loops, or a separate shadow database purely to work around the old read-after-write gap, that logic is very likely unnecessary now and can be removed. Keep any code that handles bucket-configuration timing, replication timing, or concurrent-writer coordination, since those gaps still exist.

    Jake ended up deleting his five-second delay entirely, and added a single If-None-Match header to the one part of his upload flow where two employees could plausibly photograph the same trade-in at once. "Two changes," he said, "for a problem I'd been solving with one big dumb sleep statement for two years." Ethan's answer to that was simple: "That's most of cloud computing. The platform keeps improving underneath you. The only cost is remembering to go back and check what's actually still true."

    Revision note. Written September 2026, covering S3's consistency model as documented by AWS as of this month. This will need a fresh look only if AWS changes the bucket-configuration or replication timing model itself — the core object-consistency guarantee has held steady for years and isn't expected to move. If you've been quietly coding around a problem that isn't there anymore, you're in good company, and it's genuinely worth the ten minutes to go check.

    Related