Skip to content

Topic archive

Software Engineering

Software Engineering covers developer tooling, architecture, maintainability, engineering workflows, protocols, and practices that improve how software is designed and built.

460 articles
Software Engineering 17 Sep 2026 8 min read

io_uring Shared Rings Make Memory Ordering Part of the ABI

An io_uring queue is shared memory with two independent execution domains changing its state. User space prepares submission entries and advances queue metadata; the kernel consumes those submissions and later publishes completion entries. The ring layout removes a copy boundary, but it also makes memory visibility part of the interface contract. A plain source-level assignment to a queue tail is not sufficient as a portable model of publication. The entry data must become visible before the tail value that makes the entry eligible for consumption. On the completion side, user space must observe the kernel’s publication of a completion before reading fields from that completion. The ordering relation is part of correctness, not merely an optimization detail.

Software Engineering 17 Sep 2026 4 min read

io_uring Multishot Accept Keeps One Request Active Across Connections

A Linux io_uring multishot accept request can produce several completion queue entries from one submission queue entry. The kernel keeps the accept operation active after a successful completion when the CQE carries IORING_CQE_F_MORE, so a server does not need to submit a fresh accept SQE for every connection. This changes the lifetime contract between submission and completion. A normal oneshot request is finished after its CQE. A multishot accept can remain in flight across many accepted connections, and the CQE flags determine whether that request still exists.

Software Engineering 17 Sep 2026 4 min read

inotify Rename Cookies Correlate Move Events Without Making Them Atomic

A Linux rename() observed through inotify can produce two records carrying the same nonzero cookie: IN_MOVED_FROM for the old directory entry and IN_MOVED_TO for the new one. The cookie correlates those records, but it does not turn them into one atomic queue item. That boundary matters for software maintaining a pathname index, synchronizing directory state, or converting filesystem notifications into higher-level change records. A rename is one filesystem operation while its inotify representation can be a pair whose delivery has weaker grouping properties.

Software Engineering 17 Sep 2026 8 min read

File-Backed Mappings Can Outlive the File Size They Assume

A process can retain a valid virtual memory mapping after another actor has shortened the mapped file. The address range still exists in the process, but the backing object may no longer contain every page that range once represented. On POSIX systems, an access to a whole mapped page beyond the new end can deliver SIGBUS rather than behaving like an ordinary failed file read. That boundary makes file-backed mmap() different from copying bytes into private heap storage. A pointer into a mapping is not proof that the corresponding file extent still exists. The virtual address, mapping lifetime, file identity, and current file size are related state, but they are not one indivisible object.

Software Engineering 17 Sep 2026 5 min read

eventfd Counter Coalesces Notifications Before Read

A Linux eventfd can receive several writes before any consumer runs, yet the descriptor does not retain those writes as separate messages. Each accepted write adds its unsigned 64-bit value to a kernel-maintained counter. Without EFD_SEMAPHORE, one successful read returns the current counter and resets it to zero. That behavior makes eventfd a counter-backed notification primitive rather than a message queue. Readiness indicates that the counter is nonzero; it does not preserve the number, ordering, or boundaries of individual write operations.

Software Engineering 17 Sep 2026 5 min read

EPOLLET Reports Readiness Transitions, Not Buffer Drainage

With EPOLLET, a file descriptor can still contain unread data after its readiness event has already been consumed. A later epoll_wait() is not required to report that descriptor again merely because the old readable state persists. That behavior is the central boundary of edge-triggered epoll: notification tracks changes in readiness, while the underlying I/O object retains its own state independently. Readiness state and event delivery are separate An epoll instance maintains an interest list and a ready list. Registration through epoll_ctl() defines which open file descriptions matter and which event classes are relevant. epoll_wait() returns entries that have reached the ready list.

Software Engineering 17 Sep 2026 9 min read

Epoll Edge Triggering Turns Readiness Into a Drain Obligation

An edge-triggered epoll registration can stop producing notifications while unread bytes still remain in a socket or pipe. The descriptor is still usable for I/O, but the event loop has already consumed the notification associated with the readiness transition. If the handler reads only part of the available data and returns to epoll_wait(), no fresh transition is required to occur, so the pending bytes can remain untouched indefinitely. This behavior makes EPOLLET more than a notification preference. It changes the contract between the kernel’s ready list and application state. A level-triggered loop can repeatedly receive a descriptor while the requested I/O condition remains true. An edge-triggered loop must preserve enough local state to treat a delivered event as an obligation to exhaust the currently available nonblocking I/O, normally until an operation reports EAGAIN.

Software Engineering 16 Sep 2026 6 min read

Vary Expands HTTP Cache Selection Beyond the URI

