ReliabilityGENERALFORMAT-SPECIFICCLOUD-SPECIFICWAREHOUSE-SPECIFIC

Atomic Publish

A consumer must never read a half-written dataset. Build somewhere they are not looking, validate it there, then make it visible in one operation — and know which of the available operations is genuinely one.

What actually happensHow to build itCan I trust it?

Who needs this, what one row is, and why the obvious build breaks

Every lesson starts from the consumer, because designing from the source outward is this domain's characteristic mistake.

The question

A query runs at 02:14 while the nightly load is halfway through rewriting fct_orders. What does it see, and what should it have seen?

Who needs this

Any reader that arrives at an arbitrary moment: a dashboard refresh, a scheduled export, a downstream transformation whose own run does not coordinate with yours, a reverse-ETL sync pushing to a CRM. None of them ask permission and none of them can tell a partially built table from a complete one — a table with half the day's rows looks exactly like a quiet day (Stale Dashboards).

What one row is

The unit of atomicity is whatever becomes visible in one operation: a whole table, one partition, one snapshot of a table format. Everything inside that unit is all-or-nothing; everything outside it is not. A pipeline that writes twelve partitions "atomically" one at a time has twelve atomic publishes and no atomic run, and a consumer joining across partitions can still see an inconsistent whole.

The obvious build

Truncate the target table and insert the new rows, or write the day's files straight into the partition directory the query engine reads. It is one statement, it is obvious, it needs no staging area, and for a table that is only read during business hours by people who know when the pipeline runs, it genuinely never causes a problem.

Why it breaks

A dashboard refreshes during the write window and reports the day as ninety percent lower than it was. Nobody screenshots it, the next refresh looks fine, and the only lasting artifact is a small permanent reduction in how much anyone trusts the dashboard (Trusting Data).

How it breaks with real data
  • A dashboard refreshes during the write window and reports the day as ninety percent lower than it was. Nobody screenshots it, the next refresh looks fine, and the only lasting artifact is a small permanent reduction in how much anyone trusts the dashboard (Trusting Data).
  • A downstream transformation reads the table mid-write, succeeds, and materialises the partial state into its own output — where it stays after the upstream table is complete, because nothing recomputes it (The Transformation DAG).
  • The load fails after eight of fourteen statements. The table is now a state that no correct run would ever produce, and there is no marker anywhere recording that fact (Partial Failure).
  • The truncate succeeds and the insert fails. The table is empty. Every consumer sees zero, every freshness check passes because the table was modified seconds ago, and the volume check fires — if one exists (Volume Anomalies).
  • On object storage, the "publish" is a rename of _tmp/ to dt=2026-08-25/. The rename is executed as a copy of every file followed by a delete of every original, so for a period proportional to the data size the destination contains some of the new files and none of the old ones (Object Storage as Data Infrastructure).
SourceIngestionRawTransformationValidationStorage ModelServingConsumerObservability

What is actually happening

  • Atomicity is a property of a visibility switch, not of a write. The bytes can take an hour to land; what must be instantaneous is the moment at which readers stop resolving the old version and start resolving the new one. Every real implementation is therefore some form of pointer swap (Transactions and ACID).
  • In an open table format, the pointer is a metadata file. A writer produces new data files, writes a new manifest and metadata object describing which files constitute the table, and then atomically updates the single reference that says which metadata object is current. Readers resolve that reference at query start and see a consistent set of files for the whole query (Open Table Formats).
  • In a warehouse, the pointer lives inside the system catalog and the swap is a catalog transaction — a CREATE OR REPLACE, an INSERT inside an explicit transaction, or a table rename performed as a metadata operation. The warehouse owns both the data and the catalog, which is what lets it make the two consistent (The Data Warehouse).
  • On plain object storage with a directory convention, there is no pointer and there is no directory. Keys are flat strings; a prefix is a naming convention that listing APIs let you filter on. A rename is not an operation the store provides — clients implement it as copy-then-delete per object, which is neither atomic nor cheap, and a reader listing the prefix midway through sees whatever subset has been copied so far.
  • The reason the third case is dangerous is that it *looks* like the second. The code says rename, the file browser shows folders, the mental model is a filesystem, and the failure only appears under concurrency or size — which means it appears in production and not in the test.
  • Validation belongs in the gap the pointer creates. Because the new version exists as real, queryable data before it is visible, you can run assertions against it with ordinary queries and abandon the publish if they fail — which is the single largest practical benefit of the pattern and the one most often left unimplemented (Data Tests).

