Strict priority and deficit round robin (DRR) answer the same question in different ways: which queued packet leaves next. In ns-3 both belong in the Traffic Control layer, implemented as queue discs. The two questions readers usually ask have direct answers. ns-3 provides a classful strict-priority discipline, PrioQueueDisc, that serves as the built-in reference for priority treatment. The ns-3 documentation covered here does not describe a standalone, general-purpose DRR discipline. Its closest built-in relative is FqCoDelQueueDisc, whose scheduler is a modified DRR, but that class also classifies packets into flow queues and applies CoDel to each queue. For plain DRR you will usually write your own QueueDisc subclass and treat FQ-CoDel as a reference for the mechanics, or accept FQ-CoDel knowingly with its AQM attached.
The mechanics below are described against the ns-3.45 queue-disc documentation and the older PrioQueueDisc class reference. The target ns-3 release for your project is not specified here, so confirm class names, attributes, band ordering and defaults in the release you build. This article gives design rules and test designs rather than a compile-ready module, because the release and your integration path decide which class to extend.
As an Amazon Associate I earn from qualifying purchases.
Where a scheduler sits in ns-3 Traffic Control
The Traffic Control layer sits between network-layer protocols and the NetDevice. Packets handed down from the network layer pass through a queue disc before they reach the device’s transmit path. When the link is the bottleneck, the queue disc is where departure order is decided. That makes it the correct extension point for a scheduler; a change inside the NetDevice or the protocol stack is the wrong place for it.
Free tools Windows power users keep installed
One-click scans. No signup required.
QueueDisc is an abstract base class. A subclass supplies the behaviour by implementing the hooks the base class calls: enqueue, dequeue, peek, and configuration checking (named DoEnqueue, DoDequeue, DoPeek and CheckConfig in ns-3’s naming). The base class also exposes queue and packet statistics and a sojourn-time trace, which are the observation points you will use when testing.
#1 Best Overall
Keep policy and classification separate
Each arriving packet involves two decisions that are easy to blur together. Classification answers “which queue or class does this packet belong to?” Policy answers “when a queue is eligible, which head packet leaves next?” The ns-3 documentation states that a multi-queue or multi-class discipline needs an external packet filter for classification. If that wiring is missing, packets have no reliable destination queue, and a scheduler that looks correct in code will appear to do nothing in simulation.
Define the mapping before writing the scheduler. The table below shows one example of a mapping from DSCP marking to band index, with band 0 as the highest priority. It is an illustration for your own design, not an ns-3 default.
| Traffic marking (example) | Band index (0 = highest) | Typical use in this example |
|---|---|---|
| DSCP EF | 0 | Latency-sensitive traffic such as voice |
| DSCP AF41 | 1 | Interactive or video traffic |
| Default (best effort) | 2 | Bulk or background traffic |
Whatever mapping you choose, make the classifier total and explicit:
- Attach one packet filter, or one classifier function you own, that returns a band or class index for every packet.
- Define a default band for packets the filter does not match. If you have no default, reject that configuration in
CheckConfig. - Treat an out-of-range index as a configuration error, not as a silent move to another band.
Strict priority
Layout and configuration
- One internal queue per band, each with its own packet limit, plus a total limit if your model needs one.
- A fixed band count set at construction or configuration time. Changing it at runtime complicates tests and should be avoided unless you need it.
CheckConfigshould reject zero bands, a missing classifier, a missing default band, and limits that are zero where a queue must hold packets.
Dequeue rule
Strict priority is a short rule. Each time the device asks for a packet:
- Scan bands from index 0 upward.
- In the first band that holds at least one packet, remove and return its head packet.
- If every band is empty, return nothing.
DoPeekperforms the same scan without removing the packet, so peek and dequeue always agree.
Use the built-in PrioQueueDisc in your release as the reference for the band ordering it applies. Do not assume a convention from memory; check the ordering and the classifier mapping in the source of the release you build.
Preemption and starvation
Priority applies at packet boundaries. The discipline chooses the next packet when the device requests one, so a packet already being transmitted is not interrupted. A high-priority packet that arrives mid-transmission waits for the current packet to finish and then goes first.
The same rule causes starvation. While band 0 has a backlog, bands 1 and 2 receive no service. If the offered load in band 0 stays above the link rate, the lower bands can be starved for the whole run. This is the intended behaviour of strict priority, not a bug, but it must be stated in any result that compares it with DRR.
Deficit round robin
State you must keep
- An active list: the queues that currently hold packets, in round-robin order.
- A deficit counter per queue, in bytes. Use a 64-bit signed integer so that a negative value cannot wrap if your rule allows one.
- The quantum, in bytes, as an explicit configuration value.
- The state of the queue currently being visited, including whether its quantum has already been added for this visit.
The visit procedure
DRR is harder than strict priority for one reason: DoDequeue returns one packet per call, but a visit to a queue may send several packets. The visit state must therefore persist across calls. The procedure is:
Rank #3
- If the active list is empty, return nothing.
- If the queue at the head of the active list is not mid-visit, start a visit by adding the quantum to its deficit.
- While the head packet’s size is at most its deficit, remove that packet, subtract its size from the deficit, and return it.
- When the queue is empty, set its deficit to zero and remove it from the active list.
- When the queue still has packets but the head packet does not fit the deficit, end the visit and move the queue to the back of the active list.
on dequeue:
if no visit in progress:
q = active_list.front()
q.deficit += quantum
visit_in_progress = true
while q.head.size ≤ q.deficit:
q.deficit -= q.head.size
return q.pop()
if q.empty(): q.deficit = 0; active_list.remove(q)
else: active_list.move_to_back(q)
visit_in_progress = false
On enqueue to an empty queue, append that queue to the back of the active list once, with its deficit reset to zero. Appending it more than once is a common bug that gives one flow double service.
Packets larger than the quantum
A head packet larger than the quantum cannot leave on the visit where it is first examined. With the classic rule the deficit carries over, so the packet is sent after enough rounds have added credit. That keeps long-run shares fair but can stall a queue with large packets for several rounds. The alternative is to enforce a quantum at least as large as the maximum packet size in CheckConfig, so every visit can send at least one full-size packet. FQ-CoDel’s quantum defaults to the device MTU, which is the same idea applied to a common case. Pick one rule, document it in the code, and test it.
What ns-3 already provides
The table compares the built-in options with the custom design. “Not stated” means the ns-3 documentation consulted here does not specify that behaviour; check the source of your release before relying on it.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →| Option | Service rule | Classification | Per-queue AQM | Starvation risk | Status in ns-3 documentation |
|---|---|---|---|---|---|
| PrioQueueDisc | Strict priority by band index | External packet filter | Not stated | Yes, under persistent high-priority load | Built-in classful priority reference; verify band ordering in your release |
| FqCoDelQueueDisc | Modified DRR with new and old flow lists, byte deficits | Flow classification into queues | CoDel per queue | Not stated as a general property | Built-in; default quantum equals device MTU at initialization, changeable through its setter |
| Custom DRR QueueDisc | Plain DRR with your quantum and visit rules | External packet filter you define | None unless you add it | Not applicable; long-run shares depend on quantum and packet sizes | Written by you against the QueueDisc base class |
Some FQ-CoDel documentation also lists a default of 1024 flow queues. That value depends on the documentation version you read, so confirm it in your release before quoting it.
Rank #4
- Used Book in Good Condition
Choosing the DRR quantum
The quantum sets how many bytes a queue may send during one visit. It is the main control you have over short-term behaviour:
- A small quantum gives finer byte-level fairness across queues with unequal packet sizes, because queues alternate more often. The cost is more visits per byte, more bookkeeping, and a queue with large packets waits more visits to send one.
- A large quantum reduces the number of rounds. Each queue sends bursts of up to a quantum’s worth of bytes before yielding. Long-run shares are unchanged, but short-term service is burstier.
- A quantum at least equal to the device MTU, as FQ-CoDel uses by default, is a sensible baseline. It guarantees that a visit can send one full-size packet.
Expose the quantum as a configuration value and report it in every experiment. Changing it changes short-term delay even when throughput looks identical.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Build a QueueDisc or modify FQ-CoDel?
Choose a custom QueueDisc when the study needs plain DRR, explicit per-class queues, or an exactly defined dequeue order that you can test. A custom discipline also keeps AQM out of the measurement, so differences in results come from the scheduler alone.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallChoose FQ-CoDel when the study needs flow-hashed classification, per-queue CoDel and the sparse-flow handling that the new flow list provides. RFC 8290 (IETF, January 2018, Experimental) describes FQ-CoDel as a combined packet scheduler and AQM based on modified DRR and notes reference implementations for ns-2 and ns-3. Use it as the reference for those behaviours. Do not attribute its AQM effects to generic DRR.
Best Value
In short, if the question is about scheduling alone, write a custom DRR. If the question is about latency under realistic mixed flows, FQ-CoDel is the appropriate reference.
Validating the scheduler
Test the dequeue order directly. Aggregate throughput hides the difference between a correct scheduler and one that merely moves the same bytes.
- Strict priority service: enqueue distinguishable packets into three bands while band 0 is non-empty. Verify that band 0 is served first, in arrival order within the band, and that lower bands are served only after band 0 empties.
- Strict priority starvation: keep band 0 backlogged with an arrival rate above the link rate. Verify that bands 1 and 2 dequeue nothing during that interval, then stop band 0 and verify that they drain.
- DRR byte accounting: with a known quantum and two queues of unequal packet sizes, verify that the deficit changes by exactly the transmitted byte count at each dequeue.
- Oversized head packet: place a packet larger than the quantum at the head of a queue. Verify that it waits for accumulated credit under your chosen rule, or is rejected by
CheckConfigif you enforce the MTU rule. - Active list transitions: verify that an empty-to-active transition adds the queue once, that queue exhaustion resets its deficit and removes it, and that no queue appears twice.
- Limits and drops: verify per-queue and total limits, confirm that drops appear in the queue statistics, and confirm that any requeue path leaves the deficit consistent.
- Delay ordering: use the sojourn-time trace to confirm the expected delay ordering between classes.
These are recommended test designs derived from the scheduler rules above. They are not measured results from a particular build.
Keeping comparisons fair
When you compare strict priority with DRR, hold everything except the scheduler constant: classification, packet sizes, queue limits, link rate, offered load, simulation duration and random seeds. Report per-class throughput, sojourn time, drops, and a fairness measure with its formula stated. State the quantum used for DRR, and state the band layout used for strict priority.
Two expectations should be stated before running the experiment. Strict priority will starve lower classes under persistent high-priority load. DRR’s short-interval shares depend on the quantum, so a comparison over a short window can mislead unless the quantum is reported.
Version and integration checks
- Record the ns-3 release and the source revision you build against. Class names and defaults change across releases.
- Verify band ordering and classifier mapping in the PrioQueueDisc source of that release.
- Verify FQ-CoDel attribute names, the quantum default and the flow-queue default in that release.
- Community code repositories contain alternative custom designs. They are project-specific and are not official ns-3 patterns, so treat them as examples to read rather than templates to copy.
Sources for the statements above are the ns-3 QueueDisc class reference, the ns-3.45 queue-disc model documentation, the ns-3 development documentation for FQ-CoDel, the ns-3 Traffic Control module reference, the older PrioQueueDisc class reference, and RFC 8290.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




