2026年11月12日
2026年11月12日
Apache Bandwidth Limit with mod_ratelimit: Throttle Download Speed
This article is a localized edition of the Japanese original. Read the Japanese original
To limit transfer speed in Apache, enable the standard module mod_ratelimit and write SetOutputFilter RATE_LIMIT and SetEnv rate-limit value for the target location. The unit of the value is KiB/second, and the limit applies "per connection (request)." This article explains the setup steps, an example of applying it to WordPress upload files, how to measure the effect, and what mod_ratelimit cannot do.
What mod_ratelimit can and cannot do
mod_ratelimit is an output filter that sets an upper limit on the speed of responses Apache sends to clients. It has been bundled as standard since Apache 2.4.
What it can do:
- Keep the download speed of large files (video, ZIP, backup files and so on) below a set rate per connection
- Send the first set amount quickly, then throttle the speed (
rate-initial-burst) - Apply limits only to specific directories or extensions
What it cannot do:
- Limit total bandwidth per IP address or per user. The limit is per connection, so a client that opens several connections at once gets that many times the bandwidth
- Limit the number of requests (such as how many per second)
- Manage monthly transfer volume, or stop serving when a limit is reached
As a countermeasure against traffic spikes and abusive crawling, mod_evasive, which blocks based on request counts, a WAF (such as mod_security) or fail2ban fits the purpose better. It is easier to choose if you think of mod_ratelimit as a tool for "making sure large transfers by legitimate users do not squeeze other users' page speed or the network line."
Step 1: Enable the module
On the Debian / Ubuntu family, enable it with a2enmod.
sudo a2enmod ratelimit
sudo apachectl configtest
sudo systemctl reload apache2
On the RHEL / AlmaLinux / Rocky Linux family, check whether the LoadModule line for ratelimit_module is enabled in the configuration files under /etc/httpd/conf.modules.d/. Which file it is written in differs by package version, so searching with grep makes it easier to find.
grep -rn ratelimit /etc/httpd/conf.modules.d/
httpd -M | grep ratelimit
If ratelimit_module appears in the output of httpd -M (apache2ctl -M on the Debian family), it is loaded.
Step 2: Decide where to limit and at what speed
This is a configuration, close to the example in the official documentation, that limits everything under /downloads. Write it in the virtual host's configuration file.
<Location "/downloads">
SetOutputFilter RATE_LIMIT
# Limit to 400 KiB/second per connection
SetEnv rate-limit 400
# Send the first 512 KiB without limiting
SetEnv rate-initial-burst 512
</Location>
rate-limit is in KiB/second. As a guide, 1024 is about 1 MiB/second (about 8 Mbps) and 400 is about 3.2 Mbps. rate-initial-burst is a setting available in Apache 2.4.24 and later, and it lets small files and images arrive almost without waiting while only large files are throttled.
When you decide the speed, it is realistic to work backward from "how many simultaneous downloads will share the server's line." For example, if you want to keep some headroom on the line and devote about 50 Mbps to delivering large files, assuming about 5 simultaneous downloads you would give each one around 10 Mbps (about 1250 KiB/second). It is only a starting point, so measure and adjust in the next step.
Example of applying it to WordPress files
Files placed in the WordPress Media Library are served directly by Apache without going through PHP. So if you add conditions by directory or extension under uploads, the limit applies as is.
<Directory "/var/www/example/wp-content/uploads">
<FilesMatch "\.(zip|mp4|mov|pdf)$">
SetOutputFilter RATE_LIMIT
SetEnv rate-limit 1024
SetEnv rate-initial-burst 1024
</FilesMatch>
</Directory>
If you include images (jpg, png, webp and so on) in the target, article pages display more slowly, which affects the reader's experience and page speed metrics. As a rule, limit only large file formats.
In an environment where you cannot edit the server configuration, you can also write it in .htaccess. When used in .htaccess, SetOutputFilter and SetEnv need AllowOverride FileInfo. <Location> cannot be used in .htaccess, so use <FilesMatch>.
# wp-content/uploads/.htaccess
<IfModule mod_ratelimit.c>
<FilesMatch "\.(zip|mp4)$">
SetOutputFilter RATE_LIMIT
SetEnv rate-limit 1024
</FilesMatch>
</IfModule>
If a download-management plugin sends files from PHP, the actual URL may be the plugin's own processing URL. Check which URL is actually serving the file with your browser's developer tools before you decide what to limit.
Step 3: Measure the effect
You can check whether the setting is working with curl's transfer speed output. speed_download is shown in bytes/second, so dividing by 1024 gives KiB/second.
curl -s -o /dev/null -w 'size=%{size_download} speed=%{speed_download} B/s time=%{time_total}s\n' \
https://example.com/wp-content/uploads/sample.zip
With rate-limit 1024, the approximate speed excluding the burst portion should be around 1,048,576 B/second. For comparison, running the same command on a file that is not subject to the limit makes the difference clear. It is better to measure from a network close to your actual users than from inside the same data center as the server.
Points that are easy to trip over in operation
Throttling the speed lengthens the time each download takes, and Apache keeps the connection open for that whole time. In setups without spare workers, such as the prefork MPM, slow downloads can occupy workers and increase the wait for normal page responses. After adding a limit, watch the number of concurrent connections and workers in a waiting state with mod_status or similar, and check that MaxRequestWorkers has headroom.
If you have a CDN in front, what mod_ratelimit limits is the speed at which the CDN fetches from the origin. The delivery speed to users is determined by the CDN's behavior, so you may not get the effect you expected. For delivery through a CDN, checking the CDN's own features can sometimes be quicker.
Behavior in combination with compression (mod_deflate) or HTTP/2 may change depending on the Apache version and the order of settings. Before putting it into production, run the curl measurement above on a staging environment and check the speed with both HTTP/1.1 and HTTP/2. Before changing settings, back up the original configuration files, and reload only after passing apachectl configtest.
The behavior of mod_ratelimit described here is based on the official Apache 2.4 documentation (as of October 2026). For changes in minor versions, check the documentation for the version you use.
Summary
- mod_ratelimit sets an upper limit on response speed with
SetOutputFilter RATE_LIMITandSetEnv rate-limit(KiB/second) - The limit is per connection. It cannot be used for total bandwidth per IP or for request-count limits
rate-initial-burst(2.4.24 and later) lets you send the first set amount quickly- On WordPress, apply it only to large file formats under uploads and leave images out
- Measure the effect with curl's
speed_download, and check the effects on worker counts and the CDN - Take a backup before changing, and try it on staging before applying to production
Questions about WordPress? The publisher of this site is based in Japan and replies in Japanese. Contact (Japanese)