Build it where nobody is looking

The pattern is three steps and its whole value is in the order of them. Build the new version somewhere consumers do not resolve. Validate it there, as real data, with ordinary queries. Then flip visibility in a single operation. The validation step is only possible because the build step produced something queryable but invisible, which is the non-obvious part.

Notice what each stage promises the next. The build promises nothing except that the bytes exist; it is allowed to fail, to be abandoned, and to leave garbage behind. The validation promises that the assertions you wrote hold — no more. The swap promises that every reader after it sees the whole thing and every reader before it saw the whole previous thing.

The cleanup stage is in the table because it is where the pattern most often erodes. Deleting the previous version immediately after the swap turns a reversible publish into an irreversible one, and it usually happens for a good reason — storage was growing — with nobody connecting the change to the rollback promise it silently cancelled.

The publish path, and what each stage actually promises
  1. 1
    Build

    Computes the new version of the unit into a staging table, a new snapshot, or a temporary prefix that no consumer resolves.

    guarantees Only that the output exists and is queryable. Explicitly does not guarantee correctness, completeness, or that it will ever be published.

    fails by Being written somewhere a consumer can in fact find — a catalog-registered staging table that someone builds a dashboard on.

  2. 2
    Validate

    Runs assertions against the staged version: counts against the source, uniqueness on the business key, null rates, measure bounds.

    guarantees That the assertions you wrote hold on this unit. Nothing about the properties you did not encode.

    fails by Running after the swap instead of before it, which converts a protection into a detection.

  3. 3
    Swap

    Makes the new version visible in one operation: a catalog transaction, a metadata pointer update, an atomic conditional write.

    guarantees All-or-nothing visibility of this unit. Says nothing about other units published by other operations.

    fails by Being a copy-then-delete rename that only resembles an atomic operation, or being several swaps that a reader can observe between.

  4. 4
    Retain

    Keeps the previous version addressable for the length of the stated rollback window.

    guarantees That an undo exists, and for how long. This is the guarantee a rollback runbook depends on.

    fails by Being shortened for storage reasons without the rollback promise being updated, so the runbook stays true on paper only.

  5. 5
    Clean up

    Removes abandoned staging output and versions older than the retention window.

    guarantees That storage and metadata do not grow without bound.

    fails by Removing the version a rollback needed, or never running, so listing costs grow until a query planner starts to notice.

Read the guarantees column as a chain of what is safe to assume at each point. The most common design error is to treat the build's output as trustworthy because it is queryable — it is queryable precisely so that it can be doubted before anyone else sees it.

Three swaps, and one that only looks like a swap

CLOUD-SPECIFICObject stores differ in what conditional-write primitives they expose, and a Hadoop-style distributed filesystem does provide an atomic directory rename — which is why publish code lifted from an HDFS-era codebase onto object storage silently loses its correctness while continuing to compile and pass tests.

Every implementation of atomic publish reduces to updating a single reference. The question is which reference and who guarantees the update. Get that answer wrong and you have written a publish path that is correct on your laptop, correct in the test with one small file, and wrong in production under a real dataset.

The first two rows below are genuine mechanisms with a named guarantor. The third is the one to internalise: on an object store there is no directory to rename, so the client library implements the rename as a listing followed by a copy of every object followed by a delete of every original. For the duration of that loop the destination prefix holds a mixture. It is not slow-but-atomic; it is not atomic.

The fourth row is the honest workaround for a lake with no table format: never rename anything, write each version to its own immutable prefix, and move a small pointer — a manifest object, a catalog partition location, a symlink table — that a single atomic write can update. It is exactly what table formats do, implemented by hand, and it is worth understanding that way rather than as magic.

MechanismWhat is actually swappedWho guarantees atomicityWhere it fails
Table-format snapshot commitThe single reference naming the current metadata object, which lists the files that constitute the table.The catalog or the store's conditional-write primitive, via a compare-and-set on that one reference.Concurrent writers colliding on the same reference — resolved by retrying the commit, which means the *commit* must be idempotent too.
Warehouse catalog transactionThe catalog entry mapping a table name to its storage, inside the warehouse's own transaction.The warehouse, using the same machinery that gives its ordinary transactions atomicity.Multi-statement publishes where the engine does not support explicit transactions, so each statement is separately visible.
Object-store directory renameNothing. There are no directories; a prefix is a listing convention over flat keys.Nobody. The client performs a copy per object and then a delete per object.Any reader listing the prefix during the loop, and any failure partway through, which leaves both prefixes partially populated.
Manual pointer objectA small manifest or location value that a reader consults to find the current immutable version prefix.The single atomic write of that one small object, or the catalog operation that updates a partition location.Readers that resolve the pointer and then take a long time to list — and any process that writes data directly to the version prefix after publish.