Two GET requests for the same target URI can require different cached responses. If an origin selects representation metadata or content from request headers such as Accept-Encoding, a cache keyed only by the URI can return a representation selected for a different request. HTTP’s Vary response field extends cache selection across nominated request fields. It does not merely document negotiation. For a stored response carrying Vary, those nominated fields constrain whether that response can satisfy a later request without revalidation.

Software Engineering 16 Sep 2026 5 min read

TCP TIME-WAIT Delays Four-Tuple Reuse

A TCP endpoint that performs the active close can keep the closed connection in TIME-WAIT after the final ACK has been sent. The application-visible stream is finished, yet the transport retains state for a bounded interval before permitting unrestricted reuse of the same connection identity. That retention is not leftover application state. It protects the protocol boundary between one connection incarnation and a later connection that could otherwise use the same source address, source port, destination address, and destination port.

Software Engineering 16 Sep 2026 7 min read

PostgreSQL SKIP LOCKED Turns Row Contention Into Visible Omission

A PostgreSQL query using FOR UPDATE SKIP LOCKED can omit a row that satisfies its predicate solely because another transaction already holds a conflicting row lock. The omitted row has not stopped matching the query. It is absent from that execution because lock acquisition would wait. That behavior changes the meaning of a locking read. Ordinary selection asks which visible rows satisfy a predicate. SKIP LOCKED adds an operational condition: among qualifying rows, return only those whose requested locks can be acquired without waiting at the point PostgreSQL attempts to lock them.

Software Engineering 16 Sep 2026 6 min read

PostgreSQL Serializable Reads Track Conflicts Without Blocking Writers

A PostgreSQL transaction at SERIALIZABLE isolation can read a set of rows while a concurrent transaction writes data relevant to that read without the reader taking a blocking row lock. PostgreSQL preserves serializable outcomes by tracking read-write dependencies and rejecting a transaction when the observed dependency structure could admit a serialization anomaly. That mechanism differs from treating every read predicate as a barrier against matching writes. The database keeps MVCC snapshot behavior, adds SIReadLock state for dependency detection, and makes transaction retry part of the isolation contract.

Software Engineering 16 Sep 2026 7 min read

PostgreSQL Sequence Values Survive Transaction Rollback

A PostgreSQL transaction can call nextval, roll back every row change it made, and still leave the allocated sequence value consumed. The row state returns to its earlier transactional form; the sequence allocation does not. This asymmetry is intentional and places sequence generators outside the rollback semantics developers often associate with database writes. That boundary matters whenever a generated identifier is treated as more than an opaque key. A sequence provides concurrent value allocation with atomic nextval calls. It does not provide a gapless ledger, a count of committed rows, or a transactionally reversible numbering stream.

Software Engineering 16 Sep 2026 7 min read

PostgreSQL Savepoint Rollback Releases Later Locks

A PostgreSQL transaction can remain open while a lock acquired during part of that transaction is released. If the lock was acquired after a savepoint and execution rolls back to that savepoint, PostgreSQL releases the lock immediately rather than retaining it until the outer transaction ends. That behavior creates a lock-lifetime boundary inside a transaction. The common rule that transaction locks last until commit or rollback remains useful, but savepoints add a narrower scope for locks acquired after the marked point.

Software Engineering 16 Sep 2026 7 min read

PostgreSQL NOT VALID Constraints Separate Installation From Table Verification

PostgreSQL can add a foreign key or CHECK constraint to a populated table without proving at that moment that every existing row satisfies it. With NOT VALID, the database records the constraint, enforces it against subsequent writes, and leaves a separate verification step for historical rows. That split creates a useful migration boundary. Constraint installation changes the rules for new data immediately, while VALIDATE CONSTRAINT later establishes that pre-existing data also conforms. The two operations have different work profiles and locking behavior, so treating them as one indivisible schema change can hide an important operational distinction.

Software Engineering 16 Sep 2026 5 min read

PostgreSQL Foreign Keys Turn Reference Checks Into Row Locks

A PostgreSQL insert into a child table can block a concurrent transaction that tries to delete the referenced parent row, even though the two statements modify different tables. Foreign key enforcement is not only a value lookup. The database must also prevent the referenced key from disappearing before the referencing transaction reaches its boundary. That requirement creates a concurrency relationship between child writes and parent-row changes. The relationship is narrower than a general parent-row write lock: PostgreSQL has a row-lock mode specifically compatible with updates that leave key columns intact.

Software Engineering 16 Sep 2026 7 min read

PostgreSQL Exclusion Constraints Express Pairwise Conflicts Beyond Equality

A PostgreSQL exclusion constraint can reject two rows even when none of their stored values are equal. Its rule is pairwise: for any two candidate rows, the configured operator comparisons must not all evaluate to true. That makes the constraint suitable for invariants such as non-overlapping time intervals, where scalar uniqueness does not describe the forbidden state. The mechanism is more general than a scheduling convenience. It turns an operator-defined notion of conflict into a database constraint, with an index access method participating in conflict detection. The exact operators, their null behavior, range boundaries, and any constraint predicate determine which row pairs are legal.

