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 19 Sep 2026 7 min read

Deadline Propagation Bounds Request Lifetime Across Service Calls

A request can stop being useful before every process handling it stops working. An HTTP client may give up after two seconds while an upstream service continues a database query, an RPC, and a retry sequence for several more seconds. Those operations still consume connections, CPU time, queue capacity, and downstream concurrency even though their result no longer has a recipient. A deadline makes that usefulness boundary explicit. Propagating it through nested calls gives participating components a common upper bound derived from the original request. This differs from assigning an independent timeout at every hop: local timeouts limit individual operations, while a propagated deadline limits the lifetime of the operation graph.

Software Engineering 19 Sep 2026 8 min read

Compose Multiplatform vs Flutter: Rendering, Performance, and Bundle Size

Compose Multiplatform vs Flutter: Rendering, Performance, and Bundle Size Compose Multiplatform and Flutter can produce similarly smooth mobile interfaces, but they do not reach the screen through the same stack. That difference matters more than the usual “Kotlin versus Dart” comparison. Compose Multiplatform extends the Compose programming model across platforms. Flutter ships a more self-contained UI stack with its own engine and Dart runtime. Both approaches add machinery around application code, but the cost appears in different places: rendering work, startup, memory, binary size, and platform integration.

Software Engineering 19 Sep 2026 7 min read

Circuit Breakers Bound Failure Traffic Across Service Calls

A circuit breaker changes the admission decision for an outbound call before the dependency receives it. In the closed state, calls proceed and their outcomes feed a failure policy. Once that policy trips, the breaker enters the open state and rejects subsequent calls locally. After a configured recovery interval, a limited set of probe calls can test whether the dependency is usable again. That mechanism is distinct from retries. A retry issues another attempt after a failed attempt. A breaker can prevent an attempt from being issued at all. Combining the two without a precise ordering can amplify traffic during an outage or keep a breaker open based on signals that do not represent dependency health.

Software Engineering 19 Sep 2026 6 min read

Circuit Breakers Bound Failure Amplification Across Service Calls

A service call can fail quickly and still create a larger system problem. When every upstream request continues to invoke a downstream dependency that is already failing, each attempt consumes connection capacity, worker time, retry budget, and queue space. The dependency receives traffic it cannot currently serve, while callers spend resources waiting for outcomes that are already strongly correlated with recent failures. A circuit breaker puts a stateful decision boundary in front of that call. Instead of treating every request as an independent opportunity to try the dependency, it records recent failure state and can reject calls locally for a bounded interval. Recovery is then tested through controlled probes rather than a full return of traffic.

Software Engineering 19 Sep 2026 6 min read

Bounded Queues Turn Overload into an Explicit Admission Decision

A queue between a producer and a slower consumer can absorb a temporary rate mismatch. It cannot remove that mismatch. If arrivals continue faster than completions, every accepted item adds to outstanding work. An unbounded queue lets that state accumulate until some other resource becomes the effective limit, often memory or an external timeout. A bounded queue moves the limit into the interface itself. Once capacity is exhausted, admission has to produce an observable result: wait for space, reject new work, discard selected work, or redirect it elsewhere. The queue therefore becomes more than a storage structure. Its capacity and full-queue behavior define part of the system’s overload contract.

Software Engineering 19 Sep 2026 5 min read

Array Syntax in Go, PHP, JavaScript, Kotlin, Rust, and Python

Square brackets make array code look deceptively portable. In Rust, [10, 20, 30] can be a fixed-size array whose length is part of its type. In Python, the same visual shape creates a mutable list. PHP uses bracket syntax for an ordered map, while JavaScript creates a resizable Array object. The syntax is easy to memorize. The more important distinction is what the value means after it has been created.

Software Engineering 19 Sep 2026 6 min read

Android Priority Notifications Are Not VIP Channels

Android Priority Notifications Are Not VIP Channels A pager-style Android application can expose a button labeled VIP channel, but Android does not turn that label into a private radio frequency, reserved cellular bearer, or guaranteed delivery path. What the application can build is a priority policy. A server can classify an event as urgent, request high-priority delivery from Firebase Cloud Messaging (FCM), and post the resulting notification to an Android notification channel with high importance. Those controls operate at different layers, and none of them alone provides pager-like delivery guarantees.

Software Engineering 19 Sep 2026 8 min read

Ad-Supported Utility SaaS: Keep Processing Stateless and Data Ephemeral

Ad-Supported Utility SaaS: Keep Processing Stateless and Data Ephemeral A utility SaaS does not need a large content operation to create repeat traffic. A user may arrive to resize an image, clean a CSV file, convert structured data, generate a QR code, validate a document, or run another narrow transformation. The technical challenge is different from a conventional content site: each visit performs work. That work can become expensive quickly if every request uploads a file, allocates server memory, writes temporary objects, invokes a database, and retains artifacts after the user leaves. An ad-supported free tier makes this pressure more visible because revenue per visit is usually small compared with the cost of heavy compute or storage.