The pattern common to every working row is that exactly one small thing changes and everything else is immutable. Any design where publish means mutating a large amount of data in place has no atomicity to offer, whatever the API is called.

Product detail — verify current documentation

Which conditional-write and multi-object capabilities a given object store offers, and which table-format specification versions a given engine can read and write, both change between releases. Verify against current documentation for the specific store and engine before relying on either — the architectural point (one small atomic reference, everything else immutable) is what is stable.

Writing the publish path

The warehouse case is short enough to write in full, and writing it in full is the point: the difference between the unsafe and safe versions is four lines, and teams frequently have the unsafe one because it was written before the table had a second reader.

The critical property of the safe version is not the transaction keyword. It is that the target is never in a state that a correct run would not produce: it holds either the previous partition or the new one, never a partial one and never none. The DELETE and the INSERT being in one transaction is what makes "never none" true, and it is the half people omit.

For a partitioned lake table the same shape holds with different verbs: write files to a new location, run the assertions against that location, and then commit the file list — as a snapshot in a table format, or as a partition-location update in a catalog. What must not appear anywhere in either version is a write to the location a consumer resolves.

Write into the table consumers read
Point the transformation at `fct_orders` directly. Delete the day, insert the day. Run the data tests on a schedule afterwards and alert if they fail.
Build aside, assert, swap
Build the day into a staging object. Run the assertions against it. Replace the unit in one atomic operation only if they pass, and keep the previous version addressable for the rollback window.

A test that runs after publish can only tell you how long consumers were reading wrong data; it cannot prevent it. Moving the same test in front of the visibility switch converts detection into protection at the cost of one extra write and a few minutes of delay — and it is the only arrangement in which "we validate our data" is a statement about what consumers see rather than about what we later discover.

Replacing one partition-day without ever showing a partial state
1-- UNSAFE: three separately visible states, and a window with no data at all.
2DELETE FROM fct_orders WHERE order_date = DATE '2026-08-25';
3INSERT INTO fct_orders SELECT ... FROM stg_orders WHERE order_date = DATE '2026-08-25';
4-- ^ a reader between these two statements sees the day as empty,
5-- and a failure between them leaves it empty until someone notices.
6
7-- SAFE: build, assert, then one atomic replacement of the unit.
8CREATE OR REPLACE TABLE staging.fct_orders_20260825 AS
9SELECT ... FROM stg_orders WHERE order_date = DATE '2026-08-25';
10
11-- Assertions run against the staged unit. Any row returned aborts the publish.
12SELECT 'duplicate_key' AS violation, order_id, COUNT(*) AS n
13FROM staging.fct_orders_20260825
14GROUP BY order_id HAVING COUNT(*) > 1
15UNION ALL
16SELECT 'null_measure', CAST(NULL AS VARCHAR), COUNT(*)
17FROM staging.fct_orders_20260825 WHERE net_amount_minor IS NULL
18HAVING COUNT(*) > 0
19UNION ALL
20SELECT 'count_vs_source', CAST(NULL AS VARCHAR), COUNT(*)
21FROM staging.fct_orders_20260825
22HAVING COUNT(*) <> (SELECT COUNT(*) FROM src_orders_20260825);
23
24-- Only now, and only if the assertions returned nothing:
25BEGIN;
26 DELETE FROM fct_orders WHERE order_date = DATE '2026-08-25';
27 INSERT INTO fct_orders SELECT * FROM staging.fct_orders_20260825;
28COMMIT;

The assertions are ordinary queries against ordinary data, which is only possible because the staged version is real. Note that the safe publish is still a delete-and-insert — atomicity comes from the transaction around them, not from avoiding them, and on an engine without multi-statement transactions this exact code is unsafe and a partition-swap or snapshot commit is required instead.

What still goes wrong once you have it

