MikroTik Queue Tree & QoS for ISPs: Bandwidth Management Done Right
Simple Queues work when you have 50 subscribers. At 500+ they become a CPU-hungry bottleneck with zero traffic intelligence. This guide shows you how to replace them with Queue Tree — MikroTik's hierarchical bandwidth engine that lets you guarantee, limit, prioritise, and fairly share bandwidth across thousands of users.
Why Simple Queues Stop Working
MikroTik Simple Queue is a flat list — one entry per subscriber, evaluated linearly. It has three fundamental limitations at ISP scale:
No Hierarchy
You can't group zones or share unused bandwidth between them. Zone A sits idle while Zone B is congested.
No Traffic Classes
VoIP, gaming, and bulk downloads all fight equally. A single torrent user can ruin VoIP for everyone.
CPU Bottleneck
At 1,000+ queues the linear evaluation burns CPU. Mid-range boards start dropping packets.
Queue Tree with HTB (Hierarchical Token Bucket) solves all three. It's the same technology Tier-1 carriers use — and MikroTik gives it to you for free.
How Queue Tree Works: Mark → Queue → Shape
Queue Tree operates in three stages:
- Mangle rules mark packets with a
packet-markas they traverse the firewall. - Queue Tree entries reference those marks and define limits, priorities, and parent-child relationships.
- HTB schedulerdistributes bandwidth hierarchically — children share the parent's capacity, priority classes get served first.
Example hierarchy:
Global (interface max-limit)
├── DOWNLOAD (100 Mbps)
│ ├── VOIP priority 1, guarantee 5M
│ ├── GAMING priority 3, guarantee 10M
│ ├── BUSINESS priority 4, guarantee 30M
│ └── RESIDENTIAL priority 8, guarantee 20M
│ └── PCQ (per-user fair share at 2 Mbps each)
└── UPLOAD (50 Mbps)
├── VOIP priority 1, guarantee 3M
└── GENERAL priority 8, PCQ 1 Mbps eachEach child has a limit-at (guaranteed minimum) and max-limit (hard cap). When the parent has spare capacity, lower-priority queues can burst up to their max-limit.
Step 1 — Mark Traffic with Mangle Rules
Before you can queue anything, you need to tell RouterOS which packets belong to which class. Mangle rules in the forward chain do this.
Mark all download traffic:
/ip firewall mangle
add chain=forward in-interface=ether1-WAN \
action=mark-packet new-packet-mark=ALL-DOWNLOAD passthrough=yesMark VoIP (SIP + RTP):
/ip firewall mangle
add chain=forward packet-mark=ALL-DOWNLOAD \
protocol=udp dst-port=5060-5061,10000-20000 \
action=mark-packet new-packet-mark=VOIP-DOWN passthrough=no
add chain=forward packet-mark=ALL-DOWNLOAD \
protocol=udp src-port=5060-5061,10000-20000 \
action=mark-packet new-packet-mark=VOIP-DOWN passthrough=noMark gaming traffic:
/ip firewall mangle
add chain=forward packet-mark=ALL-DOWNLOAD \
protocol=udp dst-port=3478-3480,27015-27030 \
action=mark-packet new-packet-mark=GAMING-DOWN passthrough=noMark a business subnet:
/ip firewall mangle
add chain=forward packet-mark=ALL-DOWNLOAD \
dst-address=10.10.0.0/16 \
action=mark-packet new-packet-mark=BIZ-DOWN passthrough=noImportant: Set passthrough=noon specific marks so packets don't get re-marked by later rules. The catch-all rule at the top uses passthrough=yes so specific rules below can override it.
Step 2 — Build the Queue Tree
Parent queue (total bandwidth):
/queue tree
add name=TOTAL-DOWNLOAD parent=global \
packet-mark=ALL-DOWNLOAD max-limit=100MPriority children:
/queue tree
add name=VOIP-DOWN parent=TOTAL-DOWNLOAD \
packet-mark=VOIP-DOWN priority=1 \
limit-at=5M max-limit=10M
add name=GAMING-DOWN parent=TOTAL-DOWNLOAD \
packet-mark=GAMING-DOWN priority=3 \
limit-at=10M max-limit=20M
add name=BIZ-DOWN parent=TOTAL-DOWNLOAD \
packet-mark=BIZ-DOWN priority=4 \
limit-at=30M max-limit=60MResidential with PCQ fair sharing:
# Create a PCQ queue type — each subscriber gets a fair share
/queue type
add name=PCQ-DOWNLOAD-2M kind=pcq \
pcq-rate=2M pcq-classifier=dst-address
# Residential child queue using PCQ
/queue tree
add name=RESIDENTIAL-DOWN parent=TOTAL-DOWNLOAD \
packet-mark=ALL-DOWNLOAD priority=8 \
limit-at=20M max-limit=80M \
queue=PCQ-DOWNLOAD-2MWith PCQ, each unique destination IP (each subscriber) gets up to 2 Mbps individually. The total residential pool is capped at 80 Mbps. No single user can hog the pipe.
Step 3 — Mirror the Structure for Upload
The upload side follows the same logic — mark outbound traffic and create a matching queue tree:
# Mark upload traffic
/ip firewall mangle
add chain=forward out-interface=ether1-WAN \
action=mark-packet new-packet-mark=ALL-UPLOAD passthrough=yes
add chain=forward packet-mark=ALL-UPLOAD \
protocol=udp src-port=5060-5061,10000-20000 \
action=mark-packet new-packet-mark=VOIP-UP passthrough=no
# Upload queue tree
/queue tree
add name=TOTAL-UPLOAD parent=global \
packet-mark=ALL-UPLOAD max-limit=50M
add name=VOIP-UP parent=TOTAL-UPLOAD \
packet-mark=VOIP-UP priority=1 \
limit-at=3M max-limit=5M
# PCQ for fair per-user upload sharing
/queue type
add name=PCQ-UPLOAD-1M kind=pcq \
pcq-rate=1M pcq-classifier=src-address
/queue tree
add name=GENERAL-UP parent=TOTAL-UPLOAD \
packet-mark=ALL-UPLOAD priority=8 \
limit-at=20M max-limit=47M \
queue=PCQ-UPLOAD-1MFighting Bufferbloat with CAKE & FQ_CoDel
Raw bandwidth limits don't solve latency. When queues fill up, packets sit in buffers for hundreds of milliseconds — this is bufferbloat. It ruins VoIP, gaming, and video calls even when bandwidth is available.
RouterOS v7 supports two advanced queue disciplines that fix this:
FQ_CoDel
Fair Queuing with Controlled Delay. Drops packets early to keep latency low. Best for environments where you want fine-grained control.
CAKE
Common Applications Kept Enhanced. Combines shaping, AQM, and fairness in one algorithm. Easiest to deploy with great results.
Using CAKE on the residential queue:
/queue type
add name=CAKE-DOWN kind=cake \
cake-bandwidth=100M cake-diffserv=besteffort
/queue tree
add name=RESIDENTIAL-DOWN parent=TOTAL-DOWNLOAD \
packet-mark=ALL-DOWNLOAD priority=8 \
max-limit=80M queue=CAKE-DOWNWith CAKE, your subscribers experience low latency even at 95% link utilisation — a massive improvement in perceived quality.
Monitoring Your Queues
After deployment, continuously monitor queue performance to catch congestion early:
# Real-time queue stats /queue tree print stats where parent=TOTAL-DOWNLOAD # Check for packet drops (sign of congestion) /queue tree print stats detail where dropped>0 # Quick overview of all queue utilisation /queue tree print stats interval=2
What to look for: Queues with high dropped counts or consistently maxed-out rates — these need higher limit-at values or an upstream link upgrade.
Scaling to Thousands of Subscribers
Manual queue management breaks down at scale. Here are four approaches that work:
RADIUS + Mikrotik-Rate-Limit
FreeRADIUS returns a Mikrotik-Rate-Limit attribute during PPPoE auth — RouterOS automatically creates a per-user queue. Zero manual config.
PCQ Instead of 1,000 Simple Queues
Replace individual Simple Queues with a single PCQ queue type under Queue Tree. CPU usage drops by 80%+ on mid-range boards.
Address Lists for Zones
Group subscribers by zone with /ip firewall address-list, then create per-zone queue branches that share a parent.
RouterOS API Automation
Use the RouterOS API to dynamically create, update, and remove queues as subscribers are provisioned or change plans.
Quick Reference
| What | Where | Key Param |
|---|---|---|
| Mark packets | /ip firewall mangle | new-packet-mark |
| Create hierarchy | /queue tree | parent, packet-mark |
| Guaranteed bandwidth | /queue tree | limit-at |
| Hard cap | /queue tree | max-limit |
| Priority (1 = highest) | /queue tree | priority |
| Fair per-user share | /queue type | kind=pcq, pcq-rate |
| Anti-bufferbloat | /queue type | kind=cake or fq-codel |
| RADIUS rate limit | FreeRADIUS reply | Mikrotik-Rate-Limit |
How ISPbills Automates Queue Management
Configuring Queue Trees manually across 10+ routers is error-prone and time-consuming. ISPbills integrates directly with MikroTik's RouterOS API to automate the entire workflow:
- Automatic provisioning — assign a subscriber to a package and ISPbills creates the correct PPP profile and queue rules on the router.
- Package-based rate limits— define bandwidth tiers once, and they're pushed to all routers via the API. Change a package and every subscriber updates instantly.
- Live traffic monitoring — see per-interface and per-subscriber bandwidth usage in real time from the ISPbills dashboard.
- RADIUS integration — ISPbills manages FreeRADIUS profiles with
Mikrotik-Rate-Limitattributes for dynamic per-user bandwidth during PPPoE authentication. - Bulk sync — synchronise queues, profiles, and IP pools across all your routers in one click.
Stop Managing Queues Manually
ISPbills automates MikroTik queue provisioning, RADIUS rate limits, and live traffic monitoring across your entire fleet — free for up to 99 subscribers.
Start Free Trial →Tags
Ready to Transform Your ISP Business?
Join hundreds of ISPs across Bangladesh and South Asia who trust ISPbills to manage their operations. Start your free trial today — no credit card required.