Software Engineering 16 Sep 2026 7 min read

PostgreSQL Deferrable Uniqueness Moves Conflict Detection to a Transaction Boundary

A PostgreSQL transaction can temporarily contain rows that violate a unique constraint and still remain executable. That state is possible only when the constraint is declared deferrable and its current mode is deferred. The duplicate is not accepted as valid data; enforcement has moved from the statement boundary to a later constraint-check boundary. This timing distinction changes which multi-statement transformations are representable. It also changes where an error can surface, which statements can act as conflict arbiters, and what application code can safely infer from the success of an individual write.

Software Engineering 16 Sep 2026 6 min read

PostgreSQL Advisory Lock Lifetime Follows Acquisition Scope

A PostgreSQL advisory lock can survive a transaction rollback when it was acquired at session scope. The SQL transaction may have ended with no committed data changes, yet the same database session can continue holding the application-defined lock until an explicit release or session termination. That behavior places lock lifetime at an interface boundary that is easy to blur in pooled applications. Advisory locks have application-defined meaning, but PostgreSQL still gives each acquisition precise server-side scope.

Software Engineering 16 Sep 2026 7 min read

Long PostgreSQL Snapshots Delay Dead Tuple Reclamation

A PostgreSQL transaction can remain idle while still preserving a visibility horizon that constrains cleanup elsewhere. Rows updated or deleted after that transaction acquired its snapshot may become obsolete for newer transactions, yet some older versions can remain potentially visible to the retained snapshot. VACUUM cannot reclaim a row version merely because the newest application state no longer references it. This is a direct consequence of multiversion concurrency control. Visibility and physical reclamation are separate decisions: one transaction changes which row version is current, while the database must retain versions that can still be observed by relevant snapshots.

Software Engineering 16 Sep 2026 7 min read

If-Range Prevents Mixed-Representation Resumes

A resumed HTTP transfer can corrupt a local result without any malformed bytes if the resource changes between requests. The first response may supply bytes from one representation while a later range response supplies offsets from another. If-Range exists to bind the resumed range to the representation that produced the stored prefix. This is a representation-identity problem rather than a transport-framing problem. Byte offsets only have stable meaning relative to a particular representation. A syntactically valid 206 Partial Content response can still be unusable for recombination when its bytes belong to a different version.

Software Engineering 16 Sep 2026 7 min read

If-Match Turns Stale HTTP Writes Into Precondition Failures

Two clients can read the same HTTP resource, compute different replacements, and send those replacements minutes apart. If the origin accepts both writes without a precondition, the later request can overwrite the earlier result even though it was computed from stale state. HTTP provides a protocol-level guard for this case. A client can retain an entity tag from the representation it read and send that tag in If-Match with a later state-changing request. The origin evaluates the precondition before applying the method. If no listed tag strongly matches the current selected representation, the method is not performed because of that precondition.

Software Engineering 16 Sep 2026 7 min read

HTTP Stale-While-Revalidate Moves Cache Refresh Off the Request Path

A cache can return an expired stored response immediately and start validation in parallel when stale-while-revalidate permits that reuse. The request that encounters the stale entry therefore does not have to inherit origin validation latency, but it can receive representation data older than the normal freshness lifetime. This is a deliberate shift in the cache contract. Freshness still expires at the configured boundary. The extension adds a separate interval in which stale reuse is permitted while validation proceeds, so response age and request latency become partially decoupled.

Software Engineering 16 Sep 2026 8 min read

HTTP If-Range Couples Partial Retrieval to Representation Identity

A client that has only part of an HTTP representation faces a consistency problem when it asks for the missing bytes later. Byte offsets are meaningful only against the representation whose bytes established those offsets. If the selected representation changes between requests, combining an old prefix with a new suffix can produce data that no server ever emitted. If-Range attaches representation identity to that partial-retrieval boundary. When its validator matches, the server can process the accompanying Range field. When it does not match, the server ignores Range and sends the complete selected representation through the normal successful response path instead of returning a failed-precondition response.

Software Engineering 16 Sep 2026 8 min read

HTTP If-Match Turns Representation State Into a Write Precondition

An HTTP origin can refuse a PUT or DELETE before applying it when the request carries If-Match and the selected representation no longer has an accepted entity tag. The condition converts a representation validator into a write precondition: a client can say that a mutation is valid only against state matching a version it previously observed. This mechanism addresses a specific concurrency boundary. It can prevent one client from silently replacing resource state after another client has changed the selected representation. It does not turn HTTP into a transaction protocol, lock the resource between requests, or guarantee that an entity tag represents every piece of application state involved in a mutation.