Teams that adopt this pattern do not stop having publish incidents; they have different ones. The failures move from "a reader saw half a table" to "the publish path itself has a hole", and those holes are more specific and more findable — which is progress, but only if you know what to look for.

The two worth internalising are the cross-table case and the retention case. Atomic publish is a per-dataset mechanism, so a dashboard joining two independently published tables can still read an inconsistent pair, and no amount of per-table rigour addresses it. The remedy is either publishing related datasets in one transaction where the engine allows it, or accepting the inconsistency explicitly and making consumers aware of the window.

The retention case is quieter. The rollback window is a promise made by a cleanup job, and cleanup jobs are tuned for storage rather than for promises. When the two diverge nobody notices until the day a rollback is needed and the previous version is gone.

Failure modes of a publish path that already exists
TriggerSymptomCauseResponse
Two writers commit to the same table concurrently.One commit fails with a conflict, or worse, one silently overwrites the other's file list.The atomic reference update is a compare-and-set; two writers racing means one must lose and retry.Make commit retries idempotent and serialise writers per table. Losing the race must cost a retry, never a lost publish (Optimistic Concurrency: Versions and If-Match).
A dashboard joins two tables published minutes apart.New facts join against an old dimension; a small number of rows fall into an "unknown" bucket and then stop doing so an hour later.Atomicity is per dataset. Nothing coordinates two independent publishes.Publish related datasets in one transaction where the engine supports it, or publish the dimension first and design the fact to tolerate it (Dimension Tables).
Cleanup retention shortened to control storage growth.A rollback runbook that claims a seven-day window finds two days of versions.The rollback promise lives in a document and the retention lives in a job, and nothing connects them.Derive the cleanup threshold from the stated rollback window in configuration, so shortening one visibly changes the other (Rolling Back Data).
The staging table is registered in the catalog and discovered by a curious analyst.A dashboard reads a location with no publish discipline and shows data that appears and disappears.Staging output is real, queryable data; the only thing making it private is convention.Put staging in a schema with access restricted to the pipeline identity, and audit for queries against it (Data Access Control).
Validation passes because the source query and the staged query share a broken filter.A perfectly reconciled publish of incomplete data.The assertion compares two things derived from the same wrong expression.Compare against the source system independently of the transformation logic, not against a restatement of it (Reconciliation).
Publish succeeds; the downstream table that read the previous version is not rebuilt.The upstream is correct and a derived mart still holds the old numbers.Atomic publish makes one dataset consistent; it does not propagate.Trigger downstream rebuilds on publish events rather than on a clock, so correction flows as far as the error did (The Transformation DAG).

How to build it

Most important first.

  • Write to a location no consumer resolves: a staging table, a new snapshot, a temporary prefix. It must be real enough to query and invisible enough that abandoning it costs nothing but storage.
  • Validate there, with the assertions that would embarrass you if they failed in production: row count against the source, uniqueness on the business key, non-null on the columns downstream joins on, and a sanity bound on the primary measure (The Dimensions of Data Quality).
  • Publish with one operation whose atomicity you can name. If you cannot say what makes it atomic — a catalog transaction, a metadata pointer update, a conditional write — then it is not atomic and you are relying on the write window being short (Open Table Formats).
  • Prefer replacing a unit over mutating a table. CREATE OR REPLACE for small tables, partition-level replacement for large ones, snapshot commits where the format gives them. Mutation in place is where partial states come from.
  • Keep the previous version reachable after the swap, for as long as your rollback window claims to be. The publish and the rollback are the same mechanism read in two directions (Rolling Back Data).
  • Make the publish itself idempotent: publishing the same validated unit twice must be indistinguishable from publishing it once, because a retry will do exactly that (Retries in Pipelines).
  • Publish once per unit, not once per statement. Fourteen sequential visible writes are fourteen observable states; one swap at the end is one.

What this actually promises

Naming the guarantee you do not have is worth more than naming the one you do — everything downstream inherits the weakest promise in the chain.

  • A metadata pointer swap in a table format guarantees that a reader resolving the table sees one complete file set, and that a reader who started before the swap continues to see the old one for the duration of its query. It does not guarantee anything across two tables published separately.
  • A warehouse transaction guarantees atomicity and isolation according to the warehouse's own model — which is usually snapshot isolation for readers and single-statement or explicit-transaction atomicity for writers. Read the specific engine's documentation rather than assuming (Isolation Levels).
  • A copy-then-delete "rename" on object storage guarantees nothing at all about intermediate states. Individual object writes are atomic per object; nothing composes that into a multi-object guarantee.
  • Nothing here guarantees cross-dataset consistency. If a dashboard joins fct_orders and dim_customer and each publishes independently, a reader can observe a new fact against an old dimension — an inconsistency no per-table mechanism addresses (Star Schema).
  • Atomic publish guarantees nothing about correctness. It guarantees only that whatever you publish becomes visible all at once, which is why the validation step is not optional decoration.

