A successful rename() can replace an existing pathname without exposing an interval in which that destination name is absent. That visibility property makes rename a common publication boundary for configuration files, checkpoints, manifests, and other file-backed state. It does not, by itself, establish that the replacement survives an abrupt loss of power.

The distinction is between namespace atomicity and persistence. Atomic replacement constrains what concurrent observers can see while the system is running. Crash durability concerns which writes and metadata changes are guaranteed to remain after volatile state disappears. Treating those properties as equivalent creates a gap precisely at the failure boundary that atomic replacement is often intended to protect.

Rename changes a directory entry as one namespace operation

For POSIX rename semantics, replacing an existing non-directory destination keeps the destination name visible throughout the operation. Other threads resolving that name see either the prior object or the replacement rather than an intermediate missing pathname.

That property is stronger than an update sequence built from explicit removal and creation:

unlink("config")
rename("config.tmp", "config")

The explicit unlink creates a period in which config has no directory entry. A reader arriving in that interval can receive a not-found result. A direct replacement avoids that gap:

rename("config.tmp", "config")

On systems implementing the relevant POSIX semantics, the destination entry is replaced atomically when the operation succeeds and its preconditions are satisfied.

Atomicity here is scoped to the namespace operation. It does not mean that every byte written to the source file becomes durable as part of the same event.

File contents and directory metadata are different persistence objects

A replacement normally begins by creating a temporary file, writing new contents, then renaming it over the destination. Two categories of state have changed by that point.

The file contains newly written data. Separately, the directory contains metadata associating the destination name with the replacement file.

Those changes can pass through different buffering and persistence paths. A successful write can leave data in volatile caches. A successful rename can update the in-memory filesystem view before the associated directory metadata is durably recorded.

This produces a sequence with distinct boundaries:

write replacement bytes
sync replacement file
rename temporary name to final name
sync containing directory

The exact synchronization calls and guarantees depend on the operating system, filesystem, mount options, storage stack, and API contract. The sequence is therefore a model of separate obligations, not a portable claim that one recipe has identical crash behavior on every storage system.

The key constraint is simpler: publishing a name and making the publication durable are separate operations unless a documented interface explicitly combines them.

Synchronizing the file does not persist the rename

Calling a file synchronization primitive on the temporary file can establish persistence guarantees for that file’s data and required metadata according to the platform contract. The later rename still changes a directory entry.

If the application requires the new pathname association to survive a crash, synchronizing only the file leaves the namespace mutation outside the durability boundary. The file’s bytes may be persistent while the directory entry selecting that file is not yet guaranteed persistent.

This is a useful separation when reviewing crash-consistency code. A file descriptor names an opened file object; the containing directory records pathname relationships. Persisting one does not automatically imply persistence of every later mutation to the other.

The reverse ordering also matters. Renaming a temporary file before its contents have reached the required persistence boundary can make the new version visible to running processes while its data is still vulnerable to a crash. Atomic visibility can therefore precede durable contents.

Replacement is not the same as in-place mutation

An in-place rewrite has a different failure surface. Truncating the destination and then writing new bytes exposes the same pathname throughout, but readers can observe a shortened or partially rewritten file unless additional coordination prevents access during the update.

Temporary-file replacement shifts publication to a namespace operation. The replacement file can be assembled under another name, validated by the writer, and then made visible at the final name in one rename operation.

This pattern protects readers from many intermediate application states, but only when their access path actually goes through the replaced pathname. A process that already holds an open descriptor for the old file can continue referring to the old file object after the rename. Rename changes names; it does not retarget existing open descriptors.

That behavior can be useful. Existing readers can finish against the prior object while new pathname resolutions reach the replacement. It also means an application cannot infer that all consumers immediately switch versions at rename time.

Cross-filesystem moves have a different contract

POSIX rename can fail with EXDEV when source and destination reside on different filesystems and the implementation cannot perform the operation across that boundary.

Command-line move utilities may hide this distinction by falling back to copy-and-remove behavior. Such a fallback is not equivalent to a single atomic rename. Copying introduces a period during which the destination is being constructed, and interruption can leave state that the same-filesystem rename path would not produce.

Code that relies on atomic publication therefore needs the temporary file in a location compatible with the final rename operation. A generic temporary directory can accidentally place the source on another filesystem.

The relevant boundary is the filesystem namespace in which the rename primitive provides its atomic semantics, not the superficial fact that both paths are reachable from one process.

Network filesystems can alter failure interpretation

Remote filesystems add another boundary between client-visible return values and server-side effects. Linux documentation for rename() notes an NFS case in which a server can perform a rename, crash, then cause a retransmitted operation to report failure after recovery.

That means an error return cannot always be interpreted as proof that the namespace remained unchanged. Distributed request retry semantics can make the operation’s outcome uncertain from the client’s local observation.

Applications operating on such storage need to separate operation status from verified state. This is the same class of issue seen in remote APIs: a response can be lost after the server has committed an effect.

The local atomicity model remains useful, but error handling must match the storage protocol rather than assuming local-system-call failure semantics extend unchanged across a network boundary.

Atomic publication still needs a recovery contract

A robust file update protocol states which post-crash states are acceptable. For a replaceable configuration file, the contract might permit either the complete old version or the complete new version, while rejecting a missing pathname or partially constructed content.

Atomic rename helps enforce the visibility portion of that contract. Synchronization and filesystem guarantees address the persistence portion. Recovery code may add another layer by validating format, checksums, sequence numbers, or paired metadata before accepting a file after restart.

Those mechanisms solve different problems. A checksum can detect corruption or incompleteness but does not make a rename durable. A rename can provide an atomic namespace switch but does not validate application content. File synchronization can request persistence but does not define which version recovery should select when several valid artifacts exist.

Keeping these roles separate makes crash behavior inspectable. The publication point is the rename. The persistence boundary comes from documented synchronization semantics. The recovery policy decides which durable artifacts are admissible after restart.

Atomic replacement is therefore a namespace guarantee with a precise scope. It can remove a visibility gap for concurrent pathname resolution, yet durability still depends on the storage contract surrounding the file data and the directory mutation. Systems that need both properties have to establish both boundaries explicitly.