SQM Cake and Being a Twitch Streamer (Upload Direction)

Cake and luci-app-sqm are great for killing bufferbloat and gaming, but...

If I'm trying to stream to twitch.tv my stream would drop frames often for the audience. It would get really bad when the whole household uses internet at the same time.

For reference I have 5Mbps upload and try to stream at a video bitrate of 3000 kbits/s.

Is there anyway I can guarantee upload bandwidth for my twitch stream with SQM on at the same time?

1 Like

Yes, well nearly. I would use cake in 'diffserv4' mode and DSCP mark the twitch stream as 'CS3'. This would put the twitch stream egress packets in the Video tin which is guaranteed a minimum bandwidth of HALF your configured egress rate (2500 kbit in your case). The cake tin bandwidth minimums are not configurable.

You could mark your game traffic as CS4 so that it's more important than the twitch stream traffic itself, and hopefully everyone else will end up as 'Best effort' or 'Bulk' mopping up whatever bandwidth remains.

None of this addresses ingress traffic. There are two approaches to this, one using 'veth' interfaces (that I don't understand) and another using the normal 'ethn' and 'ifbethn' construct in combination with 'tc act_ctinfo' and 'iptables connmark --dscpsave' (which I do understand)


Expanding on @ldir's idea, I would make a copy of simple.qos:

cp /usr/lib/sqm/simple.qos /usr/lib/sqm/simple4twitch.qos
cp /usr/lib/sqm/simple.qos.help /usr/lib/sqm/simple4twitch.qos.help

That way you have your own qos-script which will still show up in the SQM GUI.

Then I would make the following changes:
PRIO_RATE=expr $CEIL / 3 # Ceiling for prioirty to PRIO_RATE=3500 # Ceiling for prioirty
To make room in the highest priority bin for your twitch streams.
Next step is to elevate all packets from the twitch stream to the high priority class. Since I have no clue about how to unambiguously identify twitch-stream packets, I would probably try to mark these by IP address. So the first step would be to make sure the twitch machine gets a predictable IP address, by giving it a static lease in the Network -> DHCP and DNS -> Static Leases sub-tab.
Next step conceptually is to add filters that will move all packets from the static IP-address (in the example to the high priority bin by adding something like tho following to the end of the egress section of simple4twitch.qos:

   $TC filter add dev $IFACE parent 1:0 protocol ip prio 10 \
        u32 match ip dst 0xff flowid 1:11

    $TC filter add dev $IFACE parent 1:0 protocol ipv6 prio 11 \
        u32 match ip dst 0xff flowid 1:11

Mind you, I have not tested that, I just composed it in the discourse...
An alternative, if you stream alternating from different computers, would be to still change the bandwidth of the high priority bin, but instead of using a static lease, make sure all your twitch packets are DSCP marked as EF. Then use New-NetQosPolicy to make the twitch application (lets assume twitch.exe) emit its packets marked as EF:

New-NetQosPolicy -Name "twitch" -AppPathNameMatchCondition "twitch.exe" -PolicyStore ActiveStore -NetworkProfile All -DSCPAction 46

Use Get-NetQosPolicy -Store ActiveStore to list existing policies and Remove-NetQosPolicy -Name "twitch" to remove policy if you do not need them anymore.

IMHO the second option probably is easiest, as all you need to do is to fudge the bandwidth assignment to the high priority class.

That said, there is a reason why traditionally the higher priority classes get less bandwidth than the lower ones, because otherwise everybody will just use the high priority bin and you are back to square one. In your case that should e easy to avoid.

1 Like

Thank you @ldir for the original idea.

And a big big thank you @moeller0 for expanding on the idea. I'm a noob, didn't know we can make a copy of a qos-script and have it show on the GUI. Seeing the exact commands really saves me a lot of time trying to google fu everything. I would have been really lost otherwise.. Thanks for all that effort!

I just need to google fu how to do DSCP marks.

I believe twitch uses outbound TCP port 1935.

Mmmh, Port Numbers above 1023 are essentially ephemeral, that is not reserved, so any application can use them, so I would at least combine them with the source IP address of your twitch host, to avoid false positives...

1 Like

Final question, if you actually go and implement that to your satisfaction, could you please add a post/create a new post with a short problem description and your recipe how to solve that? I believe your situation is not completely unique and others might be happy to learn from your example?

1 Like

Hi yes, I can do that when things work out. Would this "Installing and Using OpenWrt" category be a good place to post? I'll also try to post the recipe to my website at www.stoplagging.com for others who stream on twitch as well.

The first method I understand how to do.. For the second method.

I understand New-NetQosPolicy is done on powershell on the client side but, regarding the part about "instead of using a static lease, make sure all your twitch packets are DSCP marked as EF" how do I do that?

1 Like

As far as i can tell, but @tmomas probably has a better feel for the best place. But let's first solve the issue before looking at such detail :wink:

Well, this really depends on what application and operating system you use for generating your twitch streams. Assuming it is windows 10 and an application like OBS (or similar?) then my example from above should be pretty straight forward to implement, but for xbox or PS[3|4] I have no real idea....

1 Like

I see I'm on OBS and windows 10.

ew-NetQosPolicy -Name "twitch" -AppPathNameMatchCondition "twitch.exe" -PolicyStore ActiveStore -NetworkProfile All -DSCPAction 46

I guess is DSCP done is client side in this example.

I always thought DSCP marking had to be done on the router haha.

Edit: From your response below you are right. In my case it would be "obs64.exe"

1 Like

Yes, as that, at least for egress/upload traffic is the best place to do mark the packets.
But keep in mind that the name "twitch" and the application name "twitch.exe" are just standins. The name only should be uniqu, but -AppPathNameMatchCondition "twitch.exe" really needs to refer to the real application that sends the packets (so OBS, I assume?).

1 Like

I've not looked too closely at 'simple.qos' but I'm assuming it doesn't use cake (because you want programatic access to bandwidth allocations) and are thus throwing away NAT and per host fairness, DRR+ shaper and soft bandwidth allocation.

I know the 2500 egress bandwidth allocation isn't an exact match but I wonder how critical that is and in combination with other fairness factors of cake whether it might give better/fairer performance for everyone. An interesting experiment.


All good thoughts. My take is, that with 3000 of 5000 the OP really needs an unfair solution. As far as I can tell deNATing is only important for the per-internal/external fairness modes, that will not work for the OP. BUT, I certainly would try with layer_cake and manual setting of the twitch traffic to EF first, as you I have a hunch that might already be good enough ;).
Now if the described priority for the twitch stream is a hard requirement, modding simple.qos might be a better approach.
Unless someone really ambitious sets out to make cake's min/max bandwidth per tin configurable :wink:

1 Like

Hello @moeller0 I made a tutorial here https://www.stoplagging.com/modifying-sqm-for-twitch-streamers/ for the twitch streamers. If you think it's ready I can make a forum post about this solution.

You are right about me needing this to be an unfair solution. It just needs to be unfair in the egress direction. Which probably won't bother most users at my household as they mainly use download.

I believe it is working out so far as the viewers haven't experienced any frame drops last night. But that may be because it's a Sunday night and not a lot of people were on the Internet. I 'll know for sure if tested on the weekdays during peak hours 2-5 pm pst at my home.

Really thankful for the solution.

Edit: To remove qos policy the command is actually Remove-NetQosPolicy -Name "twitch" -Store ActiveStore it was missing the -Store ActiveStore Part

Great that this works for you! (I assume you tested the wazoo out of it and it is robust and reliable ;))

Now, to get back to @ldir's ideas, it might be time to try level2, that is switching the ingress side to cake with per-internal-IP fairness. Just replace the ingress() section from twitch.qwos with the ingress() section from layer_cake.qos... And add the following to your /etc/config/sqm:

        option verbosity '5'
        option qdisc_advanced '1'
        option squash_dscp '0'
        option squash_ingress '0'
        option ingress_ecn 'ECN'
        option qdisc_really_really_advanced '1'
        option linklayer_advanced '1'
        option iqdisc_opts 'nat dual-dsthost ingress'

This will give you tighter shaping for ingress traffic and equal sharing of the bandwidth between all concurrently active internal IP-addresses, to make up for the unfairness you introduced in the egress/upstream direction :wink:

1 Like

As a technical point on your blog post, CAKE is not being used for egress (or ingress for that matter, something @moeller0 mentions is his follow up) CAKE doesn't allow you to adjust its bandwidth allocations per tin.

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.