An inotify watch does not make a pathname a durable identifier. Linux attaches a watch to a filesystem object selected when inotify_add_watch() succeeds, then emits records describing activity associated with watched objects and directory entries. Names can move, objects can disappear, and event delivery can lose detail when the queue overflows.

That boundary matters for file synchronizers, configuration reloaders, indexers, and service supervisors. An event stream can signal that local filesystem state changed, but reconstructing authoritative state still depends on filesystem operations performed after the event.

A watch descriptor identifies a watch inside one inotify instance

inotify_init1() returns a file descriptor for an inotify instance. inotify_add_watch() associates a watch with that instance and returns a watch descriptor, commonly called wd. Event records read from the instance contain that descriptor, an event mask, a cookie used for related rename events, and an optional name.

The watch descriptor is not a pathname and is not a process-wide object identifier. Its interpretation belongs to the inotify instance that produced it. Applications therefore need their own mapping from wd values to the state they associate with each watch.

For a watched directory, an event can carry the name of a child entry. That name is relative to the watched directory. The record reports an event at the notification boundary; it does not freeze a globally stable path for later use.

Rename events expose correlation without making delivery transactional

Renaming within monitored directory coverage can produce IN_MOVED_FROM and IN_MOVED_TO events. Linux places the same nonzero cookie in related events so an application can correlate the old and new directory entries.

The cookie is useful metadata, but it does not turn the queue into a transaction log. Other events may occur between the pair, and a move can cross the boundary of what an application watches. In that case, only one side may be visible to that inotify instance.

A consumer also cannot treat the name carried by an earlier event as a promise that the same entry still exists when it later calls open(), stat(), or another pathname API. Filesystem state can change again between event generation, queue consumption, and the subsequent lookup.

The observable sequence is therefore closer to:

filesystem mutation
       |
 event queued
       |
 consumer reads event
       |
 fresh pathname lookup

Each boundary can be separated by concurrent filesystem activity.

Replacement separates a pathname from the watched object

A pathname can continue to exist while the object previously selected through that pathname is removed or replaced. This distinction is especially visible when software updates files by creating a new inode and renaming it over an existing name.

If a watch is attached directly to the old file, the watch follows that watched object rather than automatically transferring to a replacement object that later occupies the same pathname. Events such as IN_DELETE_SELF, IN_MOVE_SELF, and IN_IGNORED communicate relevant lifetime transitions depending on the operation and watch state.

Code that requires continuing coverage of a logical pathname must therefore define a reattachment policy. Watching the containing directory can provide entry-level signals for replacement, while a direct file watch can provide events tied to the selected object. Those are different observation contracts.

Queue overflow removes event-by-event completeness

The kernel stores pending inotify events in a bounded queue. If the queue overflows, Linux emits an IN_Q_OVERFLOW event. At that point, the consumer cannot assume that every intervening filesystem mutation is represented by a record it received.

This failure mode changes the recovery contract. Continuing to apply later events to a cached model can preserve an unknown gap. A robust design treats overflow as loss of incremental completeness and rebuilds the relevant state from authoritative filesystem observations before relying on the cache again.

The rescan is not evidence that inotify itself is unreliable. It is a consequence of a bounded asynchronous notification interface: producers can outpace the consumer, so the API explicitly exposes loss rather than promising an unbounded history.

Event coalescing also limits operation counting

Identical unread events can be coalesced by inotify. As a result, the number of records is not a general-purpose count of filesystem operations. A consumer that needs to know current state can use events as invalidation signals and then inspect that state directly.

This distinction is important for designs that attach business meaning to event counts. Notification semantics describe observable changes under the API contract; they do not provide an audit ledger of every underlying VFS operation.

For audit requirements, a system needs an interface whose guarantees match that purpose. inotify is designed for filesystem change notification, with explicit queue and coalescing semantics.

Watch removal is part of resource lifetime

A watch can be removed explicitly with inotify_rm_watch(), and the kernel can remove it when the watched object reaches relevant terminal conditions. IN_IGNORED reports that a watch has been removed.

Applications must account for both the inotify file descriptor lifetime and individual watch lifetimes. Closing the inotify descriptor releases watches associated with the instance. Before that point, each watch consumes kernel resources and participates in per-user limits.

A watch table is therefore application state with lifecycle transitions, not merely a static map created during startup. Reconfiguration, object deletion, replacement, and explicit removal can all change the set of valid watch descriptors.

Notifications are invalidation evidence, not retained identity

inotify is strongest when its role is kept narrow. It tells a process that filesystem activity relevant to its watches has occurred, provides masks and names that describe that activity, and supplies rename cookies for correlation inside the event stream.

It does not make pathnames stable, transfer a watch automatically to every future object at the same name, preserve an unlimited event history, or make each event record correspond one-to-one with an underlying operation.

Systems that need current filesystem truth can combine notification with fresh lookup or rescan. That separation preserves the useful property of inotify: efficient asynchronous change signals, bounded by explicit rules for object lifetime, directory-entry naming, queue loss, and event coalescing.