Queue Tree
Queue Tree
Section titled “Queue Tree”TL;DR (Quick Start)
Section titled “TL;DR (Quick Start)”For the impatient: basic traffic prioritization setup.
Step 1: Create packet marks in mangle
/ip/firewall/mangle/add chain=forward protocol=udp dst-port=5060-5061 \ action=mark-packet new-packet-mark=voip passthrough=noStep 2: Create queue tree
/queue/tree/add name=total parent=global max-limit=100M/queue/tree/add name=voip-queue parent=total packet-mark=voip priority=1 max-limit=10M/queue/tree/add name=other parent=total packet-mark=no-mark priority=8 max-limit=90MVerify with:
/queue/tree/print statsOverview
Section titled “Overview”What this does: Queue Tree implements hierarchical traffic shaping using HTB (Hierarchical Token Bucket) for advanced QoS. It creates unidirectional queues attached to HTB trees, allowing traffic prioritization, bandwidth allocation, and guaranteed minimum rates.
When to use this:
- Prioritizing VoIP/gaming over bulk downloads
- Implementing global QoS policies
- Fair bandwidth distribution with PCQ
- Per-interface bandwidth control
- Scenarios requiring hierarchical bandwidth allocation
Prerequisites:
- Packet marks from
/ip/firewall/mangle - FastTrack disabled (or excluded for queued traffic)
- Understanding of HTB parent/child relationships
FastTrack Conflict
FastTrack bypasses mangle and queue processing. You must disable FastTrack or exclude traffic from FastTrack before it can be queued.
Queue Tree vs Simple Queues
Section titled “Queue Tree vs Simple Queues”| Aspect | Simple Queue | Queue Tree |
|---|---|---|
| Direction | Bidirectional (one entry) | Unidirectional |
| Marking required | No (uses target IP) | Yes (packet marks) |
| Processing | Sequential (ordered) | Parallel (non-ordered) |
| Configuration | Simpler | More complex |
| CPU usage | Multi-core | Single core |
| Use case | Per-client limits | Global QoS, prioritization |
Use Queue Tree when: You need traffic prioritization, hierarchical QoS, or per-interface control.
Use Simple Queues when: You just need per-IP bandwidth limits.
Configuration Steps
Section titled “Configuration Steps”Step 1: Disable FastTrack
Section titled “Step 1: Disable FastTrack”FastTrack bypasses queue processing. Disable it:
/ip/firewall/filter/disable [find action=fasttrack-connection]Or exclude specific traffic before FastTrack:
/ip/firewall/filter/add chain=forward src-address=192.168.1.0/24 action=accept \ place-before=[find action=fasttrack-connection]Clear existing FastTracked connections:
/ip/firewall/connection/remove [find fasttrack=yes]Step 2: Create Packet Marks (Mangle)
Section titled “Step 2: Create Packet Marks (Mangle)”Queue Tree requires packet marks. Mark traffic in mangle:
# Mark VoIP traffic/ip/firewall/mangle/add chain=forward protocol=udp dst-port=5060-5061 \ action=mark-packet new-packet-mark=voip passthrough=no comment="VoIP SIP"/ip/firewall/mangle/add chain=forward protocol=udp dst-port=10000-20000 \ action=mark-packet new-packet-mark=voip passthrough=no comment="VoIP RTP"
# Mark bulk downloads (large connections)/ip/firewall/mangle/add chain=forward protocol=tcp dst-port=80,443 \ connection-bytes=500000-0 action=mark-packet new-packet-mark=bulk \ passthrough=no comment="Large HTTP connections"Step 3: Create Parent Queue
Section titled “Step 3: Create Parent Queue”Create the top-level queue with total bandwidth:
/queue/tree/add name=total-bandwidth parent=global max-limit=100MStep 4: Create Child Queues
Section titled “Step 4: Create Child Queues”Add prioritized child queues:
# High priority: VoIP (guaranteed 2M, max 10M, priority 1)/queue/tree/add name=voip parent=total-bandwidth packet-mark=voip \ limit-at=2M max-limit=10M priority=1
# Low priority: Bulk (guaranteed 10M, max 80M, priority 8)/queue/tree/add name=bulk parent=total-bandwidth packet-mark=bulk \ limit-at=10M max-limit=80M priority=8
# Catch-all: Unmarked traffic/queue/tree/add name=other parent=total-bandwidth packet-mark=no-mark \ limit-at=20M max-limit=80M priority=4Step 5: Verify Configuration
Section titled “Step 5: Verify Configuration”Check mangle is marking packets:
/ip/firewall/mangle/print stats where new-packet-mark!=Check queue tree is processing traffic:
/queue/tree/print statsCommon Scenarios
Section titled “Common Scenarios”Scenario: PCQ Fair Bandwidth Distribution
Section titled “Scenario: PCQ Fair Bandwidth Distribution”Equal bandwidth per user automatically:
Step 1: Create PCQ queue types
/queue/type/add name=pcq-download kind=pcq pcq-rate=10M pcq-classifier=dst-address/queue/type/add name=pcq-upload kind=pcq pcq-rate=5M pcq-classifier=src-addressStep 2: Mark traffic by direction
/ip/firewall/mangle/add chain=forward in-interface=ether1-WAN \ action=mark-packet new-packet-mark=download passthrough=no/ip/firewall/mangle/add chain=forward out-interface=ether1-WAN \ action=mark-packet new-packet-mark=upload passthrough=noStep 3: Create queue trees with PCQ
/queue/tree/add name=client-download parent=global packet-mark=download \ queue=pcq-download max-limit=100M/queue/tree/add name=client-upload parent=global packet-mark=upload \ queue=pcq-upload max-limit=50MScenario: Interface-Specific Queuing
Section titled “Scenario: Interface-Specific Queuing”Limit bandwidth on a specific interface:
# Mark traffic going to LAN/ip/firewall/mangle/add chain=forward out-interface=ether2-LAN \ action=mark-packet new-packet-mark=to-lan passthrough=no
# Create queue on interface/queue/tree/add name=lan-limit parent=ether2-LAN packet-mark=to-lan max-limit=50MScenario: Burst Configuration
Section titled “Scenario: Burst Configuration”Allow temporary speed boost for interactive traffic:
/queue/tree/add name=interactive parent=global packet-mark=interactive \ max-limit=10M limit-at=2M \ burst-limit=50M burst-threshold=5M burst-time=16s \ priority=2This provides:
- Guaranteed 2 Mbps (
limit-at) - Normal maximum 10 Mbps (
max-limit) - Burst to 50 Mbps when average < 5 Mbps over 16 seconds
- Maximum burst duration: 5M × 16s / 50M = 1.6 seconds
Scenario: Gaming Priority
Section titled “Scenario: Gaming Priority”Prioritize gaming traffic:
# Mark gaming ports/ip/firewall/mangle/add chain=forward protocol=udp dst-port=3074,3478-3480 \ action=mark-packet new-packet-mark=gaming passthrough=no comment="Xbox/PlayStation"
# High priority queue/queue/tree/add name=gaming parent=total-bandwidth packet-mark=gaming \ limit-at=5M max-limit=20M priority=1Scenario: Connection Mark Then Packet Mark
Section titled “Scenario: Connection Mark Then Packet Mark”For stateful marking (more efficient):
# Mark connection first/ip/firewall/mangle/add chain=forward connection-state=new protocol=tcp dst-port=80,443 \ action=mark-connection new-connection-mark=http-conn passthrough=yes
# Then mark packets based on connection/ip/firewall/mangle/add chain=forward connection-mark=http-conn \ action=mark-packet new-packet-mark=http-pkt passthrough=noScenario: DSCP-Based Prioritization
Section titled “Scenario: DSCP-Based Prioritization”Use DSCP markings from upstream devices:
# Mark based on DSCP/ip/firewall/mangle/add chain=forward dscp=46 \ action=mark-packet new-packet-mark=ef-traffic passthrough=no comment="DSCP EF"
# Priority queue for EF traffic/queue/tree/add name=expedited parent=global packet-mark=ef-traffic priority=1 max-limit=10MKey Concepts
Section titled “Key Concepts”HTB Parent Options
Section titled “HTB Parent Options”| Parent | Description |
|---|---|
global | Global HTB tree (affects all traffic) |
global-in | Ingress global tree |
global-out | Egress global tree |
<interface> | Interface-specific tree (e.g., ether1) |
<queue-name> | Another queue tree (hierarchical) |
Priority vs Limit-At
Section titled “Priority vs Limit-At”limit-at: Guaranteed minimum bandwidth (CIR)max-limit: Maximum bandwidth ceiling (MIR)priority: Distributes bandwidth above limit-at values
Priority only matters when there’s excess bandwidth. Lower number = higher priority.
Burst Parameters
Section titled “Burst Parameters”| Parameter | Description |
|---|---|
burst-limit | Maximum rate during burst |
burst-threshold | Average rate below which burst activates |
burst-time | Window for calculating average rate |
Formula: max-burst-duration = burst-threshold × burst-time / burst-limit
Verification
Section titled “Verification”Confirm Queue Tree is working:
Check 1: Verify Mangle Marks
Section titled “Check 1: Verify Mangle Marks”/ip/firewall/mangle/print stats where new-packet-mark!=Expected: Non-zero bytes/packets for active rules.
Check 2: Verify Queue Tree Traffic
Section titled “Check 2: Verify Queue Tree Traffic”/queue/tree/print statsExpected: Non-zero rate/bytes for active queues.
Check 3: Check FastTrack Status
Section titled “Check 3: Check FastTrack Status”/ip/firewall/filter/print where action=fasttrack-connectionExpected: Disabled, or traffic excluded before it.
Check 4: Verify No FastTracked Connections
Section titled “Check 4: Verify No FastTracked Connections”/ip/firewall/connection/print where fasttrack=yesExpected: Empty if FastTrack properly disabled.
Check 5: Check for Dropped Packets
Section titled “Check 5: Check for Dropped Packets”/queue/tree/print stats where dropped>0High dropped count indicates queue overflow.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Cause | Solution |
|---|---|---|
| Queue shows zero traffic | FastTrack bypassing | Disable FastTrack; clear fasttracked connections |
| Mangle shows hits but queue empty | Using connection mark not packet mark | Create packet mark from connection mark |
| Unmarked traffic exceeds limits | Missing no-mark queue | Add packet-mark=no-mark catch-all queue |
| Priority not working | Sum of limit-at exceeds parent | Ensure sum of children limit-at ≤ parent max-limit |
| Upload works, download doesn’t | Wrong parent for traffic direction | Use appropriate parent (global-in/out or interface) |
| Prerouting marks not working | v6+ packet flow changes | Use forward or postrouting chain instead |
| Bridged traffic not queued | Bridge firewall disabled | Enable use-ip-firewall=yes on bridge |
| DNS slow after adding queue | Global parent affects router traffic | Use interface parent or exclude router traffic |
| Burst never activates | Threshold misconfigured | Set threshold between limit-at and max-limit |
Debug: Check Packet Flow
Section titled “Debug: Check Packet Flow”/ip/firewall/mangle/print statsIf mangle shows zero hits, traffic isn’t reaching those rules.
Debug: Check Parent-Child Limits
Section titled “Debug: Check Parent-Child Limits”Verify child limit-at values don’t exceed parent:
/queue/tree/print where parent=total-bandwidthSum of limit-at should be ≤ parent’s max-limit.
Common Mistakes
- Forgetting to disable FastTrack - Most common cause of queue tree not working
- Using connection mark instead of packet mark - Queue tree requires packet marks
- No catch-all queue - Unmarked traffic bypasses queue tree entirely
- limit-at sum too high - Children’s guaranteed bandwidth can’t exceed parent’s maximum
- Wrong chain for marking - Use forward/postrouting, not prerouting for incoming traffic
- Global parent affecting DNS - Router’s own traffic queued; use interface parent
Related Topics
Section titled “Related Topics”Prerequisites
Section titled “Prerequisites”- Firewall Mangle - create packet marks for queue tree
- NAT Masquerade - understand packet flow order
Alternative QoS
Section titled “Alternative QoS”- Simple Queues - simpler per-target bandwidth limiting
Related Topics
Section titled “Related Topics”- Firewall Basics - FastTrack conflicts with queues
- Torch - monitor traffic for QoS tuning
- SNMP - remote queue statistics
Reference
Section titled “Reference”Key Commands Reference
Section titled “Key Commands Reference”| Command | Description |
|---|---|
/queue/tree/add | Create queue tree entry |
/queue/tree/print | View all entries |
/queue/tree/print stats | View statistics |
/queue/tree/reset-counters | Reset byte/packet counters |
/queue/type/add | Create queue type (PCQ, etc.) |
Queue Tree Properties
Section titled “Queue Tree Properties”| Property | Type | Default | Description |
|---|---|---|---|
name | string | - | Unique identifier (required) |
parent | string | - | HTB parent: global, interface, or queue name |
packet-mark | string | - | Packet mark from mangle |
max-limit | rate | 0 | Maximum bandwidth (MIR) |
limit-at | rate | 0 | Guaranteed minimum (CIR) |
priority | 1-8 | 8 | Priority (1=highest) |
queue | string | default | Queue type |
burst-limit | rate | 0 | Maximum burst rate |
burst-threshold | rate | 0 | Threshold for burst activation |
burst-time | time | 0s | Averaging window |
Statistics (Read-Only)
Section titled “Statistics (Read-Only)”| Property | Description |
|---|---|
rate | Current data rate |
packet-rate | Current packet rate |
bytes | Total bytes processed |
packets | Total packets processed |
queued-bytes | Bytes in queue buffer |
queued-packets | Packets in queue buffer |
dropped | Packets dropped (overflow) |