Traffic shaping lets you prioritize certain types of network traffic over others — ensuring latency-sensitive traffic (SSH, VoIP) stays responsive even when bulk operations (backups, large transfers) are consuming significant bandwidth.
When Traffic Shaping Helps
- A scheduled backup job saturates outbound bandwidth, making SSH sessions laggy during that window
- Multiple services on one VPS compete for limited bandwidth, and some are more latency-sensitive than others
Using tc (Traffic Control) for Basic Shaping
sudo apt install iproute2 -y
iproute2 (which includes tc) is pre-installed on most modern distributions.
Step 1 — Identify Your Network Interface
ip a
Step 2 — Apply a Simple Bandwidth Limit
sudo tc qdisc add dev eth0 root tbf rate 50mbit burst 32kbit latency 400ms
Limits total outbound bandwidth on eth0 to 50 Mbit/s — useful if you want to reserve headroom rather than let one process consume 100% of available capacity.
Step 3 — Prioritize Specific Traffic (More Advanced)
sudo tc qdisc add dev eth0 root handle 1: prio bands 3
sudo tc filter add dev eth0 parent 1: protocol ip prio 1 u32 match ip dport 22 0xffff flowid 1:1
This example prioritizes SSH traffic (port 22) into the highest-priority band, ensuring it remains responsive even when other traffic is heavy.
Step 4 — Verify the Configuration
tc qdisc show dev eth0
Removing Traffic Shaping Rules
sudo tc qdisc del dev eth0 root
Making Rules Persistent Across Reboots
tc rules don't persist by default — add them to a startup script or a systemd service that runs at boot:
sudo nano /etc/systemd/system/tc-shaping.service
[Unit]
Description=Apply traffic shaping rules
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/apply-tc-rules.sh
RemainAfterExit=true
[Install]
WantedBy=multi-user.target
A Simpler Alternative: Rate-Limiting Specific Processes
For simpler needs (e.g. limiting a single backup script's bandwidth usage rather than system-wide shaping), tools like trickle or built-in rate limiting in specific applications (like rsync --bwlimit) are often simpler than full tc configuration:
rsync --bwlimit=5000 -avz /source/ user@remote:/dest/
When to Use Application-Level vs System-Level Shaping
| Scenario | Recommended Approach |
|---|---|
| One specific process needs bandwidth limiting | Application-level flag (e.g. rsync --bwlimit) |
| Need to prioritize traffic types across the whole system | System-level tc shaping |
Common Errors
Rules don't survive a reboot — expected; use a systemd service or startup script to reapply them automatically at boot.
Shaping seems to have no effect — verify you're applying rules to the correct interface (the one actually carrying the traffic you're trying to shape), and that the qdisc was applied without errors.
Best Practices
- Start with simple bandwidth limits before attempting complex multi-band prioritization
- Prefer application-level rate limiting (like
rsync --bwlimit) when only one process needs control - Always make shaping rules persistent via a startup script/service if needed long-term
Continue Reading
- How to Diagnose and Fix High Network Latency
- How to Monitor Network Traffic with vnStat and iftop
- How to Set Up Automated VPS Backups
Browse more articles in Advanced Networking & VPN.
