A buffer can prevent a short burst from becoming packet loss. The same buffer can also store a long line of packets that every new arrival must wait behind. Capacity alone does not tell us which situation we have. The useful question is whether the queue gets a chance to drain.

CoDel uses packet sojourn timeThe time a packet spends in a queue before it leaves. and persistence to identify excessive standing queuesA backlog that persists instead of draining between bursts.. Its specification includes a target, an interval, protection against starving a nearly empty queue, and a control law that changes the spacing of congestion signals. A momentary delay spike is not equivalent to delay that remains above target throughout an interval. RFC 8289, Sections 3–5.

RFC 8289 specifies the packet-level CoDel algorithm, including a normal Internet target of 5 ms and interval of 100 ms. Its datacenter appendix discusses an adapted implementation and measured latency improvements. The sampled detector here uses a shorter 40-ms interval to expose the persistence decision; it does not substitute for that full feedback loop.

Translate stored bytes into waiting time

Consider an original arithmetic example: a 10-megabit-per-second output link with one million bytes already queued ahead of a packet. Ignoring framing and other overhead, draining those bytes takes 8 × 1,000,000 / 10,000,000 = 0.8 seconds. If only 40,000 bytes are ahead, the corresponding delay is 32 milliseconds.

Neither calculation says how large the physical buffer should be. It says that buffer occupancy has a time cost tied to service rate. The same byte count on a faster link implies a different wait. Measuring the time packets actually spend in a queue makes that relationship directly visible.

Compare two delay histories

Our first synthetic trace has a high peak: sampled delays rise from one millisecond to 12, then 18, then 10, before dropping to three. Samples arrive every ten milliseconds. The second trace rises from one to eight milliseconds and stays there. Its peak is much smaller, but its queue never shows a low-delay sample afterward.

Use a five-millisecond target and, solely for this short illustration, a 40-millisecond persistence interval. The first trace goes back below target before the interval elapses. The second remains above and triggers at simulated time 50 milliseconds: the first above-target sample was at time ten.

The code implements only this sampled persistence detector and the byte-to-delay calculation. It does not dequeue packets, drop traffic, alter a sender, or implement the complete CoDel algorithm. In particular, sampled observations can miss a brief drain between samples, and the example assumes backlog is sufficient that the near-empty-queue safeguard is not relevant. These are boundaries of this detector, not hidden claims about a network stack.

Look at duration as well as height

The two delay traces share a horizontal target line. Shading begins at the first above-target observation. It ends at the low sample for the transient trace and reaches the trigger for the persistent trace. Ranking only the maxima would give the opposite ordering from this persistence test.

The code also prints several progressively shorter signal spacings from the inverse-square-root form. That separate calculation explains how a persistent condition can lead to stronger feedback; it does not simulate the network's response to that feedback.

The next step toward a queue-management experiment would be a packet-arrival model coupled to a responsive sender, with delivered throughput and delay measured together. Reducing delay by dropping everything is not a useful result. This smaller example instead establishes the diagnostic distinction that any such experiment needs: absorbing a burst and preserving a standing queue are not the same service.

A lower peak can be the persistent problem. A sampled persistence detector, queue-drain arithmetic, and separate control-law spacing calculation; not full CoDel, a responsive TCP simulation, or a Linux benchmark. The figure is generated directly from results.json; the notebook includes the original check and the parameter sweep.
A sampled persistence detector, queue-drain arithmetic, and separate control-law spacing calculation; not full CoDel, a responsive TCP simulation, or a Linux benchmark. The figure is generated directly from results.json; the notebook includes the original check and the parameter sweep.

The interval changes which event you are detecting

The extension sweeps four target values and six persistence intervals over both traces. At a five-millisecond target, shortening the interval from forty to twenty milliseconds causes the transient trace to trigger at t = 30 ms. It has been continuously above target in the sampled observations since t = 10 ms, even though it drops below target at the next sample.

The forty-millisecond setting does not trigger on that burst. The persistent trace does trigger at t = 50 ms. Neither answer is produced by comparing peaks: the transient trace still has the larger peak. The parameter defines how long an above-target episode must last before this detector classifies it as persistent.

The implementation resets its timer when a sampled delay falls below target. Equality remains in the above-target condition, consistent with the RFC helper's comparisons. But a sampled trace does not observe every dequeue event. A queue that briefly drains between samples could be misclassified here, which is why this component calculation cannot validate a real CoDel implementation.

The independent spacing calculation also remains separate: interval/√count describes progressively closer signals once persistent congestion is being controlled. It says nothing by itself about delivered throughput or the sender's response. A complete queue-management experiment needs the arrival process, dequeue service, marking or dropping action, feedback delay, and congestion controller in the same closed loop.