Skip to content

Archive

Queues

4 articles
Tech 22 Sep 2026 7 min read

NVMe Completion Queue Phase Tags Mark Reused Entries

An NVMe completion queue is a fixed-size circular array in host memory. The controller writes completion queue entries as commands finish, while host software consumes those entries and advances the queue head. Eventually both sides return to slots that already contain data from an earlier circuit of the ring. Reusing memory creates a small but important ambiguity. A slot can contain a perfectly formed completion entry even when the controller has not written a new completion there yet. Clearing every consumed entry would add memory traffic and still require careful coordination between the host and controller.

Tech 22 Sep 2026 6 min read

NVMe Completion Queue Phase Tags Distinguish New Entries After Ring Wrap

An NVMe completion queue is a circular memory structure shared by a controller and host software. The controller posts completion queue entries after commands finish, while the host consumes those entries and advances its queue head. Once either side reaches the final slot, its index wraps to slot zero. That wrap creates a small but important state problem. Queue memory still contains bytes from earlier completions. Reading a nonzero entry at the current head is not enough to prove that the controller has posted a fresh completion there. NVMe solves this with a one-bit Phase Tag carried in every completion queue entry.

Software Engineering 21 Sep 2026 6 min read

Bounded Queues Turn Overload into Explicit Backpressure

Bounded Queues Turn Overload into Explicit Backpressure A queue can absorb a short mismatch between arrival rate and processing rate. That buffering is useful when bursts are temporary. It becomes dangerous when the queue has no meaningful bound: sustained overload no longer appears as an admission failure, but as a growing backlog, rising memory use, and requests that finish long after their latency budget has expired. A bounded queue changes the contract. Once capacity is exhausted, the producer must wait, reject, shed, or route work elsewhere. The overload is no longer hidden inside an expanding buffer.

Python 09 Sep 2026 9 min read

Shut Down asyncio Worker Queues Cleanly

Asynchronous worker pools often start with a simple pattern: producers put jobs into an asyncio.Queue, consumers loop over get(), and the application waits for join() before exiting. The awkward part is shutdown. Older designs commonly put one sentinel value into the queue for each worker, cancel consumers after join(), or maintain a separate stop event. Each approach can work, but each adds a second protocol beside the queue itself. Python 3.13 added asyncio.Queue.shutdown() and the asyncio.QueueShutDown exception. They let the queue represent its own lifecycle: open for producers, shutting down while existing work drains, and finally closed to consumers.