Software Engineering 18 Sep 2026 5 min read

timerfd Turns Timer Expirations into Descriptor Readiness

A timerfd becomes readable after its timer expires. The notification is not a signal handler invocation and not a byte-stream message. Linux records pending expirations on a timer object and exposes that state through a file descriptor, so a timer can occupy the same readiness boundary as sockets, pipes, and other descriptors. That interface does more than replace one notification mechanism with another. Clock selection determines the time domain, arming flags determine whether a deadline is relative or absolute, and each successful read reports the number of expirations accumulated since the preceding successful read or timer reconfiguration.

Software Engineering 18 Sep 2026 4 min read

timerfd Turns Timer Expiration Counts into Pollable Descriptor State

A Linux timerfd becomes readable when its configured timer has expired. The bytes returned by read(2) are not a timestamp or event record: they encode one unsigned 64-bit integer containing the number of expirations since the previous successful read. Timer state therefore participates in the same readiness machinery as sockets and pipes while retaining timer-specific semantics behind the descriptor boundary. Readiness represents a pending expiration count timerfd_create(2) creates a descriptor associated with a clock, while timerfd_settime(2) arms or disarms its timer. Once at least one expiration is pending, poll(2), select(2), and epoll(7) can report the descriptor as readable.

Software Engineering 18 Sep 2026 5 min read

SO_REUSEPORT Moves Listener Distribution into Socket Selection

SO_REUSEPORT permits multiple Linux AF_INET or AF_INET6 sockets to bind the same local address and port when every member satisfies the reuse-port rules. For TCP listeners, this moves incoming connection distribution ahead of accept(): the kernel selects a listener from the reuse-port group, and that listener receives the connection on its accept queue. For UDP, selection determines which socket receives an incoming datagram. This is a different concurrency boundary from several threads sharing one listening file description. Each reuse-port member is a distinct socket, with its own descriptor, queues, polling state, and lifecycle.

Software Engineering 18 Sep 2026 3 min read

signalfd Routes Pending Signals Through Descriptor I/O

A Linux signalfd becomes readable when a signal selected by its mask is pending for the reading context. A successful read(2) consumes pending signal state and returns one or more fixed-size signalfd_siginfo records. Signal handling can therefore enter a descriptor-driven event loop without turning asynchronous handlers into the primary dispatch mechanism. The descriptor mask does not block signals The mask passed to signalfd(2) selects signals that the descriptor can accept. It does not modify the calling thread’s signal mask. Normal use separately blocks those signals with sigprocmask(2) or pthread_sigmask(3) so their ordinary dispositions do not run before descriptor consumption.

Software Engineering 18 Sep 2026 6 min read

seccomp User Notification Delegates Selected Syscalls to a Supervisor

seccomp User Notification Delegates Selected Syscalls to a Supervisor A seccomp filter can stop a selected system call before the kernel executes it and emit a notification to a user-space supervisor instead. The target thread remains blocked while the supervisor receives the event and returns a disposition. This behavior turns a filter result into a controlled handoff across the kernel/user-space boundary. The mechanism is SECCOMP_RET_USER_NOTIF. It differs from ordinary seccomp actions because the BPF filter does not finish the decision by itself. A listener file descriptor becomes the coordination point for notification receipt, response delivery, and optional file-descriptor injection.

Software Engineering 18 Sep 2026 6 min read

SCM_RIGHTS Transfers Open File Descriptions Across Process Boundaries

SCM_RIGHTS lets one process send a reference to an open file through a Unix domain socket. The receiver obtains a file descriptor in its own descriptor table, but the transfer does not reopen the pathname or copy the kernel object. On Linux, the resulting reference has semantics equivalent to duplicating the sender’s descriptor into the receiving process. That distinction matters whenever a process boundary is also an authority boundary. A supervisor can open a socket, file, pipe, device, or other descriptor-backed object and pass the established reference to a worker. The worker receives access to the already-open object, including open-file state that can remain shared with the sender.

Software Engineering 18 Sep 2026 4 min read

pidfds Bind Process Operations to Stable Kernel References

A numeric PID names a process only while that PID remains assigned to it. After termination and reaping, Linux can reuse the number for another process. A PID file descriptor, or pidfd, instead holds a kernel reference to a specific task, so later operations can target that task without resolving its numeric PID again. This distinction removes a class of time-of-check/time-of-use races from process management. It does not make a process immortal, grant extra permissions, or turn every process operation into a portable descriptor API.

Software Engineering 18 Sep 2026 5 min read

openat2 Constrains Path Resolution Inside a Directory Boundary

A pathname is not a stable object reference. Between its starting directory and final component, Linux path resolution may follow symbolic links, cross mount points, process .., or encounter special links exposed by pseudo-filesystems. openat2() lets a caller attach constraints to that resolution operation so the kernel can reject a lookup that leaves the intended boundary. The distinction is stronger than checking a normalized string before open(). String validation examines syntax. openat2() can constrain the kernel’s actual traversal while filesystem objects and mount topology participate in the lookup.

