TC(8)

๐Ÿ’– NAME ๐Ÿ’–

okay so the manual name here is TC(8), and the thing we're talking about is tbf, aka the Token Bucket Filter โœจ

๐ŸŽ€ SYNOPSIS ๐ŸŽ€

tc qdisc ... tbf rate rate burst bytes/cell ( latency ms | limit bytes )
[ mpu bytes [ peakrate rate mtu bytes/cell ] ]

bestie, burst is also known as buffer and maxburst. and mtu is also known as minburst ๐Ÿซถ

๐Ÿฆ‹ DESCRIPTION ๐Ÿฆ‹

okay so the Token Bucket Filter is a classful queueing discipline you can use for traffic control with the tc(8) command. iconic, right? ๐Ÿ’…

TBF is a pure shaper and it never schedules traffic. it's non-work-conserving, which means it may throttle itself even when packets are available, just so the configured rate never gets exceeded. ngl that's very responsible of it ๐Ÿฅน It can shape up to 1mbit/s of normal traffic with ideal minimal burstiness, sending data out exactly at the configured rates.

much higher rates are possible, but you lose that minimal burstiness. in that case data is on average dequeued at the configured rate, but it can get sent way faster on millisecond timescales. because there are more queues living in network adaptors, this is often not a problem ๐Ÿ’€โœจ

๐ŸŒˆ ALGORITHM ๐ŸŒˆ

so the name literally tells you what it does: traffic gets filtered based on how many tokens it spends ๐Ÿช™ Tokens roughly correspond to bytes, with the extra rule that every packet eats some tokens no matter how tiny it is. that's because even a zero-sized packet occupies the link for some time. main character energy for sure ๐Ÿ‘‘

on creation, the TBF gets stocked with tokens, which correspond to the amount of traffic that can be burst in one go. tokens then arrive at a steady rate until the bucket is full. ๐Ÿ“

if there are no tokens available, packets get queued, up to a configured limit. the TBF then calculates the token deficit and throttles until the first packet in the queue can be sent ๐Ÿ™ˆ

if bursting out packets at maximum speed isn't acceptable, you can configure a peakrate to limit how fast the bucket empties. this peakrate is implemented as a second TBF with a very small bucket, so it doesn't burst. lowkey genius ๐Ÿงš

to achieve perfection, the second bucket may contain only a single packet, and that's what leads to the 1mbit/s limit we mentioned earlier.

this limit happens because the kernel can only throttle for at minimum 1 'jiffy', and a jiffy depends on HZ as 1/HZ. for perfect shaping, only a single packet can get sent per jiffy. for HZ=100, that means 100 packets of on average 1000 bytes each, which roughly corresponds to 1mbit/s ๐Ÿ˜ญ

๐Ÿ’œ PARAMETERS ๐Ÿ’œ

okay bestie, see tc(8) for how to specify the units of these values ๐Ÿ“

  • limit or latency โ€” limit is the number of bytes that can be queued while waiting for tokens to show up. you can also flip it around and set the latency parameter instead, which specifies the maximum amount of time a packet can sit in the TBF. the latter calculation takes into account the size of the bucket, the rate, and possibly the peakrate (if set). these two parameters are mutually exclusive, so pick one bestie ๐Ÿซ 
  • burst โ€” also known as buffer or maxburst. this is the size of the bucket, in bytes, and the maximum amount of bytes that tokens can be available for instantaneously. in general, larger shaping rates need a larger buffer. for 10mbit/s on Intel, you need at least a 10kbyte buffer if you want to reach your configured rate!
    • if your buffer is too small, packets may get dropped, because more tokens arrive per timer tick than fit in your bucket. the minimum buffer size can be calculated by dividing the rate by HZ.
    • token usage calculations are done using a table that by default has a resolution of 8 packets. you can change this resolution by specifying the cell size with the burst. for example, to get a 6000 byte buffer with a 16 byte cell size, set a burst of 6000/16. you'll probably never have to set this ๐Ÿ™ˆ It must be an integral power of 2.
  • mpu โ€” a zero-sized packet does not use zero bandwidth. for ethernet, no packet uses less than 64 bytes. the Minimum Packet Unit determines the minimal token usage (specified in bytes) for a packet. it defaults to zero ๐Ÿผ
  • rate โ€” the speed knob! see the remarks above about limits. see tc(8) for units ๐ŸŽ๏ธ

furthermore, if you want a peakrate, these parameters are available:

  • peakrate โ€” the maximum depletion rate of the bucket. the peakrate doesn't need to be set. it's only necessary if perfect millisecond timescale shaping is required โฑ๏ธ
  • mtu/minburst โ€” specifies the size of the peakrate bucket. for perfect accuracy, it should be set to the MTU of the interface. if you need a peakrate but some burstiness is acceptable, this size can be raised. a 3000 byte minburst allows around 3mbit/s of peakrate, given 1000 byte packets. like the regular burstsize, you can also specify a cell size โœจ

๐ŸŽ€ EXAMPLE & USAGE ๐ŸŽ€

so to attach a TBF with a sustained maximum rate of 0.5mbit, a peakrate of 1.0mbit, a 5kilobyte buffer, and a pre-bucket queue size limit calculated so the TBF causes at most 70ms of latency, with perfect peakrate behaviour, slay and issue:

# tc qdisc add dev eth0 handle 10: root tbf rate 0.5mbit \
  burst 5kb latency 70ms peakrate 1mbit       \
  minburst 1540

to attach an inner qdisc, for example sfq, issue:

# tc qdisc add dev eth0 parent 10:1 handle 100: sfq
without an inner qdisc, the TBF queue acts as bfifo. if the inner qdisc is changed, the limit/latency is not effective anymore ๐Ÿšซ

๐Ÿ”— SEE ALSO ๐Ÿ”—

tc(8) ๐Ÿซถ

๐Ÿ‘‘ AUTHOR ๐Ÿ‘‘

Alexey N. Kuznetsov, <kuznet@ms2.inr.ac.ru>. this manpage is maintained by bert hubert <ahu@ds9a.nl> ๐Ÿฅฐ


and that's the whole tea โ˜•๐Ÿ’– this one came from iproute2, dated 13 December 2001, so it's a certified vintage gem. love you bestie, go shape some traffic ๐Ÿฆ‹๐ŸŒธ๐Ÿ’…

๐Ÿ“ฆ where this page comes from