PFQD: A Practically Fair Queueing Discipline
Unified for Routers and Hosts
March 2026
Abstract
Network egress pipelines can chain three independent subsystems: a queueing discipline with active queue management (DualPI2, CoDel, PIE), DiffServ classification, and a rate policer, each with its own state, control plane, and failure modes. Their interactions are difficult to reason about, and their combined complexity makes them hard to build into fixed-function ASICs. We propose the Practically Fair Queueing Discipline (PFQD), a per-flow scheduling mechanism that hashes packets into per-flow priority queues organized into four tiers (NEW, CTL, DHI, and DLO). In PFQD, every egress port is backed by a single-consumer multiple-writer queue with per-flow packet round-robin and a packet-count simplification of DRR [1] approximating our equal-weight GPS fairness [2] target. We show that PFQD provides flow-level fairness that is materially stronger than the class-level fairness of DualPI2 (RFC 9332). Against FQ-CoDel (RFC 8290), PFQD matches its throughput fairness, serves backlogged flows more evenly, and enforces rate limits on ECN-capable flows using marks.
1 Introduction
A packet’s typical journey from application to router-wire touches three independent scheduling
subsystems: the egress qdisc with an optional AQM (e.g., sch_fq, or fq_codel),
a DiffServ/DSCP classifier, and a rate policer (token bucket).
We argue that better utilization and lower latency come from a simpler AQM, not a more
sophisticated one. PFQD replaces the above three mechanisms with a single per-flow
scheduler that can be applied at host, router or switch.
1.1 The Three Subsystems
egress qdisc. A Linux host enqueues packets via a root qdisc such as pfifo_fast or another
of the available queueing disciplines. Active queue management modules are themselves qdiscs
(red, codel, pie), attached in place of or beneath the scheduler to signal congestion;
for example, fq_codel runs a CoDel instance inside each flow queue.
DiffServ / DSCP classification. DSCP marks (RFC 2474) sort traffic into behavior aggregates, and each aggregate is granted a per-hop behavior, such as expedited forwarding (RFC 3246) or assured forwarding with policing (RFC 2597). The behavior-aggregate model deliberately keeps per-flow state out of the router, so every packet carrying a given mark receives the same treatment. Differentiation is therefore only available between classes not within a class, where a flow that responds less to congestion signals can crowd other flows out, an effect §7.1 measures directly.
QoS rate policing. ISPs enforce contractual per-subscriber rate caps, typically with token-bucket policers (RFC 2698). Note that a rate cap is, in effect, a minimum inter-packet departure (IPD) constraint.
A single misconfigured egress service can silently degrade flow rates, and when the anomalies span systems run by different organizations the diagnosis compounds.
1.2 Complexity is a Tax
DualPI2 [3] addresses a real coexistence problem: classic congestion controls (Reno [4], CUBIC [5]) cut their window sharply on any congestion signal and need hundreds of RTTs to recover [6]; while scalable CCs (DCTCP [7], Prague [8]) respond proportionally and recover in constant time. When the two types of CC’s share a queue, the classic flow cedes a disproportionate share of the bandwidth to its scalable competitor. DualPI2 splits them into separate queues and couples their marking probabilities through a PI controller. The result is nine interdependent components governed by eight parameters that do not vary independently ([3] Fig. 1 and App. A, [9]). Changing alone shifts both controller gains, and reasoning about correctness becomes a loop-stability analysis. An engineer facing a performance incident likely resets to defaults instead. Furthermore, the architectural consequence is that the router is now running congestion control: the host’s CC decides how fast to send while the router’s PI controller decides how aggressively to mark, and when the two loops disagree the result can be throughput collapse, unfair allocation, or both [3].
1.3 What PFQD Unifies
Host mode. On a sending host, PFQD replaces sch_fq or pfifo_fast as the egress qdisc.
Its primary function is to inherit pacing rates from the local CC algorithm: when a sender
(WarpRATE [10],
BBR [11], or any pacing-capable CC) sets a rate, PFQD’s dequeue path holds packets until their pacing-eligible time. Per-flow fair queuing ensures that locally originated flows share the NIC egress fairly; on a host PFQD never marks or drops locally generated packets. Recently, in a September 2026 deployed configuration: WarpRATE [10] using host-mode PFQD delivered, on a wired ISP path, 1.5× CUBIC and BBR, 1.3× over LTE, and 4.4× CUBIC via Starlink ([10], §7.2).
Router mode. On a router, switch, or a host forwarding traffic, PFQD also operates on forwarded traffic. Notably, there is no local CC to inherit pacing from, so the designs dequeue path is governed by the per-flow IPD floor of §3.5, derived from the subscriber’s contracted rate and defaulting to the raw port rate. When a flow’s queue exceeds its per-flow ECN limit, packets are marked CE per §3.4. The Linux module at the time of writing implements host-mode pacing inheritance and the marking and head-drop mechanics; the rate policing of §3.5 is specified for the design and not yet implemented in the module. Flows that do not respond to ECN experience head-drop from their per-flow queue, a UDP flood thus harms only itself. Conversely, under DualPI2, whose behaviour is defined to be similar to a single FIFO queue with respect to unresponsive and overload traffic [3], the same flood starves every flow sharing its queue.
Operational simplicity. The scheduling semantics are identical on host and router: round-robin across active flows, the same priority tiers, the same ECN threshold and demotion mechanics1. An engineer diagnosing a performance problem reasons about a consistent set of rules at every hop, governed by four parameters, each with a physical interpretation: how long a flow may occupy the DHI tier, how long a packet may wait before ECN signaling begins, the byte floor under that limit, and the total available buffer.
2 Fairness
2.1 The Ideal Queueing Model
Parekh and Gallager [2] established the foundational result for fair scheduling under the Generalized Processor Sharing (GPS) model. GPS considers sessions (flows) sharing a single server of capacity , where each session is assigned a weight and receives whenever it is backlogged. GPS is an idealized model2, but it is the natural fairness benchmark for this topology: at every instant it delivers the max-min fair allocation among backlogged flows because transmits never idle while any queue is nonempty, and no backlogged flow is ever starved. When all weights are equal, each backlogged flow receives and per-flow round-robin is then the packet-level analogue, serving each flow once per cycle.
Both PFQD deployment modes instantiate this topology: locally originated flows contending for one NIC serializer, or forwarded flows contending for one egress port, are writers and one consumer, exactly the GPS model.
An ideal scheduler fills every available slot whenever any flow queue holds a ready packet, since a transmit slot that goes unused is capacity lost for good, and a slot consumed by a low-priority flow while a higher-priority flow waits is engineered latency. Class-based schemes (DiffServ, DualPI2) compromise the ideal by grouping flows into shared queues where intra-class contention reintroduces unfairness, and priority schemes without round-robin risk starvation of lower classes.
2.2 Equal Treatment for UDP, TCP, IPsec, and Others
Traditional network QoS exists largely because UDP and TCP do not coexist fairly in a shared queue: TCP backs off on congestion and UDP does not, so the conventional answer reserves bandwidth for UDP via DiffServ classes, weighted scheduling, or dedicated queues.
PFQD eliminates this need. Under per-flow round-robin, a UDP flow and a TCP flow sharing the same bottleneck each get one dequeue turn per cycle. If the UDP flow sends faster, its per-flow queue grows and eventually packets are tail-dropped from only that flow; the concurrent TCP flow is unaffected as long as it also does not overrun its queue.
PFQD’s structural isolation removes the starvation rationale for a reservation, though reservations that exist to guarantee capacity remain a contractual matter. Per-flow isolation contains a greedy flow structurally, with the caveat that any flow-granular scheduler can be gamed by opening more flows3.
2.3 Objections
The authors of DualPI2, De Schepper et al. [12], argue against per-flow queuing on three grounds: privacy, neutrality, and simplicity.
Privacy: “FQ needs to inspect transport layer headers.” For tunneled traffic, PFQD falls back to the outer 5-tuple, exactly as ECMP and RSS already do. For tunneled traffic, DualPI2 faces the same limitation. The concern applies equally to all such designs; the cost of the shared fallback is that a tunnel’s inner flows share one queue, as they already do today.
Neutrality: “FQ imposes rate judgments on flows.” Round-robin makes none: every flow gets equal dequeue turns regardless of content, protocol, or rate, and a flow that exceeds its fair share simply builds a deeper queue until it is ECN-marked or head-dropped. In this model, the network signals congestion; the source decides how to respond. DualPI2 is the design that, through a coupling factor set by whoever configures it, imposes a rate judgement on flows without any knowledge of the sender’s flow state.
Simplicity: “FQ requires more complex scheduling structures.” The meaningful difference is cognitive load, not code size. DualPI2 exposes eight interdependent tuning parameters
| Tier | Traffic | Scheduling |
|---|---|---|
| NEW | TCP SYN, SYN-ACK | Strict priority, connection setup |
| CTL | TCP pure ACK, ICMP, DNS4 | Strict priority, network control plane |
| DHI | TCP ACK/data, UDP, IPsec, SCTP, QUIC, etc | Round-robin among active data flows |
| DLO | Demoted elephants (any protocol) | RR with one DLO served per DHI cycle |
requiring familiarity with PI control theory; PFQD has four independent parameters with intuitive physical interpretations. The 36-byte per-flow state PFQD requires is smaller than what ASICs already maintain §4.2. Further, empirical studies document that misconfiguration, not hardware failure, is the dominant cause of production outages [13] [14].
3 PFQD: Design Overview
3.1 Core Principles
PFQD is grounded in three principles:
- Flow-level fairness. Every active flow gets an equal share of dequeue opportunities.
- Minimal tuning parameters. The DLO demotion time and the per-flow ECN limit are the two that matter.
- Explicit control-plane priority. Connection setup and network control are served before data bearing packets. This ensures control plane latency stays as low as possible.
3.2 Traffic Classification
These principles point at a four-tier (Table 1) traffic classification, not in the traditional DiffServ sense, but organized around network integrity and user experience. Received packets are assigned to tiers by their function or by duration of their flow.
The NEW and CTL tiers are independent FIFOs shared by all of their traffic, not per-flow timed queues, since control-plane packets are small and transient. When the NEW or CTL FIFO is full, arriving packets are tail-dropped; a head-drop would penalize the wrong flow. Newly arriving non-CTL or non-NEW traffic that has no prior flow context enters the discipline in DHI. A flow transitions to DLO when it is continuously live5 for 2 s or more and at least one other DHI flow is active; a lone flow is never demoted.
Pacing. When a sender on a source host sets a pacing rate (as WarpRATE and BBR do), PFQD respects it. Flows without a pacing rate (CUBIC, UDP, IPsec, router queues) dequeue as soon as their turn comes, so PFQD behaves as a pure priority fair queue for them. When a QoS IPD floor is in effect (§3.5), the dequeue path enforces the more restrictive of the two: such that sender pacing and contracted rate caps coexist.
3.3 Enqueue and Dequeue
Enqueue logic:
- If the packet is a TCP SYN or SYN-ACK → NEW tier.
- If the packet is a TCP pure ACK, ICMP, or DNS (UDP 53) → CTL tier.
- If the packet’s flow ID is in DHI, the flow has been resident longer than
demotion_ms, and another DHI flow is active → demote: move the entire queue to DLO and append the packet there. - If the packet’s flow ID is already in DLO → append to its DLO queue.
- Otherwise → append to the flow’s DHI queue (creating it if new).
Dequeue logic (one packet per cycle):
- If the NEW FIFO is non-empty and fewer than 10 NEW packets have been served this cycle → dequeue one NEW packet, continue with #1.
- if the CTL FIFO is non-empty and fewer than 10 CTL packets have been served this cycle → dequeue one CTL packet, continue with #2.
- if DHI has active flows → dequeue one packet from the next DHI flow (advancing the DHI cursor); if the queue just served is now empty, remove it. After all active DHI flows have been served once, continue to DLO.
- if DLO has active flows → dequeue one packet from the next DLO flow (advancing the DLO cursor); if the queue just served is now empty, remove it. Then reset the cycle.
- Otherwise → all queues are empty, pause and wait for packet arrival.
The DLO cursor advances on each visit, so successive cycles serve a different DLO flow. The number of DHI flows in a cycle is snapshotted at the start of the cycle: new DHI flows arriving mid-cycle are served in the next cycle, thereby preventing an unbounded DHI walk from starving DLO. Thus, the DLO tier as a whole, receives at least of data-tier bandwidth when DHI flows are active.
3.4 ECN Marking
PFQD’s ECN mechanism separates the marking decision from the marking action. Each flow has a
byte limit derived from a sojourn target: with the port rate, the target
(ecn_sojourn_us, 5 ms by default) and the number of active flows,
so that the bytes a flow may hold correspond to the time its packets
would wait behind an
equal share of the port, with a 64 KB floor (ecn_thresh) so that a slow port does not mark a
single window.6 The limit is recomputed only when the active-flow count or the
configuration changes. When a flow’s queue exceeds its limit at enqueue time, a per-flow
flag is set. The CE codepoint is applied later, at dequeue time, when the flow’s packet
departs. This way the mark reflects congestion at departure rather than arrival. The flag is
cleared at dequeue once the flow’s queue is at or below its limit. A fixed byte threshold
was our first design; on a bridged host it marked an unpaced sender’s every window and cut
CUBIC to a tenth of its paced neighbors, whereas the sojourn form restored parity.
ECN-capable packets (ECT(0) or ECT(1)) that depart while the flag is active are marked CE.
ECN marking is the primary congestion signal, with head-drop the mechanism for flows that
cannot receive it: when a Not-ECT flow’s queue exceeds its limit, the oldest packet of that
flow is dropped, creating a sequence gap that signals the sender at the earliest
opportunity. An ECN-capable flow is never head-dropped for exceeding its limit; only a
total buffer cap (max_queue) drops, and it drops from the deepest flow. Marking and
head-drop apply to forwarded traffic; a host does not mark or drop packets its local sockets
originate.
Flow drain cleanup: Per the DLO/DHI handling of empty queues in §3.3, removing a drained queue also removes the flow’s state, including its ECN flag and demotion timer.
3.5 Rate Policing
As §1.1 notes, a rate cap is a per-flow IPD floor enforced at dequeue time; no additional subsystem is required. This section specifies the policing design for the implementation of §4. Note that the current Linux module inherits pacing from the local sender and does not yet enforce a contracted floor.
Burst windows. PFQD accommodates step-function burst policies by re-using the demotion
timer. If a burst window is configured, the timer operates in two phases: armed first for
T_burst, during which the flow transmits at port speed; when it fires, the IPD floor switches
to the contracted rate and the timer re-arms for T_demote - T_burst; when that fires, the
flow is demoted to DLO. The constraint T_demote > T_burst is enforced at configuration time.
Without a burst window the timer operates in a single phase as described in
§3.3. The per-flow state budget of §4.1 accounts for the burst
re-arm value and phase bit.
3.6 Fairness
Each flow’s CC algorithm determines how efficiently the flow uses its fair share, so per-flow fair queuing does not need to understand or classify congestion control algorithms. PFQD’s round-robin serves one packet per flow per turn and counts packets rather than bytes, trading the deficit accounting of DRR [1] for a cheaper dequeue path; since, in practice, bulk traffic sends MSS-sized packets, packet-count tracks byte fairness in the common case. Every active flow gets equal service within its tier; the DHI/DLO split adds an intentional preference for fresh flows over continuously backlogged elephants.
Per-flow fairness also simplifies the decisions a CC algorithm has to make. With a private queue and a guaranteed share of dequeue turns, a sender’s only remaining question is how fast to fill its queue, and timely ECN feedback answers it: window-based senders such as CUBIC and Prague cut and recover against their queue depth, while rate-based senders such as BBR and WarpRATE converge to the drain rate and stabilize. The scheduler never discriminates between flows, so uncontrolled traffic needs no special case: a UDP flood is isolated to its flow queue leaving other flows unaffected; see §2.2.
4 Hardware Implementation
Packet scheduling is the part of a switch that resists change: algorithms are fixed in silicon at design time [15], line-rate per-flow fair queueing is approximated on reconfigurable switches rather than implemented [16], and even CoDel’s control law needed dedicated engineering to fit a programmable data plane [17]. What makes PFQD simple in software, integer arithmetic, fixed per-flow state and no periodic computation, carries over directly to fixed-function ASIC design.
4.1 Active-Flow State Budget
Each active flow requires 36 bytes of state: queue head/tail pointers (8 bytes), a demotion timestamp (8 bytes), a burst re-arm value (4 bytes), a packet count for round-robin fairness (4 bytes), a queue depth in bytes for the ECN threshold (4 bytes), the 5-tuple flow hash (4 bytes), and tier/ECN/burst-phase flags (4 bytes). The number of active flows at a bottleneck, meaning those with packets queued rather than merely established, is bounded by the total buffer for MTU-sized traffic:
In practice, active flow counts at a single egress port are far lower: 50–500 on a datacenter ToR port, 200–2,000 at campus aggregation, and 1,000–10,000 at ISP edge and core routers. At 36 bytes per flow, 5,000 active flows require 180 KB of SRAM, much smaller than every existing per-flow feature on a modern switch ASIC.7
4.2 Hash Bucket Architecture
PFQD locates a flow’s queue through a fixed hash table keyed on the 5-tuple, the same lookup mechanism FQ_CoDel [18] uses. The table scales from 1,024 buckets (36 KB of state) for low-flow-count links, through 4,096–8,192 buckets (144–288 KB) for campus and ISP edge deployments, to 65,536 buckets (2.3 MB) for IPv6-heavy or high-flow-count cores. Even the largest
configuration is trivial relative to the packet buffers on every modern port, and raising the bucket count toward the active-flow bound of Equation (2) keeps lookups near O(1) and distinct flows in distinct queues.
5 Real-Time Media
Real-time voice and video (RTP over UDP) are a large and growing fraction of network traffic, tolerant of lost frames but not of latency. The L4S ecosystem’s answer is SCReAM [19], a full rate-based CC embedded in the media application itself. This repeats the architectural pattern §1.2 questioned in DualPI2: placing congestion control where, we argue, it fits poorly. When RTP falls back to TCP (RFC 4571), SCReAM’s rate decisions conflict with those of the transport’s CC, producing an unstable two-loop system8. Furthermore, running over UDP requires both sender and receiver to implement SCReAM, thereby coupling congestion control to the end-to-end pipeline on a per-application basis.
PFQD’s ECN handling is well suited to RTP. RTP already carries ECN feedback via RTCP receiver reports [20], so the sender sees the congestion signal within one reporting interval and retains full control over how it responds: dropping enhancement layers, reducing resolution, going audio only, or switching codec profiles [21]. The network provides the signal; the codec provides the adaptation. If the sender does not respond, the unresponsive-flow head-drop of §3.4 applies. The result is targeted per-flow signaling without per-application congestion control.
6 Experimental Setup
We evaluate PFQD against DualPI2 (RFC 9332) and FQ-CoDel (RFC 8290) on a bandwidth x RTT sweep across six congestion-control pairings. The question is whether each discipline serves competing flows fairly, and what the flows then make of that service. All endpoints negotiate ECN (ECT(0)), so CE marks reach every CC; head-drop remains PFQD’s mechanism for Non-ECT traffic.
6.1 Methodology
All experiments use WarpSIM, a pure discrete-event network simulator operating at picosecond resolution. Every packet is modeled through serialization, propagation, queuing, and AQM processing, and every run is deterministic. CUBIC and BBRv3 are ports of the Linux kernel implementations, WarpRATE runs its current control law, and each sender closes its epochs on ACKs as the kernel does.
Topology. Senders (eg. SND1, SND2) connect through a shared bottleneck router (RTR) to a single receiver (RCV) (see Figure 1). Access links are modeled as unlimited so the bottleneck link alone sets the overall capacity. The router buffer is auto-sized at 1.5x the nominal BDP. Receivers advertise a 50 MB window, so the receive window never limits a flow.
Sweep parameters. Each experiment varies bottleneck link speed {12, 40, 120, 200, 1000} Mbps and base RTT {5, 10, 20, 50, 100} ms, yielding 25 operating points per configuration. Each flow transfers 20 MB. The BDP range spans 7.5 KB (12 Mbps / 5 ms) to 12.5 MB (1 Gbps / 100 ms).
CC pairings. Six pairings cover all combinations of CUBIC (window-based), WarpRATE (rate-based), and BBR (model-based): three identical pairs and three cross-pairings.
Qdiscs. All three run at default parameters. DualPI2 uses the gains of RFC 9332 Appendix A (alpha = 0.1 * T_update / RTT_max^2, beta = 0.3 / RTT_max). FQ-CoDel uses a 1500-byte quantum, a 5 ms CoDel target and a 100 ms interval. PFQD uses the per-flow ECN limit of §3.4, max(64 KB, C x 5 ms / N), and demotion at 2 seconds. PFQD and FQ-CoDel implement per-flow separate queues.
Metrics. A flow’s throughput depends on two things: the service the discipline gives it, and how its CC responds to that service and to the discipline’s signals. Only the first is the discipline’s responsibility. A CC that cuts its window on a mark and drains its queue forfeits the turns it no longer uses, and in a work-conserving scheduler the other flow takes them; that is the CC’s choice, not the scheduler’s unfairness. Fairness in the generalized-processor-sharing sense [2] is owed only to backlogged flows, and DRR’s relative fairness bound [1] compares service only over intervals in which both flows are backlogged. We therefore report three measures, all over data packets only (control packets are small, infrequent, and served ahead of data by design):
- Backlogged service share. The bytes each flow is served while both flows have data queued, as the ratio of the larger to the smaller. This is the scheduler’s fairness, and it applies to per-flow and shared queues alike. A cell is scored only if each flow receives at least 1 MB of such service; below that the two flows rarely queue at the same time and there is no scheduling to measure.
- Head-of-line wait. The time from a packet reaching the head of its flow’s queue to its departure, divided by the number of backlogged flows, counted while both flows are backlogged and reported per tier. This is the latency view of the same fairness for per-flow queues.
| Qdisc | Pair | Svc | Svc fair | Tput | Tput fair | Util |
|---|---|---|---|---|---|---|
| PFQD | C-C | 1.04 | 25/25 | 1.01 | 25/25 | 83% |
| PFQD | W-W | 1.00 | 25/25 | 1.00 | 25/25 | 97% |
| PFQD | C-B | 1.07 | 25/25 | 1.14 | 24/25 | 83% |
| PFQD | B-B | 1.06 | 25/25 | 1.01 | 25/25 | 87% |
| PFQD | C-W | 1.03 | 22/23 | 1.43 | 18/25 | 84% |
| PFQD | W-B | 1.11 | 20/23 | 1.25 | 23/25 | 89% |
| FQCDL | C-C | 1.04 | 25/25 | 1.01 | 25/25 | 86% |
| FQCDL | W-W | 1.05 | 24/25 | 1.01 | 25/25 | 97% |
| FQCDL | C-B | 2.00 | 17/25 | 1.07 | 25/25 | 85% |
| FQCDL | B-B | 1.10 | 23/25 | 1.01 | 25/25 | 87% |
| FQCDL | C-W | 2.14 | 13/23 | 1.27 | 21/25 | 88% |
| FQCDL | W-B | 1.26 | 19/23 | 1.24 | 23/25 | 90% |
| DPI2 | C-C | 1.14 | 24/25 | 1.08 | 25/25 | 72% |
| DPI2 | W-W | 1.20 | 21/25 | 1.13 | 24/25 | 92% |
| DPI2 | C-B | 2.17 | 11/25 | 2.63 | 12/25 | 68% |
| DPI2 | B-B | 1.06 | 25/25 | 1.03 | 25/25 | 87% |
| DPI2 | C-W | 5.03 | 4/22 | 3.38 | 6/25 | 65% |
| DPI2 | W-B | 2.86 | 8/23 | 1.62 | 13/25 | 85% |
- Throughput ratio and utilization. Each flow’s goodput over its transfer, as the ratio of the faster to the slower, and the bytes both flows deliver over link capacity times the transfer span. This is the outcome, and it includes each CC’s response.
A ratio of 1.0 is perfect; a trial counts as fair below 1.5. The dataset is 3 qdiscs x 6 pairings x 25 points x 10 seeds = 4,500 trials, each capped at 300 simulated seconds, long enough for a starved flow to finish rather than be truncated.
7 Results
Table 2 summarizes all 18 configurations (C = CUBIC, B = BBR, W = WarpRATE; FQCDL = FQ-CoDel, DPI2 = DualPI2). Svc is the mean backlogged service share across the scored points and Svc fair counts the points below 1.5; the denominator drops below 25 where the two flows never queued together long enough to score (§6.1). Tput and Tput fair are the same for the throughput ratio, and Util is mean link utilization. Each point averages ten seeds; the seed perturbs the NIC pacing phase, so every trial is a different packet interleaving.
7.1 Scheduler Fairness
7.1.1 PFQD: fair by construction, and measured so
PFQD’s backlogged service share stays between 1.00 and 1.11 in every pairing, and it scores fair at 142 of 146 scored points. That is the round-robin guarantee: while two flows both have data waiting, each gets the same number of turns, whatever CC sends it. Every enforcement action is a CE mark except at 12 Mbps, where the port buffer is at its smallest (§7.2).
7.1.2 FQ-CoDel: fair outcomes, uneven service
FQ-CoDel’s throughput looks as fair as PFQD’s (144 of 150 points), but its service while both flows are backlogged is not: the mixed pairings average 2.00 (CUBIC vs BBR) and 2.14 (CUBIC vs WarpRATE), and 121 of 146 points score fair, so its outcomes are fairer than its scheduling. The imbalance comes from its sparse-flow optimization: a flow that empties its queue and returns is served as new, ahead of the backlogged flow, and waits 0.21–0.27 packet times per queue against 0.92–0.99 for an old flow. It also drops: 145,182 packets across the sweep, up to 3,151 in a single trial (§7.2).
7.1.3 DualPI2: the allocation follows the marks
DualPI2 is unfair on both measures, 93 of 145 on service and 105 of 150 on throughput. Classic-ECN traffic, which is all three CCs here, shares one FIFO and one stochastic mark stream, so the allocation falls out of how each CC responds to the marks rather than out of any protection the discipline provides. CUBIC vs WarpRATE is the worst pairing, with a service share of 5.03 and a throughput ratio of 3.38 (worst point 12.5), and the mixed pairings run the link at 65–85%.
7.1.4 What the throughput ratio adds
Under PFQD the throughput ratio exceeds the service share only in the mixed pairings, CUBIC vs WarpRATE (1.43 against 1.03) and WarpRATE vs BBR (1.25 against 1.11). The scheduler served them evenly; the difference is how the CCs used their turns. A CUBIC flow that cuts its window on a mark leaves its queue empty for a while, and the turns it gives up go to the other flow, which is what a work-conserving scheduler should do with them. At 1 Gbps and 100 ms the two flows barely queue together at all, and the gap is startup speed: whichever CC reaches its share first carries more of a 20 MB transfer.
7.1.5 Head-of-line wait
The latency view agrees. While both flows are backlogged, a PFQD packet at the head of its queue waits about one packet time per active queue before it leaves: 0.89–0.99 in DHI and 1.00 in DLO, in every pairing. Demotion therefore costs a flow no waiting time while it competes. The two flows’ mean waits differ by at most 15% on average across the pairings, against up to 53% for FQ-CoDel and 13%–5.5x for DualPI2.
7.2 Utilization and Drops
Figure 2 plots the backlogged service share (top row, log scale) and link utilization (bottom row) for all six pairings across the sweep; the three columns share the same axes. PFQD’s points sit on the 1.0 line, while FQ-CoDel’s and DualPI2’s mixed pairings spread upward. PFQD holds 83–97% utilization across pairings, FQ-CoDel 85–97%, and DualPI2 65–92%, with DualPI2’s losses concentrated in the mixed pairings.
A note on high-BDP utilization. Utilization falls along the 1 Gbps row as RTT grows, and identically under all three disciplines: two BBR flows read 92, 85, 72, 47 and 27% from 5 to 100 ms under every one. A falloff no discipline moves is not a discipline effect; it is ramp time, since at 1 Gbps and 100 ms the 20 MB transfer ends before the CCs reach their share.
Drops. PFQD drops 29,581 packets across the sweep, all at 12 Mbps and all in pairings with BBR or WarpRATE; two CUBIC
flows lose none. The marks still fire there, 9,000 to 28,000 per trial, but the flows overrun a buffer sized at 1.5x a 7.5–150 KB BDP before their senders slow down, and BBRv3 heeds CE only on paths under 5 ms and only once half its data is marked. A PFQD port should be provisioned for the BDPs it expects to serve, with headroom, so that the per-flow mark limit sits well inside it. Switch ports carry far more memory than this sweep gives them, and a host’s PFQD never drops. FQ-CoDel and DualPI2 drop 145,182 and 115,201 packets, 61% and 87% of them at 12 Mbps, where their delay targets bite on the same small pipe, and most of the rest in WarpRATE pairings at 5 and 10 ms; FQ-CoDel’s per-trial worst is 3,151 and DualPI2’s 6,022, both in pairings with WarpRATE.
7.3 Predictability
Figure 3 asks whether the outcome is predictable: for each point, the standard deviation across the ten seeds of the throughput ratio (top row) and of the combined throughput as a share of link capacity (bottom row), with the typical Internet BDP range of 50 KB to 2 MB [23] shaded. The figure plots the three same-CC pairings; the counts below cover all six, with a point said to vary when its ratio’s deviation exceeds 0.005. PFQD varies at 8 of 150 points, never by more than 0.10 in the ratio or 0.9% of link capacity. FQ-CoDel varies at 14, up to 0.11 and 1.3%. DualPI2 varies at 31 of 150, spread across pairings and through the typical-Internet band, up to 0.35 in the ratio and 3.6% of link capacity: the same link can measure fair on one trial and unfair on the next with nothing changed but packet-arrival phase, and an operator cannot tune away what does not reproduce.
8 Related Work
Per-flow fair queuing has a long academic and operational history [24] [1] [2]. PFQD builds on this foundation while making a distinct argument about what belongs in the queueing discipline and what does not.
8.1 DualPI2 (RFC 9332, 2023)
DualPI2 achieves class-level fairness between L4S and Classic traffic using a PI controller with coupled marking. The key distinction is structural: DualPI2 provides fairness between two traffic classes; PFQD provides fairness between individual flows. A class-level controller cannot distinguish two flows competing within the same queue, and the evaluation shows the consequence is not theoretical: within a class the allocation follows how much attention each endpoint pays to the shared mark stream, and the flow that backs off hardest loses (§7.1).
8.2 FQ-CoDel (RFC 8290, 2018)
FQ-CoDel is the closest existing per-flow fair queue, deployed on millions of Linux systems. Its throughput fairness and utilization match PFQD’s (§7.1), and the differences lie in scheduling and enforcement. Its sparse-flow optimization serves a flow that returns from an empty queue ahead of the backlogged one, so service while both flows compete is less even than PFQD’s (121 against 142 of 146 points fair). Its per-flow CoDel instances hold their delay target with packet loss as well
as marks, and drop 145,182 packets across the sweep against PFQD’s 29,581, all of PFQD’s at 12 Mbps (§7.2).
8.3 Classical Fair Queuing and Linux sch_fq
Weighted Fair Queuing [24] and Deficit
Round-Robin [1] provide the theoretical and algorithmic foundation for per-flow
scheduling. PFQD’s round-robin dequeue is a packet-count simplification of DRR. Linux’s sch_fq
(Dumazet, 2013) is the closest operational precedent for PFQD’s control-packet priority: it
maintains a high-priority FIFO for TC_PRIO_CONTROL packets (including SYN) and provides
host-side pacing. In practice, deploying both sch_fq (pacing, SYN priority) and fq_codel
(per-flow AQM at the router) approximates what PFQD provides in a single mechanism.
8.4 Information-Agnostic Scheduling and Receiver-Driven Transports
PFQD’s tiering belongs to the information-agnostic line PIAS [25] made canonical: priority queues approximate shortest-remaining-first without knowing flow sizes by demoting a flow as it sends. PIAS demotes by bytes sent, PFQD by time in the high tier, with a bytes-in-tier option planned. The information-aware line, pFabric [26] and Homa [27], reaches lower short-message completion times by letting a receiver that knows message sizes schedule and admit traffic, at the price of a transport on both ends and an accounting that sees only its flows. PFQD differs in deployment: one qdisc on one host or router, unmodified peers, and isolation that holds for the whole population of the queue rather than for the participants of a protocol.
9 Conclusion
This paper’s evaluation reduces to an argument about incentives. Inside a shared queue, ECN is not incentive-compatible: every mark a responsive sender honors surrenders capacity that a less responsive neighbor absorbs, so the flow that backs off hardest loses the link (§7.1), and a signal that is profitable to ignore trains the endpoint population to ignore it.
The ecosystem’s drift toward model-driven senders that discount classic ECN is that pressure already at work, and a shared-queue AQM’s remaining recourse is enforcement by loss, which FQ-CoDel pays for in retransmissions even at fair outcomes.
Per-flow scheduling eliminates the dilemma instead of policing it: a flow that ignores its marks fills only its queue and starves only itself, so obedience is safe, defection is pointless, and fairness rests on the scheduler rather than on endpoint virtue. The same argument reaches admission control: a receiver-driven transport such as Homa [27] bounds queueing only for the flows it can account for, and one flow that is not a participant returns the port to best effort, where PFQD’s isolation holds for the population it cannot see. The contribution is that fair round-robin scheduling, explicit control-packet priority tiers, and a per-flow ECN limit displace the control-loop complexity DualPI2 and FQ-CoDel devote to fairness at shared bottlenecks, and the state and arithmetic budget fits router silicon constraints, per §4.
Where to focus first. High-speed WAN links rarely queue; congestion lives at the edge, at the access port facing the subscriber. A residential gateway at 300 Mbps and 8 ms RTT sits at a 300 KB BDP, inside the range where our evaluation shows DualPI2 misallocating capacity. Edge crossover points (DSLAM, CMTS, eNodeB, residential gateway) are where the problem is worst and easiest to address.
10 Statement on AI Use
AI, specifically models and tools provided by Anthropic, were used to create simulation harnesses, organize data sets, and validate implementations against specifications.
References
- [1] M. Shreedhar and G. Varghese, “Efficient Fair Queuing Using Deficit Round-Robin,” in Proceedings of ACM SIGCOMM, 1995, pp. 231–242.
- [2] A. Parekh and R. Gallager, “A Generalized Processor Sharing Approach to Flow Control in Integrated Services Networks: The Single-Node Case,” IEEE/ACM Transactions on Networking, vol. 1, no. 3, pp. 344–357, 1993.
- [3] K. De Schepper, B. Briscoe, O. Bondarenko, I. Tsang, and K. Hedayat, “DualQ Coupled AQMs for Low Latency, Low Loss, and Scalable Throughput (L4S),” RFC 9332, 2023.
- [4] M. Allman, V. Paxson, and E. Blanton, “TCP Congestion Control,” RFC 5681, 2009.
- [5] L. Xu, S. Ha, I. Rhee, V. Goel, and L. Eggert, “CUBIC for Fast and Long-Distance Networks.” RFC Editor, Aug. 2024. doi: 10.17487/RFC9438.
- [6] B. Briscoe, K. De Schepper, M. Bagnulo, and G. White, “Low Latency, Low Loss, and Scalable Throughput (L4S) Internet Service: Architecture,” RFC 9330, 2023.
- [7] S. Bensley, D. Thaler, P. Balasubramanian, L. Eggert, and G. Judd, “Data Center TCP (DCTCP): TCP Congestion Control for Data Centers,” RFC 8257, 2017.
- [8] K. De Schepper, O. Tilmans, and B. Briscoe, “Prague Congestion Control,” technical report, 2023.
- [9] B. Briscoe and K. De Schepper, “PI\textsuperscript{2} Parameters,” arXiv preprint arXiv:2107.01003, 2021.
- [10] D. Vadura, “WarpRATE: A Rate-Paced CC Solution,” technical report, 2026.
- [11] N. Cardwell, Y. Cheng, C. Gunn, S. Yeganeh, and V. Jacobson, “BBR: Congestion-Based Congestion Control,” ACM Queue, vol. 14, no. 5, pp. 20–53, 2016.
- [12] K. De Schepper, O. Albisser, O. Tilmans, and B. Briscoe, “Dual Queue Coupled AQM: Deployable Very Low Queuing Delay for All,” arXiv preprint arXiv:2209.01078, 2022.
- [13] T. Xu et al., “Do Not Blame Users for Misconfigurations,” in Proceedings of the 24th ACM SOSP, 2013, pp. 244–259.
- [14] R. Mahajan, D. Wetherall, and T. Anderson, “Understanding BGP Misconfiguration,” in Proceedings of ACM SIGCOMM, 2002, pp. 3–16.
- [15] A. Sivaraman et al., “Programmable Packet Scheduling at Line Rate,” in Proceedings of ACM SIGCOMM, 2016, pp. 44–57.
- [16] N. K. Sharma, M. Liu, K. Atreya, and A. Krishnamurthy, “Approximating Fair Queueing on Reconfigurable Switches,” in Proceedings of USENIX NSDI, 2018, pp. 1–16.
- [17] R. Kundel, J. Blendin, T. Viernickel, B. Koldehofe, and R. Steinmetz, “P4-CoDel: Active Queue Management in Programmable Data Planes,” in Proceedings of IEEE NFV-SDN, 2018.
- [18] T. Hoeiland-Joergensen, P. McKenney, D. Taht, J. Gettys, and E. Dumazet, “The Flow Queue CoDel Packet Scheduler and Active Queue Manager,” RFC 8290, 2018.
- [19] I. Johansson and Z. Sarker, “Self-Clocked Rate Adaptation for Multimedia,” RFC 8298, 2017.
- [20] M. Westerlund, I. Johansson, C. Perkins, P. O'Hanlon, and K. Carlberg, “Explicit Congestion Notification (ECN) for RTP over UDP,” RFC 6679, 2012.
- [21] C. Krasic, K. Li, and J. Walpole, “Quality-Adaptive Media Streaming by Priority Drop,” in Proceedings of the 13th International Workshop on Network and Operating Systems Support for Digital Audio and Video (NOSSDAV), ACM, 2003.
- [22] C. Raiciu et al., “How Hard Can It Be? Designing and Implementing a Deployable Multipath TCP,” in Proceedings of the 9th USENIX Symposium on Networked Systems Design and Implementation (NSDI), USENIX, 2012.
- [23] Ookla, “Speedtest Global Index,” technical report, 2025.
- [24] A. Demers, S. Keshav, and S. Shenker, “Analysis and Simulation of a Fair Queueing Algorithm,” in Proceedings of ACM SIGCOMM, 1989, pp. 1–12.
- [25] W. Bai, L. Chen, K. Chen, D. Han, C. Tian, and H. Wang, “Information-Agnostic Flow Scheduling for Commodity Data Centers,” in 12th USENIX Symposium on Networked Systems Design and Implementation (NSDI '15), USENIX Association, 2015, pp. 455–468.
- [26] M. Alizadeh et al., “pFabric: Minimal Near-Optimal Datacenter Transport,” in Proceedings of the ACM SIGCOMM 2013 Conference, ACM, 2013, pp. 435–446. doi: 10.1145/2486001.2486031.
- [27] B. Montazeri, Y. Li, M. Alizadeh, and J. Ousterhout, “Homa: A Receiver-Driven Low-Latency Transport Protocol Using Network Priorities,” in Proceedings of the ACM SIGCOMM 2018 Conference, ACM, 2018, pp. 221–235. doi: 10.1145/3230543.3230564.