Production-oriented Linux bandwidth limiter built on tc + ifb.
BWLimiter gives you a practical control center for port-based shaping, service-safe automation, and schedule-based speed policies.
Persian guide: README.fa.md
Use BWLimiter when you need to:
- limit traffic by port
- limit traffic by client IP or CIDR (with optional service port matching)
- control upload and download separately
- manage rules from an interactive numeric menu
- auto-restore policy after reboot
- apply different speed profiles based on time/day
The script is designed for real server operations, including VPN stacks like x-ui/3x-ui/xray.
| Domain | What You Get |
|---|---|
| Traffic shaping | HTB classes with tc, ingress redirect to ifb for download control |
| Rule model | Add/edit/enable/disable/delete/list/apply rules without destructive reset |
| IP/CIDR policies | Mark-based shaping with nftables + tc fw, designed for higher rule counts |
| Protocol control | tcp, udp, or both |
| Multi-port support | One rule can target multiple ports |
| Inbound discovery | VPN-aware discovery + 3x-ui DB/config parsing fallback chain |
| Scheduling | Unlimited time windows per rule, day filters, overlap priority |
| Safety | Conflict guard + protected-port policy + safe apply with snapshot rollback |
| Monitoring | Live tc monitor, status view, debug report generator |
| Automation | systemd service + 1-minute scheduler timer |
Detection path is intentionally ordered:
- 3x-ui database (
x-ui.db) when available - xray config files (
config.json) when available - VPN-related listening processes (
xray,x-ui,sing-box,v2ray) - General listening sockets (
ss)
This helps keep detected ports relevant to VPN workloads first.
Required:
- Linux
- root privileges (
sudo) iproute2(tc,ip,ss)nftables(nft) for IP/CIDR limitingkmod(modprobe)systemd(for service/timer automation)
Recommended:
sqlite3jq
curl -fsSL https://github.com/B3hnamR/BWLimiter/main/bootstrap.sh | sudo bashWhat bootstrap does:
- installs missing dependencies
- installs/updates
/usr/local/bin/limit-tc-port - installs systemd unit files
- enables main service and scheduler timer
- launches interactive menu
git clone https://github.com/B3hnamR/BWLimiter.git
cd BWLimiter
chmod +x limit-tc-port.sh install.sh
sudo ./install.shStart:
sudo limit-tc-portMain menu:
[1]Rules Studio[2]Inbound Discovery[3]Service Ops[4]Live Monitor[5]Maintenance Toolkit[6]Quick Wizard[7]Apply Active[8]Time Schedules[0]Quit
Important submenus:
Service Ops: service install/start/stop + scheduler timer controlMaintenance Toolkit: interface selection, IFB config, debug report, safe apply, conflict checks, snapshot rollbackTime Schedules: create/edit/enable/disable/delete schedule windowsRules Studio > [9] IP/CIDR rules: manage IP/CIDR-based limits
Each schedule window has:
- target
rule_id days:all,weekday,weekend, ormon,tue,...start_hhmm/end_hhmm- scheduled
down_kbit,up_kbit,burst_kb priority(higher wins if windows overlap)
Behavior:
- if a schedule is active now, it overrides base rule speed
- if no schedule is active, base rule speed is used
- overnight windows are supported (
23:00to06:00) - you can define 3, 5, or many windows per rule
sudo limit-tc-port --apply
sudo limit-tc-port --safe-apply
sudo limit-tc-port --tick
sudo limit-tc-port --clear
sudo limit-tc-port --status
sudo limit-tc-port --list
sudo limit-tc-port --list-ip-rules
sudo limit-tc-port --list-schedules
sudo limit-tc-port --conflict-check
sudo limit-tc-port --list-snapshots
sudo limit-tc-port --rollback-latest
sudo limit-tc-port --rollback-snapshot <snapshot_id>
sudo limit-tc-port --install-service
sudo limit-tc-port --debug-report
sudo limit-tc-port --helpCommand intent:
--apply: force apply current effective policy--safe-apply: create snapshot, run guarded apply, auto-rollback if apply fails--tick: apply only when effective schedule state changes--conflict-check: validate overlapping rules and protected-port safety before apply--rollback-*: restore previous policy from snapshots--debug-report: generate diagnostics in/tmp
Main service:
sudo systemctl enable --now limit-tc-port.service
sudo systemctl status limit-tc-port.serviceScheduler timer:
sudo systemctl enable --now limit-tc-port-scheduler.timer
sudo systemctl status limit-tc-port-scheduler.timerExecution model:
- service applies policy lifecycle (
--apply,--clear) - timer runs
--tickevery minute
BWLimiter keeps classic per-port shaping, and adds an IP/CIDR policy engine with nftables marking:
nftmarks matching packets inprerouting(download) andoutput(upload)tcmaps those marks to dedicated HTB classes viafwfilters- class rates enforce per-IP/CIDR limits independently from base port rules
Why this scales better:
- avoids huge
u32filter growth for every IP+port tuple - uses compact nft expressions for CIDR and port lists
- keeps enforcement in kernel datapath with low control-plane overhead
Current scope of IP policies:
- IPv4/CIDR matching
- optional service port match (
anyor CSV list) - protocol-specific (
tcp,udp,both)
- Config:
/etc/limit-tc-port/config - Rules DB:
/etc/limit-tc-port/rules.db - Schedules DB:
/etc/limit-tc-port/schedules.db - IP Rules DB:
/etc/limit-tc-port/iprules.db - Runtime hash/state:
/run/limit-tc-port/ - Log:
/var/log/limit-tc-port.log
- Open
Rules Studioand create a rule for your inbound port (for example8080). - Set base limits (example: down
24576, up24576for about 3 MB/s). - Apply active rules.
- Open
Time Schedulesand add windows such as:- weekday 08:00-18:00, lower speed
- all days 18:00-23:00, medium speed
- all days 23:00-08:00, higher speed
- Enable scheduler timer from
Service Ops.
Generate report:
sudo limit-tc-port --debug-reportInspect report:
cat /tmp/limit-tc-port-debug-*.logWhat to verify first:
- selected interface is correct
- IFB device is present after apply
- service and scheduler timer are enabled
- rules and schedules are enabled
- detected source matches your environment (
3xui-db,xray-config, etc.)
- Filter path is currently IPv4-focused (
protocol ipwithu32). - Per-user shaping from x-ui account identity is not implemented (policy works at network IP/CIDR level).
The idea and general concept behind this project were inspired by the Telegram channel KillNationChannel. However, the actual implementation, structure, and source code in this repository were independently written and developed by me.
It should also be noted that KillNationChannel already provides a script with similar functionality, and users are welcome to use their version directly if they prefer.
Developed by: Behnam (@b3hnamrjd)