Running Fedora 20, I had to run
as well as add 'default 0' to the following line:
/sbin/tc qdisc add dev eth0 root handle 1:0 htb
Without 'default 0', I got
RTNETLINK answers: Invalid argument
I have made a few modifications to the script posted earlier by realpariah, including a small systemd service that runs automatically on boot to re-configure the traffic shaping rules and the addition of a round-robin SFQ (Stochastic Fair Queuing) scheduler for the clients, which ensures that bandwidth is distributed equally if there is not enough bandwidth to go around. From my small tests so far, it seems to work well enough.
It doesn't support per-user limits, but does enable you to specify an absolute limit for Plex's bandwidth and then a target limit.
- Under high traffic demands, it will attempt to use no more than the target rate (as of yet untested; I have a hunch it may always use the absolute limit. May require an additional traffic shaping class definitions matching all non-plex ports to get this part working)
- If too many users are connected and there isn't enough bandwidth to share, the system allocates bandwidth in a round-robin fashion ensuring that users who have specified a smaller bitrate in their Plex preferences will buffer more quickly than those hogging the bandwidth by using direct play or whatever.
- If too few users are connected, then that user is allowed to use up to the maximum limit (even if this is above the target limit).
Run the following to set it up:
cat << EOF > /usr/local/bin/plex-traffic-shape
# Setup Traffic Control to limit outgoing bandwidth
# Sourced from:
# * http://www.cyberciti.biz/faq/linux-traffic-shaping-using-tc-to-control-http-traffic
# * https://forums.plex.tv/index.php/topic/39823-howto-limit-plex-media-server-bandwidth-on-linux/?p=466013
# * http://serverfault.com/questions/174010/limit-network-bandwith-for-an-ip
# * http://luxik.cdi.cz/~devik/qos/htb/manual/userg.htm
# Ensure that the sch_htb module is available.
# For very high rates, you may need to adjust the quantum values. See: http://mailman.ds9a.nl/pipermail/lartc/2003q1/007508.html
echo "\$0 ifdev rate maxrate ipblock"
echo -e " ifdev is usually eth0"
echo -e " rate and maxrate are a rate accepted by tc (e.g. 500kbit, 1mbit)"
echo -e " ipblock is a IP block per iptables syntax (e.g. 192.168.1.0/24"
if [ -z \$IFDEV ] || [ -z \$RATE ] || [ -z \$MAXRATE ] || [ -z \$R2Q ] || [ -z \$IPBLOCK ];then
### Sleep for a second
### Delete all TC rules for \$IFDEV
/sbin/tc qdisc del dev \$IFDEV root 2> /dev/null || /bin/true
### Delete the iptables mangle rule if it exists
/sbin/iptables -D OUTPUT -t mangle -p tcp --sport 32400 ! --dst "\$IPBLOCK" -j MARK --set-mark 10 2> /dev/null || /bin/true
### Activate queueing discipline
/sbin/tc qdisc add dev \$IFDEV root handle 1: htb default 20 r2q "\$R2Q"
### Define class with limited allowed bandwidth
/sbin/tc class add dev \$IFDEV parent 1: classid 1:1 htb rate "\$MAXRATE" ceil "\$MAXRATE"
/sbin/tc class add dev \$IFDEV parent 1:1 classid 1:10 htb rate "\$RATE" ceil "\$MAXRATE"
### Send packets in round-robin if we have too many clients and too little BW
/sbin/tc qdisc add dev \$IFDEV parent 1:10 handle 100: sfq perturb 10
### Create iptables mangle rule for outgoing port 32400 (Plex Media Server)
/sbin/iptables -A OUTPUT -t mangle -p tcp --sport 32400 ! --dst "\$IPBLOCK" -j MARK --set-mark 10
### Assign the rule to the proper qdisc
/sbin/tc filter add dev \$IFDEV parent 1: prio 3 protocol all handle 10 fw flowid 1:10
## Source variables
# . /etc/sysconfig/plex-traffic-shape
## show TC rules
# /sbin/tc -s -d class show dev \$IFDEV
## Show iptables mangle rules
# /sbin/iptables -t mangle -n -v -L
## Show actual bandwidth being used on 32400
# watch -n 1 /sbin/tc -s -d class show dev \$IFDEV
chmod +x /usr/local/bin/plex-traffic-shape
cat << EOF > /etc/sysconfig/plex-traffic-shape
# Interface to enable traffic shaping on.
# Define your "fair-share" rate and maximum uplink for Plex.
# Valid suffixes:
# kbit - kilobits/s;
# mbit - megabits/s;
# kbps - kilobytes/s;
# mbps - megabytes/s;
# The rates above converted to bytes/s divided by this number should fall
# anywhere between 1500 and 60,000. It's used to evenly distribute surplus
# bandwith: http://www.docum.org/faq/cache/31.html
# Your local IP block to exclude from traffic shaping. To disable traffic
# shaping exclusion (i.e., to enable it on your LAN as well) enter '127.0.0.1'
# as-is with no subnet modifier.
cat << EOF > /etc/systemd/system/plex-traffic-shape.service
Description=Starts traffic shaping for Plex Media Server
ExecStart=-/usr/local/bin/plex-traffic-shape $IFDEV $RATE $MAXRATE $R2Q $IPBLOCK
systemctl enable plex-traffic-shape
Now edit /etc/sysconfig/plex-traffic-shape according to your needs When you're all set:
systemctl start plex-traffic-shape