How to Limit the Number of Concurrent Connections in Apache

How to limit the number of concurrent connections in Apache

How to limit the number of concurrent connections in Apache

I once watched a client’s server grind to a halt during a product launch — not because of malicious traffic, but because a handful of users with slow connections were tying up worker threads while thousands of others tried to get through. Limiting concurrent connections, both globally and per-IP, is how I prevent this kind of resource exhaustion. Here’s my full approach.

Why Limiting Concurrent Connections Matters

Prerequisites

Step 1: Understand MaxRequestWorkers as Your First Limit

The most basic form of connection limiting in Apache is simply capping the total number of workers via your MPM configuration, which I cover in more depth in my performance tuning post:

<IfModule mpm_event_module>
    MaxRequestWorkers 150
</IfModule>

Once this limit is reached, new connections queue up rather than being served immediately, which protects the server from being overwhelmed — but it doesn’t prevent one IP from consuming a disproportionate share of those workers.

Step 2: Limit Simultaneous Connections Per-IP With mod_qos

For genuine per-client connection limiting, I install mod_qos, which gives fine-grained control:

sudo apt install libapache2-mod-qos
sudo a2enmod qos

Then I configure a per-IP connection cap:

<IfModule mod_qos.c>
    QS_SrvMaxConnPerIP 50
    QS_SrvMaxConnClose 2000
</IfModule>

QS_SrvMaxConnPerIP limits how many simultaneous connections a single IP address can hold open.

Step 3: Limit Requests Per Second With mod_ratelimit

While mod_qos controls concurrent connections, mod_ratelimit throttles bandwidth per connection, which indirectly helps manage load from data-heavy clients:

sudo a2enmod ratelimit
<Location "/downloads">
    SetOutputFilter RATE_LIMIT
    SetEnv rate-limit 400
</Location>

That example caps download speed to 400KB/s for anything under /downloads, freeing up bandwidth for other visitors.

Step 4: Use mod_evasive for DoS-Style Protection

mod_evasive is specifically designed to detect and block clients making an abnormally high number of requests in a short window — a classic sign of a DoS attempt or aggressive scraper:

sudo apt install libapache2-mod-evasive
sudo a2enmod evasive

Configuration:

<IfModule mod_evasive20.c>
    DOSHashTableSize    3097
    DOSPageCount        5
    DOSPageInterval     1
    DOSSiteCount        50
    DOSSiteInterval     1
    DOSBlockingPeriod   60
    DOSEmailNotify      admin@example.com
    DOSLogDir           "/var/log/mod_evasive"
</IfModule>

Here’s what these actually mean, since I always double check them against the server’s real traffic patterns:

Step 5: Limit Connections at the Listen/Socket Level

For an additional layer, I sometimes use ListenBackLog to control how many pending connections the OS-level socket queue can hold before rejecting new ones outright:

ListenBackLog 511

This is more of a safety valve than a primary defense, but it’s worth setting deliberately rather than leaving at the OS default.

Step 6: Test Your Configuration

I always run a controlled load test to confirm limits are behaving as expected before relying on them in production:

ab -n 500 -c 100 https://yourdomain.com/

I watch the server’s response codes and worker activity during the test (via mod_status) to confirm the limits kick in appropriately rather than crashing the server.

Step 7: Monitor Real-World Impact

After deploying connection limits, I keep an eye on the mod_evasive and mod_qos logs for a few days to make sure legitimate users — like people behind a shared corporate NAT, where many users share one public IP — aren’t getting incorrectly throttled.

sudo tail -f /var/log/mod_evasive/*

If I see a shared office IP getting flagged, I raise the per-IP limits or add that IP to a whitelist:

<IfModule mod_evasive20.c>
    DOSWhitelist 203.0.113.0/24
</IfModule>

Real-World Use Case

During a flash sale for an e-commerce client, we anticipated a traffic spike but were also worried about scrapers hitting the site aggressively to snipe inventory. I set QS_SrvMaxConnPerIP 20 and tuned mod_evasive thresholds based on load-test data beforehand. The sale went smoothly — a couple of scraper IPs got auto-blocked within the first ten minutes, while legitimate shoppers behind shared office or campus IPs weren’t affected because the per-IP cap was set generously enough.

Common Mistakes to Avoid

Troubleshooting Tips

If real users start reporting connection errors after implementing limits, check the mod_evasive and mod_qos logs to identify which rule is triggering, and consider whether the threshold needs to account for shared IPs (offices, VPNs, mobile carriers using CGNAT). If server load remains high despite connection limits, verify your MPM MaxRequestWorkers setting matches your actual available memory, since connection limiting alone won’t fix an underlying resource shortage.

Security and Performance Best Practices

Frequently Asked Questions

What’s the difference between MaxRequestWorkers and per-IP connection limits? MaxRequestWorkers caps the total connections the server will handle across everyone. Per-IP limits (via mod_qos or mod_evasive) prevent any single client from consuming a disproportionate share of that total.

Will limiting connections protect against a large-scale DDoS attack? Not on its own. Apache-level limiting helps with moderate abuse and basic DoS attempts, but large distributed attacks need upstream mitigation like a CDN or specialized DDoS protection service.

How do I choose the right per-IP connection limit? Base it on real traffic analysis — check your logs for legitimate concurrent connection patterns from shared IPs (offices, mobile carriers) and set the limit comfortably above that baseline.

Does mod_evasive replace a firewall? No, it’s a complementary, application-aware layer that reacts to request patterns Apache can see, whereas a firewall operates at the network level without that context.

Summary and Key Takeaways

Limiting concurrent connections in Apache protects your server from both malicious abuse and accidental resource exhaustion during traffic spikes. Start with sane MaxRequestWorkers tuning, add per-IP connection caps with mod_qos, and layer in mod_evasive for automated DoS-style detection — always load-testing your limits before relying on them during a real traffic event.

References

Exit mobile version