Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

throttle - constrict bandwidth

Holds the path to a ceiling by slowing the reader down.

$ tocat file:big.iso throttle,rate=256k tcp:host:9000
$ tocat -f tcp-listen:9000,fork -t tcp:backend:8080 -p 'throttle,rate=1MiB,burst=4MiB'
OptionDescription
rate=SIZEThe ceiling, in bytes per second. Required, and must be greater than zero. Aliases: bandwidth, bps
burst=SIZEHow much unused allowance may accumulate, so an idle path can resume at full speed briefly. Defaults to one second of rate

Nothing is buffered. Every chunk passes through untouched and the stage asks the relay to wait before reading again, so there is no queue to grow when the source outruns the limit. It also throttles the right end: a read that does not happen leaves the receive buffer full, which closes the TCP window and slows the sender at source. Buffering here would let the sender keep sending at full speed into memory that has to go somewhere, which is a queue, not a limit.

The allowance is a token bucket. It accrues at rate bytes per second up to burst, and each chunk spends its own length. Spending is not capped, so a chunk larger than the bucket is paid for with a proportionally longer wait rather than being split, which is what keeps the stage safe on a datagram path: a message goes out as the message it arrived as, just later. The bucket starts full, so a path that has just opened may move burst bytes before the ceiling first bites.

The wait lands between reads, so the stall comes in units of chunks. At the 256 KiB default buffer, rate=64k is four seconds of silence followed by 256 KiB at once. The average is right either way, but for smooth pacing give the relay a buffer at or below the per-second rate (-b 64k here).

The wait is also applied after the chunk in hand has been written, so nothing is held hostage by it. Where several stages on one path ask to wait, the longest request wins rather than the sum: two stages each asking for a second are satisfied by one second.

As with limit, an instance paces its own path, so rate=1MiB paces the source and direction=both is a megabyte per second each way rather than between them. To stop a stream rather than slow it, use limit; rate=0 is rejected.