Can I trust it?

A green pipeline is evidence that code ran. These four fields are the evidence that the data is right.

The check that would catch this
  • The check the pattern exists to enable: run the full assertion suite against the staged version and gate the swap on it. Row count within tolerance of the source for the period, uniqueness on the key, null rates within their historical band, and the measure inside a plausible range.
  • What it still misses: anything that is wrong in both the source and the staged output, anything about periods that are still open, and anything the assertions do not encode — which is every semantic error (Semantic Changes).
  • The check on the mechanism rather than the data: assert that no consumer-visible table was written outside a publish operation. In practice this means auditing for direct writes, and finding them, because there is always one job that predates the convention.
Freshness
  • The pattern delays visibility by the duration of the validation plus the swap. That is real and it is the price: data that would have been readable in pieces from 02:03 becomes readable as a whole at 02:11.
  • It also makes freshness *meaningful*. Without an atomic publish, "the table was updated at 02:07" describes a moment inside a write and tells a consumer nothing about completeness; with one, the publish timestamp is exactly the moment the unit became complete, which is the number a freshness SLO needs (The Freshness SLO).
  • For streaming sinks the same logic applies at a smaller unit: a commit interval is a publish cadence, and shortening it trades more frequent visibility for more metadata operations and more small files (File Size and the Small-Files Problem).
When the schema or meaning changes
  • Adding a column to a staged build and publishing atomically is safe for readers that name their columns and hazardous for readers that do not, which is one more reason SELECT * in a downstream model is a reliability problem rather than a style one.
  • Changing the publishable unit — from whole-table replace to partition replace — changes what atomicity covers. A consumer that previously could not see a partial table now can see a partially refreshed set of partitions, and nobody is told (Schema Evolution).
  • Table formats evolve their own metadata versions. A writer on a newer specification and a reader on an older one is a compatibility question about the *pointer*, not about the data, and it fails in ways that look like corruption (Backward Compatibility).
How to re-run this safely
  • The abandoned staging location is the cheapest recovery there is: a failed validation costs storage and a re-run, and no consumer ever knew.
  • After a bad publish, recovery is a second publish — either of the retained previous version or of a corrected rebuild. Formats that keep snapshots make the first a metadata operation; warehouses that keep time-travel windows make it a query (Rolling Back Data).
  • Cleaning up orphaned staged files is a real operational task, not a detail. A publish path that fails often enough leaves a prefix full of data nobody references and every listing operation has to walk (File Compaction).

What can go wrong

Failure modes
  • A directory rename on object storage treated as atomic, which is the single most common instance of this failure and the hardest to see in code review.
  • Validation running after the swap instead of before it, so the pattern costs latency and buys detection rather than protection.
  • The swap succeeding and the cleanup of the previous version running immediately, removing the rollback target in the same run that created the need for it.
  • Two tables published independently and joined downstream, producing a consistent read of each and an inconsistent read of the pair.
  • A consumer holding a long-running query across a publish and seeing a mixture, on engines whose isolation model does not pin the file set at query start (Query Engines).
  • The staging location itself being registered in the catalog "for debugging", after which someone builds a dashboard on it and it becomes a consumer-visible table with no publish discipline at all.
Misreads
  • "We use object storage, so writes are atomic." Individual object writes are atomic. Nothing composes that into an atomic multi-file publish, and the "directory" you are renaming does not exist (Object Storage as Data Infrastructure).
  • "The write window is only a few seconds, so nobody will see it." Somebody will. Scheduled exports fire on the minute, dashboards refresh on timers, and the probability of an unlucky read is not zero — it is small, which means it happens rarely and is never reproducible.
  • "Atomic publish means the data is correct." It means all of it appears at once. Whether it is right is a question for the assertions you put in front of the swap.
  • "Truncate-and-insert inside a transaction is fine." In a warehouse that supports it, yes. On a lake with a directory layout, there is no transaction to be inside, and the same SQL means something completely different.
  • "Snapshots make this free." They make the swap cheap. They do not make validation happen, they do not bound how many snapshots you retain, and they do not coordinate two tables with each other.

