Articles · Amazon
Amazon S3 Interview Questions: Consistency, Versioning, and Concurrent Writers
Prepare for Amazon S3 interviews with strong consistency, versioning, delete markers, conditional writes, and a two-writer manifest race.
Two release jobs read the same S3 manifest, each adds a different artifact, and both upload a replacement. Every request succeeds. One artifact disappears from the current manifest. Has S3 violated strong consistency?
No. The application performed two competing read-modify-write operations without a conflict protocol. Strongly consistent object storage can faithfully expose the winning write while the application loses another writer's intended change.
That distinction drives useful Amazon S3 interview answers. Explain what a read can observe, what version history retains, and what prevents a stale writer from replacing newer application state. Treat them as separate contracts.
Evidence boundary: Official AWS documentation supports the S3 behavior linked below. The release-manifest race and recovery exercises are original preparation scenarios, not candidate reports or measurements from an AWS account. This article concerns ordinary object workflows in general purpose buckets; it does not generalize every feature to directory, table, or vector buckets.
Start with Design an S3-like object storage service and add two writers to one key. The interesting question is which business update survives, not whether both clients received a response.
What does strong consistency actually guarantee here?
Official fact: S3 provides strong read-after-write consistency for object writes and deletes, including overwrites. Reads and listings begun after a successful write reflect the write, and updates to an individual key are atomic. This does not provide atomic updates across multiple keys. See the S3 consistency model.
Scope your answer to the actual endpoint and operation. “The application returned old content” does not prove a direct S3 read returned stale content. The application may have read a different key, requested an older version, consulted a cache, or reached a replication destination.
In the original exercise, the key is releases/current.json. A reader that overlaps a replacement is a different case from a reader started after a completed write. Describe the ordering of requests and responses before debating which observation is allowed.
Atomic replacement also means something narrower than an application transaction. It prevents a reader from seeing half of one object mixed with half of another replacement. It does not guarantee that the JSON's business fields were calculated from the newest application state.
Why can two successful writes still lose a business update?
Suppose the original manifest contains artifact A. Writer One adds artifact B, and Writer Two adds artifact C. Both began from the original document. The following is an original race, not an AWS execution trace:
| Step | Writer One | Writer Two | Current application document |
|---|---|---|---|
| 1 | Reads [A] | Reads [A] | [A] |
| 2 | Builds [A, B] | Builds [A, C] | [A] |
| 3 | Writes [A, B] successfully | Waiting | [A, B] |
| 4 | Finished | Writes [A, C] successfully | [A, C] |
The final document is a complete object. The missing B is an application conflict, not a partially written object. Adding a sleep before reading does not repair the write protocol; it only changes how often the race appears.
Ask what the business semantics should be. Must both additions survive? Should only one release win? Are two documents allowed to coexist? Those answers determine whether you need a conditional update, an immutable key per release, an external transaction, or a single publication owner.
The interviewer may ask which writer “really happened last.” Client start times and wall clocks are insufficient evidence for a global ordering claim. Use successful responses, returned identifiers, and the observed current state. Design the protocol so correctness does not depend on guessing timing.
How do conditional writes change the race?
Official fact: S3 conditional writes support checking that a current object does not exist with If-None-Match: *, or that its ETag matches an expected value with If-Match. A failed condition can return 412 Precondition Failed; concurrent operations can produce other documented outcomes. See conditional writes.
For our exercise, both writers read the initial document and its ETag. Writer One conditionally replaces it. Writer Two's stale condition then fails if the current ETag has changed. The important improvement is visible conflict, not automatic merging.
An original application sketch is:
read current manifest and ETag
build proposed manifest using the required business operation
conditionally replace current manifest using that ETag
if precondition fails:
read current state again
decide whether the operation is still valid
recompute, reject, or ask the publication coordinator
Do not retry the same stale body unconditionally after a conflict. That recreates the lost-update bug. If the operation means “add artifact C,” recompute from the current document; if it means “publish release only if approval still applies,” revalidate that approval too.
Bound retries and make conflicts observable. Under sustained contention, unlimited retries can turn a publication problem into a traffic and latency problem. An interviewer should hear your conflict policy, retry limit, and escalation path rather than only the name of an HTTP header.
Also ask how all writers follow the protocol. A carefully implemented conditional writer can still be overwritten by a separate tool that performs unconditional updates. Inventory the publication paths and constrain them appropriately.
Is an ETag a version number or a universal MD5 checksum?
Official fact: An object's ETag is not always an MD5 digest, including multipart and certain encryption cases. Metadata-only changes do not necessarily change it. AWS documents separate checksum mechanisms for integrity verification. See checking upload integrity.
Use an ETag according to the conditional-operation contract, and use the chosen checksum contract to verify bytes. Do not convert every ETag into a content hash in your design because a small demonstration upload happened to resemble one.
Engineering inference: An ETag comparison also should not be presented as proof that no historical change occurred. If content returns to an earlier representation, an application that cares about intervening transitions needs a stronger application revision protocol. Include an explicit generation or operation identifier in the manifest when that history matters, and enforce its handling across writers.
For the release exercise, a content checksum answers “Are these artifact bytes what I expected?” A version ID answers “Which retained S3 version am I referring to?” An application generation answers “Which publication decision does this represent?” Keep those identifiers separate in logs and review explanations.
What does versioning preserve, and what does it not prevent?
Official fact: S3 Versioning retains multiple versions of an object so overwritten or deleted content can be recovered. Versions have distinct identities and consume storage. See S3 Versioning.
Versioning can make the lost-update incident recoverable, but it does not merge B and C into a correct current manifest. The application still needs to decide which historical content to restore or combine. “We enabled versioning” is therefore a recovery statement, not a complete concurrency answer.
Official fact: A simple delete in a versioning-enabled bucket can create a delete marker. A request for the current object can then behave as if the object were deleted even though older versions remain. See delete markers.
In an interview, distinguish deleting the current key without a version ID from permanently deleting a specified version. Ask which operation occurred, which version is now current, and what permissions and retention configuration apply. Do not describe all deletes as irreversible or all versioned deletes as harmless.
Our original recovery exercise starts with a bad manifest publication. Preserve the current version ID and inspect the intended earlier version. Validate its artifact references, then publish the approved recovery state through the same conflict-aware process. Blindly restoring an old document could discard a valid release that arrived during investigation.
How can you publish several artifacts without a multi-key transaction?
The original design below uses immutable release content and a small publication pointer. It is an application protocol, not a built-in S3 transaction:
- Assign an application release identifier and upload artifacts under unique keys.
- Verify required objects and their integrity before publication.
- Write an immutable manifest naming that release's exact artifacts.
- Conditionally update the current pointer using the expected prior state.
- Have readers follow one selected manifest rather than independently discover “latest” files.
A failed artifact upload leaves the old pointer in place. A failed pointer condition leaves an unpublished release that can be reviewed or cleaned up later. This separates preparation from publication without claiming the preparatory writes were atomic together.
State the reader contract. If a reader fetches the pointer once and then follows immutable references, it can continue using that release even if another publication happens mid-request. If it repeatedly fetches “current” for every file, it may assemble a mixture of releases despite strong consistency at each key.
Garbage collection needs the same care. Retain content while active readers or rollback policy may require it. A pointer moving forward does not prove every reader has stopped using the previous release. Define a retention window or another reference-management mechanism appropriate to the application.
Why might a user still see old content after publication?
Official fact: S3 replication copies objects asynchronously across buckets. A source write's success is not proof that a destination already contains the same state. See S3 replication.
First identify which bucket, key, version, and endpoint served the response. Then separate origin state from caches and application state. An old response at a CDN or in-process cache belongs to a different freshness contract from a direct read at the source bucket.
For the manifest exercise, record the release identifier in a response header or diagnostic record where appropriate. That lets you compare what a user received with what the publisher intended. A timestamp alone may be difficult to interpret when requests overlap or clocks differ.
If a client timed out during publication, treat the outcome as uncertain until reconciled. It may have lost the response after the write succeeded. Read the relevant state and compare the operation identifier before starting an unrelated replacement. Business idempotency means recognizing the same publication intent, not assuming every network retry creates a new release.
What should a concurrency test demonstrate?
Use a controlled environment and two writers with a barrier after their initial read. Record expected results before allowing both to proceed. For unconditional replacement, the exercise should reveal lost business updates. For conditional replacement, it should surface a conflict that the application handles deliberately.
Add a delete during publication, an uncertain client response, and a reader that begins before the pointer changes. Verify the reader sees a coherent release, not merely that every API call returns a status code. Record version IDs, application generation, conditional outcomes, and checksums without exposing credentials.
These are proposed tests, not results run for this article. Their value in an interview is that each test targets a specific contract and would falsify a specific claim.
Practice storage semantics with these interview questions
The verified records below support adjacent practice. The follow-ups are original and do not claim their original interviewers asked about this exact manifest protocol.
| Interview question | S3-specific follow-up |
|---|---|
| Design an S3-like object storage service | Separate per-key atomicity from application transactions. |
| Fetch Public S3 Object Metadata | Explain ETag, version identity, and integrity checks. |
| Design a production file storage service | Publish metadata without exposing incomplete file sets. |
| Design highly available blob storage service | Define source consistency and replication freshness separately. |
| Design VPC, IP plan, management, storage, SSO | Identify the actual storage endpoint and recovery boundary. |
Continue with Design an S3-like object storage service. Explain the two-writer table, then change the requirement from “one winner” to “preserve both additions.” Your conflict-handling logic should change with it.