Fair Bandwidth Sharing with PCQ (Per Connection Queue)
While Simple Queues give each IP address a fixed bandwidth limit, PCQ (Per Connection Queue) takes a different approach: it automatically divides available bandwidth equally among active users or connections. This is ideal when you want fairness without manually creating a queue for every user.
What is PCQ?
PCQ is a queuing discipline that splits bandwidth dynamically. Instead of assigning a fixed limit per user, PCQ observes all active flows and tries to give each one an equal share. If you have 10 users active, each gets roughly 1/10 of the total bandwidth.
PCQ is particularly useful for:
- Shared internet connections serving many users.
- ISP-style fair access policies.
- Preventing one heavy user from saturating the link while others are idle.
PCQ Concepts
- pcq-rate: Optional maximum rate per sub-stream (each classified flow). Set to 0 for no per-stream limit.
- pcq-limit: Queue depth per sub-stream (how many packets to buffer before dropping).
- pcq-classifier: What field is used to classify flows into sub-streams. Options:
src-address,dst-address,src-port,dst-port. - pcq-total-limit: Maximum total packets in the queue across all sub-streams.
Step 1: Create PCQ Queue Types
First, define the PCQ queue types for download and upload:
/queue type add name=pcq-download kind=pcq pcq-classifier=dst-address pcq-rate=0 pcq-limit=50 pcq-total-limit=2000
/queue type add name=pcq-upload kind=pcq pcq-classifier=src-address pcq-rate=0 pcq-limit=50 pcq-total-limit=2000For download: classify by dst-address — each destination IP (your LAN users) gets a fair share.
For upload: classify by src-address — each source IP (your LAN users) gets a fair share.
Step 2: Create a Queue Tree
PCQ works best in a Queue Tree, which lets you set a total bandwidth limit and then apply PCQ within that total.
First, mark all traffic from the WAN interface (for download) and to the WAN (for upload):
/ip firewall mangle add chain=forward in-interface=pppoe-out1 action=mark-packet new-packet-mark=wan-download passthrough=yes
/ip firewall mangle add chain=forward out-interface=pppoe-out1 action=mark-packet new-packet-mark=wan-upload passthrough=yesThen create the Queue Tree:
/queue tree add name=total-download parent=global packet-mark=wan-download max-limit=100M queue=pcq-download
/queue tree add name=total-upload parent=global packet-mark=wan-upload max-limit=20M queue=pcq-uploadSet max-limit to your actual ISP connection speed (100M down / 20M up in this example).
How PCQ Distributes Bandwidth
With the above setup and 100 Mbps total download:
- 1 active user → gets 100 Mbps
- 2 active users → each gets ~50 Mbps
- 10 active users → each gets ~10 Mbps
- 20 active users → each gets ~5 Mbps
PCQ dynamically adjusts as users start and stop downloading.
Setting a Per-User Maximum with pcq-rate
If you want each user to have a maximum (even when others are idle):
/queue type set pcq-download pcq-rate=10M
/queue type set pcq-upload pcq-rate=5MNow no single user can exceed 10 Mbps download or 5 Mbps upload, regardless of what others are doing.
Viewing Queue Statistics
/queue tree print statsCombining Simple Queue with PCQ
You can combine both approaches:
- Use a Simple Queue to limit each user to a maximum (e.g., 20 Mbps).
- Use PCQ inside that limit to distribute fairly when multiple users are active.
This requires Queue Trees with PCQ as the queue type on child queues.
PCQ vs Simple Queue: When to Use Which
| Situation | Use |
|---|---|
| Fixed limit per user regardless of load | Simple Queue |
| Fair sharing of a total bandwidth pool | PCQ |
| ISP or shared connection with many users | PCQ |
| Per-department limits with fairness within | Queue Tree + PCQ |
Troubleshooting PCQ
- All users get low speeds: Check that
max-limiton the Queue Tree matches your actual ISP speed. - Classifier not working: Make sure you use
dst-addressfor download andsrc-addressfor upload. - Mangle marks not matching: Check that mangle rules are in
forwardchain and referencing the correct WAN interface.
Summary
- PCQ dynamically divides bandwidth fairly among active users.
- Create PCQ queue types with
/queue type add kind=pcq. - Use Queue Trees to apply PCQ to a total bandwidth limit.
- Use mangle marks to identify upload and download traffic.
- Set
pcq-rateto cap per-user speed. - PCQ is ideal for shared connections and ISP-style fairness.