Operating it

How you see it in production
  • A publish ledger: unit, version, publish timestamp, run id, validation outcome. It answers "when did this become complete" and "which run produced what is visible now" without archaeology (Pipeline Metrics).
  • Snapshot or version count per table, trended. A table whose version count is not growing has stopped publishing; one growing far faster than its schedule is being republished by retries (Freshness Monitoring).
  • Storage held by staged and orphaned locations, because it grows monotonically until someone looks (What Actually Drives Data Platform Cost).
  • Queries executed against staging locations — if any exist, the boundary has leaked and the staging area has quietly become production (Data Lineage).
What changes at 10x and 100x
  • At 10x, full-table replacement stops fitting the window and the unit must become the partition. Publish moves from one swap per run to many, and per-unit tracking becomes necessary rather than tidy.
  • At 100x, metadata itself becomes the constraint: a snapshot listing hundreds of thousands of files takes real time to write and to plan against, and compaction of both data files and metadata becomes a scheduled job with its own reliability requirements (File Compaction).
  • More consumers do not change the publish mechanism but sharply raise the cost of getting it wrong, because a partial state observed by eighty readers is eighty derived artifacts to check (Impact Analysis).
What drives cost here
  • The output is written twice in the copy-based variants: once to staging, once at publish. In pointer-swap formats it is written once and only metadata is rewritten, which is the main architectural argument for them at scale (Open Table Formats).
  • Validation costs a full read of the staged unit. That read is the cheapest scan in the pipeline relative to what it prevents, and it is also the first thing removed when someone is optimising a schedule.
  • Retaining previous versions costs bytes for the length of the rollback window. Longer windows cost more storage and buy a longer period in which a mistake is undoable (Storage Lifecycle).
  • The copy-then-delete rename costs a full data copy per publish and grows linearly with the unit size, which is why it becomes both slow and expensive at exactly the scale where its lack of atomicity starts to bite.
What this approach costs
  • Latency for safety: the data is complete later than it was readable in pieces. For most analytical consumers this is trivially worth it; for a near-real-time serving table it is a genuine design tension resolved by making the unit smaller rather than by abandoning the pattern.
  • Storage for reversibility: staging plus retained previous versions is a standing cost against an occasional event.
  • Complexity for observability: the pattern introduces a publish step that can itself fail, and a staging area that can itself accumulate. That is a real operational surface, and it is smaller than the surface of not having it.

Where this applies

Almost nothing here is universal. These labels say what each claim is specific to, and where a different engine, format, warehouse or scale would differ.

  • GENERALThe build-validate-swap shape holds anywhere readers and writers share a dataset without coordination. What varies completely is which operation is genuinely atomic, and that is a property of the storage layer rather than of the pipeline.
  • FORMAT-SPECIFICOpen table formats implement the swap as an atomic update of a single current-metadata pointer, which is what gives files snapshot isolation. Plain Parquet or CSV under a directory convention has no such pointer, so the identical directory layout gives no atomicity at all — the format, not the file type, is what carries the guarantee.
  • CLOUD-SPECIFICObject stores expose no atomic multi-object operation and no true rename: keys are flat and a prefix is a listing convention. Some stores offer an atomic single-key conditional write that a metadata pointer can be built on, and HDFS-style filesystems do offer an atomic directory rename — so code moved between them changes its correctness, not just its performance.
  • WAREHOUSE-SPECIFICWarehouses own their catalog and can make a replace or a rename a metadata transaction, but they differ in whether multi-statement transactions are supported, what isolation readers get, and how long prior versions remain addressable. Those three answers decide the publish design and none of them is portable.

Where the depth lives

This domain teaches how data moves and how you know it arrived intact. It hands the rest off by name.

Domains that do not exist yet
  • Distributed Systems owns why a multi-object update cannot be made atomic without a coordinator, and what the available coordination primitives cost. The reason atomic publish always reduces to swapping one small reference is that result, applied to storage.
  • DevOps / Production Engineering owns the analogous idea for code — blue-green and symlink-swap deploys are the same mechanism applied to artifacts — and the difference worth carrying across is that a deploy swap can be reversed by swapping back, while a data swap has already replaced what it replaced unless you retained it deliberately.