LiteSpeed Web Server ships with a per-client throttling engine that caps concurrent connections, request rates, and bandwidth per source IP. It is the cheapest Layer 7 mitigation you already own — no extra appliance, no scrubbing service, no extra license. This guide configures it on a cPanel server and covers the two mistakes that take a site offline behind the change: throttling a CDN's shared egress IPs, and setting dynamic request rates so low that a logged-in WordPress dashboard trips its own ban.
It is for hosts seeing connection floods, slow-loris attempts, or aggressive scrapers hammering wp-login.php and XML-RPC across shared tenants. If you have not switched Apache out for LiteSpeed yet, start with installing LiteSpeed on cPanel first — these settings live in the LiteSpeed WebAdmin Console, not WHM.
Open the WebAdmin Console
Per-client throttling is not exposed in the cPanel or WHM UI. You configure it in the LiteSpeed WebAdmin Console on port 7080.
# Set or reset the WebAdmin password if you never have
/usr/local/lsws/admin/misc/admpass.sh
Then browse to https://your-server:7080 and log in. If port 7080 is firewalled (it should be — don't expose it publicly), open it to your own IP only, or tunnel in:
ssh -L 7080:127.0.0.1:7080 root@your-server
# now hit https://127.0.0.1:7080 locally
Set per-client throttling
Navigate to Configuration > Server > Security > Per Client Throttling. These limits apply to every site on the box, keyed by client IP. Start conservative — the defaults below are LiteSpeed's own reference values and suit a typical shared-hosting node.
| Field | Value | What it does |
|---|---|---|
| Static Requests/second | 40 | Cap on static-file hits (images, CSS, JS) per IP |
| Dynamic Requests/second | 2 | Cap on PHP/CGI hits per IP — the one that bites legit users if too low |
| Connection Soft Limit | 15 | Above this, the IP enters the grace period |
| Connection Hard Limit | 20 | New connections from the IP are dropped immediately |
| Outbound Bandwidth (bytes/sec) | 0 | Per-IP egress cap; 0 disables |
| Inbound Bandwidth (bytes/sec) | 0 | Per-IP ingress cap; 0 disables |
| Block Bad Request | Yes | Bans IPs sending malformed requests |
| Grace Period (sec) | 15 | Window to observe soft-limit violators before banning |
| Banned Period (sec) | 60 | How long an offending IP stays blocked |
Click Save, then Graceful Restart (top-right). No connections drop:
# equivalent from the shell
/usr/local/lsws/bin/lswsctrl restart
The Cloudflare and CDN trap
If you front sites with Cloudflare, QUIC.cloud, or any proxy that restores the real visitor IP, the throttle keys on whatever IP LiteSpeed sees. Get the real-IP plumbing wrong and every visitor collapses to a handful of CDN edge IPs, which instantly blow past the connection hard limit and get the whole CDN banned. The site goes dark for everyone.
Two correct fixes, pick one:
- Make LiteSpeed see the true client IP. Confirm the
X-Forwarded-For/CF-Connecting-IPhandling is active so throttling keys on real visitors. This is the same plumbing covered for security tooling in restoring real visitor IPs behind Cloudflare — the principle is identical for LiteSpeed. - Exempt the CDN's egress ranges. If you deliberately throttle on the proxy IP, raise the limits to absurd numbers (e.g. soft 100000 / hard 150000) for those ranges, or whitelist them outright (next section).
Whitelist trusted IPs
Monitoring probes, your own office IP, payment-gateway callbacks, and uptime checkers should never be throttled or banned. LiteSpeed treats "trusted" IPs as exempt from all per-client limits.
Server-wide, edit the trusted list:
# one IP or CIDR per line
echo "203.0.113.10" >> /usr/local/lsws/conf/trusted-ip-list
/usr/local/lsws/bin/lswsctrl restart
Or in the WebAdmin Console under Server > Security > Access Control, append a T to an allowed IP — 203.0.113.10T marks it trusted. Per-site, drop this into the vhost .htaccess:
<IfModule LiteSpeed>
Trusted 203.0.113.10
</IfModule>
Add reCAPTCHA for application-layer floods
Connection and request limits stop volumetric noise but not a low-and-slow botnet that stays just under your thresholds. LiteSpeed's built-in reCAPTCHA gate challenges suspect clients before they reach PHP. Configure it under Configuration > Server > Security > reCAPTCHA: set your site and secret keys, a Connection Limit (concurrent connections that triggers the challenge server-wide) and a Static/Dynamic Request Limit per second. When the server crosses the connection limit, new clients get a reCAPTCHA instead of a 503 — humans pass, bots stall.
This is distinct from per-client throttling: throttling bans individual abusive IPs, reCAPTCHA gates the whole server when total load spikes. Run both.
Verify it works
Trip the limit on purpose from an external host (not a trusted IP):
# fire 60 rapid dynamic requests; expect 503s once the rate cap hits
for i in $(seq 1 60); do curl -s -o /dev/null -w "%{http_code}\n" https://example.com/?nocache=$i; done
You should see 200 responses degrade to 503 as the dynamic rate limit engages, then recover after the banned period. Cross-check the ban in the log:
grep -i "denied access\|banned\|soft limit" /usr/local/lsws/logs/error.log | tail -20
For attacks that outscale per-server tuning — sustained multi-Gbps floods, or coordinated botnets across thousands of IPs — throttling buys time but not victory. Layer it with network-edge filtering and country blocking via CSF when an attack is geographically concentrated.
Next steps
- Install LiteSpeed on cPanel if you are still on stock Apache
- Restore real visitor IPs behind Cloudflare before you throttle, or you will ban your CDN
- Enable LSCache for WordPress so fewer requests ever reach the throttle
Need more enterprise sessions than your current tier allows under load? Compare LiteSpeed license tiers or ask sales about worker counts for high-traffic nodes.