Software Engineering 18 Sep 2026 4 min read

memfd Seals Turn Shared File State into Monotonic Restrictions

A memfd_create() file can begin as writable shared state and later become progressively more constrained. File seals make that transition monotonic: successful seals are properties of the inode, affect every descriptor referring to it, and cannot be removed. That property is useful when one process prepares bytes and then transfers a descriptor to another process. The receiver can inspect kernel-enforced restrictions instead of relying only on a protocol promise that the producer has stopped changing the object.

Software Engineering 18 Sep 2026 8 min read

MAP_SHARED mmap Couples Memory Writes to File-Backed Page State

A writable MAP_SHARED mapping lets a process modify file-backed state with ordinary memory stores. The bytes are addressed through virtual memory rather than passed to write(), but the mapping still participates in filesystem state: modifications can become visible through other shared mappings and file I/O, and dirty pages can later be written back to storage. That interface compresses several mechanisms into one address range. CPU stores, page faults, page-cache residency, filesystem writeback, and storage persistence can all participate in the lifetime of the same bytes. Treating a successful store as equivalent to durable file output collapses boundaries that the operating system keeps distinct.

Software Engineering 18 Sep 2026 6 min read

Linux userfaultfd Moves Selected Page Fault Handling into User Space

A page fault normally crosses from a process into the kernel and returns only after the kernel has resolved the virtual-memory condition or delivered an error. Linux userfaultfd can insert a user-space component into that path for explicitly registered address ranges. The kernel reports selected faults through a file descriptor, blocks the faulting execution context when the mode requires it, and accepts an ioctl that resolves the fault. This is a Linux virtual-memory interface, not a C or POSIX memory guarantee. Its behavior depends on negotiated kernel features, the registered range, its mapping type, and the registration mode.

Software Engineering 18 Sep 2026 7 min read

Linux splice Makes Pipe Capacity Part of Data-Transfer Semantics

Linux splice() can transfer bytes between file descriptors without routing those bytes through a user-space buffer, but the interface is not a generic descriptor-to-descriptor copy primitive. At least one endpoint must be a pipe. That requirement makes pipe state part of the transfer contract: capacity, readable data, writer presence, blocking mode, and partial progress can all affect an otherwise straightforward data path. The useful boundary is therefore not simply “kernel copy versus user copy.” splice() changes the shape of ownership and flow control. Application code stops owning an intermediate byte array, while it still owns the control loop that accounts for bytes transferred, handles readiness, and preserves offset semantics.

Software Engineering 18 Sep 2026 5 min read

Linux signalfd Converts Selected Signals into Descriptor Reads

A signal included in a signalfd mask can become readable state on a file descriptor instead of invoking an asynchronous signal handler, provided that the signal is blocked from ordinary delivery in the relevant thread. This changes the interface boundary: signal arrival can participate in the same descriptor-oriented event loop as sockets, pipes, and other pollable objects. The mechanism does not replace Linux signal semantics. Signal generation, process and thread signal masks, pending state, standard-signal coalescing, real-time signal queuing, and delivery rules still apply. signalfd changes the consumption interface for signals selected by its mask.

Software Engineering 18 Sep 2026 7 min read

Linux signalfd Converts Pending Signals into Descriptor Reads

Linux signalfd gives selected signals a descriptor-oriented consumption path. Instead of transferring control into an asynchronous handler, a process can block those signals, associate them with a signalfd object, and consume pending instances through read(). The descriptor can also participate in poll(), select(), and epoll, placing signal reception beside sockets, timers, and other readiness sources. This interface is Linux-specific. The signal mask, pending-signal rules, and descriptor operations come from Linux and POSIX signal semantics where applicable; they are not properties of the C language itself.

Software Engineering 18 Sep 2026 6 min read

Linux renameat2 Makes Path-Replacement Policy Atomic

A pathname rename changes directory entries while open file descriptors continue to refer to the same underlying objects. Linux renameat2() adds policy to that namespace update: a caller can reject replacement, exchange two existing names, or request a whiteout for union-filesystem operation. These policies are executed as part of the rename operation rather than as checks performed separately in userspace. The interface is Linux-specific. A zero flags argument gives renameat() behavior, while nonzero flags add Linux semantics that also depend on support from the mounted filesystem.

Software Engineering 18 Sep 2026 6 min read

Linux pidfd Binds Process Operations to Stable Kernel References

A numeric process ID is a name in a PID namespace, not a durable handle to one process lifetime. After a process exits and its PID becomes available for reuse, a later process can receive the same number. Linux PID file descriptors add a different interface boundary: a pidfd is a file descriptor referring to a particular task, so later operations can target that kernel reference rather than resolving the numeric PID again.