CAKE-autorate is a script that automatically adapts CAKE Smart Queue Management (SQM) bandwidth settings by measuring traffic load and RTT times. This is designed for variable bandwidth connections such as LTE, and is not intended for use on connections that have a stable, fixed bandwidth.
CAKE is an algorithm that manages the buffering of data being sent/received by a device such as an OpenWrt router so that no more data is queued than is necessary, minimizing the latency ("bufferbloat") and improving the responsiveness of a network.
Present version is 1.1.0 - please see the changelog for details.
The CAKE algorithm always uses fixed upload and download bandwidth settings to manage its queues. Variable bandwidth connections present a challenge because the actual bandwidth at any given moment is not known.
As CAKE works with a fixed set bandwidth this effectively forces the user to choose a compromise bandwidth setting, but typically this means lost bandwidth in exchange for latency control and/or bufferbloat during the worst conditions. This compromise is hardly ideal: whilst the actual usable line rate is above the set compromise bandwidth, the connection is unnecessarily throttled back to the compromise setting resulting in lost bandwidth (yellow); and whilst the actual usable line rate is below the compromise value, the connection is not throttled enough (green) resulting in bufferbloat.
The cake-autorate.sh script periodically measures the load and Round-Trip-Time (RTT) to adjust the upload and download values for the CAKE algorithm.
cake-autorate.sh
monitors load (rx and tx) and ping respones from one or more reflectors, and adjusts the download and upload bandwidth for CAKE. Rate control is intentionally kept as simple as possible and follows the following approach:
- with low load, decay rate back to set baseline (and subject to refractory period)
- with high load, increase rate subject to set maximum
- on bufferbloat, decrease rate subject to set min (and subject to refractory period)
Setting the minimum bandwidth: Set the minimum value to the worst possible observed bufferbloat free bandwidth. Ideally this CAKE bandwidth should never result in bufferbloat even under the worst conditions. This is a hard minimum - the script will never reduce the bandwidth below this level.
Setting the baseline bandwidth: This is the steady state bandwidth to be maintained under no or low load. This is likely the compromise bandwidth described above, i.e. the value you would set CAKE to that is bufferbloat free most, but not necessarily all, of the time.
Setting the maximum bandwidth: The maximum bandwidth should be set to the lower of the maximum bandwidth that the ISP can provide or the maximum bandwidth required by the user. The script will adjust the bandwidth up when there is traffic, as long no RTT spike is detected. Setting this value to a maximum required level will have the advantage that the script will stay at that level during optimum conditions rather than always having to test whether the bandwidth can be increased (which necessarily results in allowing some excess latency through).
To elaborate on setting the minimum and maximum, a variable bandwidth connection may be most ideally divided up into a known fixed, stable component, on top of which is provided an unknown variable component:
The minimum bandwidth is then set to (or slightly below) the fixed component, and the maximum bandwidth may be set to (or slightly above) the maximum observed bandwidth. Or, if a lower maximum bandwidth is required by the user, the maximum bandwidth is set to that lower bandwidth as explained above.
The baseline bandwidth is likely optimally either the minimum bandwidth or somewhere close thereto (e.g. the compromise bandwidth).
There is a detailed and fun discussion with plenty of sketches relating to the development of the script and alternatives on the OpenWrt Forum - CAKE /w Adaptive Bandwidth.
Only requires:
- bash for its builtins, arithmetic and array handling
A pinger binary chosen from:
- fping round robin pinging to multiple reflectors with tightly controlled timings (default selection)
- iputils-ping advanced pinging than the default busybox ping with sub 1s ping frequency
The pinger binary that cake-autorate uses is set using the $pinger_binary variable in the config file.
-
Install SQM (
luci-app-sqm
) and enable CAKE on the interface(s) as described in the OpenWrt SQM documentation -
Alternatively, set up your own script to initiate CAKE. For ubnusual setups such as those with WireGuard with PBR, then you may want to consider cake-dual-ifb.
-
Install with the installer script from this repo, copying and pasting each of the commands below:
wget -O /tmp/cake-autorate-setup.sh https://raw.githubusercontent.com/lynxthecat/CAKE-autorate/main/cake-autorate-setup.sh sh /tmp/cake-autorate-setup.sh
-
The installer script will detect a previous configuration file, and ask whether to preserve it. If you do not keep it...
-
Edit the
cake-autorate-config.sh
script (in the/root/cake-autorate
directory) using vi or nano to set the configuration parameters below (see comments insidecake-autorate-config.sh
for details).-
Change
ul_if
anddl_if
to match the names of the upload and download interfaces to which CAKE is applied. These can be obtained, for example, by consulting the configured SQM settings in LuCi or by examining the output oftc qdisc ls
.Variable Setting ul_if
Interface that uploads (often wan
)dl_if
Interface that uploads data (check tc qdisc ls
) -
Set bandwidth variables as described in
cake-autorate-config.sh
.Type Download Upload Min. min_dl_shaper_rate_kbps
min_ul_shaper_rate_kbps
Base base_dl_shaper_rate_kbps
base_ul_shaper_rate_kbps
Max. max_dl_shaper_rate_kbps
max_ul_shaper_rate_kbps
-
The following variables control logging:
Variable Setting output_processing_stats
If non-zero, log the results of every iteration through the process output_cake_changes
If non-zero, log when changes are made to CAKE settings via tc
- this shows when CAKE-autorate is adjusting the shaperdebug
If non-zero, debug lines will be output log_to_file
If non-zero, log lines will be sent to /tmp/cake-autorate.log regardless of whether printing to console and after every write the log file will be rotated f either log_file_max_time_mins
have elapsed orlog_file_max_size_KB
has been exceededlog_file_max_time_mins
Number of minutes to elapse between log file rotaton log_file_max_size_KB
Number of KB (i.e. bytes/1024) worth of log lines between log file rotations
-
A compressed log file can be extracted from a running cake-autorate instance using:
kill -USR1 $(cat /var/run/cake-autorate/maintain_log_file_pid)
This will place a compressed log file in /var/log with the date and time in its filename
And a very helpful summary plot like this:
can be created therefrom using the excellent Octave/Matlab utility put together by @moeller0 of OpenWrt, using something like:
octave -qf --eval 'fn_parse_autorate_log("./log.gz", "./outpug.png")'
(see the introductory notes in 'fn_parse_autorate_log.m' for more details).
- OpenWrt forum member @gba has kindly shared his Starlink config. This ought to provide a helpful starting point for adjusting the present configuration file format for Startlink users.
- See discussion on OpenWrt thread from around this post.
To run the cake-autorate.sh
script:
-
run:
cd /root/cake-autorate # to the cake-autorate directory ./cake-autorate.sh
-
Monitor the script output to see how it adjusts the download and upload rates as you use the connection.
-
Press ^C to halt the process.
You can install this as a service that starts up the autorate process whenever the router reboots. To do this:
-
Run these commands to enable and start the service file:
# the cake-autorate-setup.sh script already installed the service file service cake-autorate enable service cake-autorate start
When running as a service, the cake-autorate.sh
script outputs to /tmp/cake-autorate.log
.
WARNING: Take care to ensure sufficient free memory exists in router to handle selected logging parameters.
The Backup and Restore page on the wiki describes how files can be saved across upgrades.
Add these files on the Configuration tab, so they will be saved in backups and preserved across snapshot upgrades.
/root/cake-autorate
/etc/init.d/cake-autorate
If you use this script I have just one ask. Please post your experience on this OpenWrt Forum thread. Your feedback will help improve the script for the benefit of others.