# Tune LiteSpeed for High-Traffic WordPress: Cache Hits First, Then PHP Workers

Source: https://srvscripts.com/guides/tune-litespeed-high-traffic-wordpress/
Updated: 2026-10-18
Publisher: srvScripts (https://srvscripts.com/)

**Short answer:** to tune LiteSpeed for a high-traffic WordPress site, first make sure most pages come from LSCache, because a cached page never starts PHP. On our 2-vCPU test server one WordPress page served about 33 requests per second from PHP and 17,000 to 22,000 per second from LSCache. Then size the PHP workers (on cPanel, **PHP suEXEC Max Conn**, default 10) to the CPU cores and memory you actually have, instead of raising them as far as they go. Add an object cache (Redis or Memcached) for pages that cannot be cached. Run WP-Cron from a real cron job. Only then touch the server’s connection limits.

In short: To tune LiteSpeed for a high-traffic WordPress site, first make sure most pages come from LSCache, because a cached page never starts PHP. On our 2-vCPU test server one WordPress page served…

Most “LiteSpeed is slow under load” problems are cache misses, not a slow web server: a cookie that every page sets, a query string on every link, a plugin that purges everything on each save, or logged-in traffic. Raising worker or connection limits on top of a cache that misses mainly buys you a higher load average. This guide goes in the order that matters, shows how to check each step, and gives the numbers from our own test.

## What a cache hit is worth: our measurement

We measured one WordPress post on a small test server (2 vCPU, 8 GB RAM, OpenLiteSpeed 1.9.3, LSPHP 8.3, MariaDB 10.11, WordPress 7.1.3 with the default theme and 51 posts), with ApacheBench (`ab`) on the same machine, three runs each:

- **No page cache, 20 concurrent clients:** 32 to 33 requests per second, median 370 to 660 ms, 95th percentile about 1.0 to 1.1 seconds. The two CPUs were the limit.

- **The same, with 4 instead of 10 PHP workers:** 32 requests per second, the same as with 10. More workers did not add throughput, because two CPUs can only run two PHP processes at a time.

- **LSCache hit, 20 concurrent clients:** 17,100 to 20,500 requests per second, median 1 ms, 95th percentile 2 ms.

- **LSCache hit, 100 concurrent clients:** 20,500 to 22,400 requests per second, 95th percentile 7 to 9 ms.

Your numbers will differ with hardware, theme, plugins and network, and a benchmark on the same machine is not the same as visitors over the internet. The ratio is the point: a page that comes from the cache costs hundreds of times less than one that runs WordPress.

## Step 1: make sure pages are cache hits

Check what LiteSpeed answers for a page a visitor would see. Run it twice; the first request may fill the cache:

```
curl -sI https://example.com/some-post/ | grep -i x-litespeed-cache
x-litespeed-cache: hit
```

`hit` means the page came from the cache, `miss` means PHP built it, and no header at all usually means the page is not cacheable (LSCache is off for the site, the page is excluded, or the request is from a logged-in user). Test a few kinds of page: the home page, a post, a category, a product. Installing and configuring the plugin itself is covered in [LiteSpeed Cache for WordPress on cPanel](/guides/litespeed-cache-wordpress-cpanel-setup/).

Common reasons for misses, from the LSCache for WordPress documentation and from practice:

- **A cookie on every page.** The documentation warns that a “Do Not Cache Cookies” entry that every page sets excludes the whole site. Look for a plugin that sets a cookie for every visitor.

- **Query strings.** Each different query string is a separate cache entry. Marketing parameters on every link (for example `utm_source`) create new misses; LSCache’s **Drop Query String** setting removes named parameters before caching.

- **Purges.** Publishing, updating, comments without moderation and plugin or theme upgrades purge cached pages. A plugin that saves something every few minutes can keep the cache nearly empty.

- **Varies.** **Cache Mobile**, vary cookies and vary groups each keep separate copies, so each one starts as a miss.

- **Logged-in users.** They get a private cache (**Cache Logged-in Users** is on by default), which helps a single user browsing but not a crowd of different members.

If many visitors arrive just after a purge, they all reach PHP at once. LSCache’s **Serve Stale** setting serves the old copy while a new one is built. The **crawler** refreshes expired pages ahead of visitors, but it adds load of its own: by default it runs 3 threads, stops when the server load passes its **Server Load Limit** (default 1), and it only works if the host has allowed it at server or virtual-host level. On shared hosting, leave it off unless the host says otherwise.

## Step 2: size the PHP workers

Every request that is not a cache hit needs an LSPHP process. On cPanel servers with LiteSpeed Enterprise, the limit per account is **PHP suEXEC Max Conn** under **Configuration › Server › General › Using Apache Configuration File** in the LiteSpeed WebAdmin console. LiteSpeed’s cPanel tuning page gives the default as 10 and suggests raising it to a value such as 40 or 100 if accounts need more PHP processes. In LiteSpeed’s process-group mode an account can briefly go about a third above that number. On OpenLiteSpeed and in a plain LiteSpeed setup, the same limit is `PHP_LSAPI_CHILDREN` (alias `LSAPI_CHILDREN`) in the external application, which should match its **Max Connections**.

How to choose the number:

- **Memory.** Each LSPHP process for a typical WordPress site uses tens of megabytes; ours used about 48 MB resident. Multiply the per-process size by the limit, add MariaDB’s buffer pool and the operating system, and stay below the RAM you have. Swapping makes everything slower than queueing does.

- **CPU.** PHP work is mostly CPU. In our test, 4 and 10 workers on 2 CPUs gave the same throughput. Extra workers above the core count only help when requests spend time waiting (on a slow external API or a slow database), and then the real fix is the wait.

- **The log tells you when the limit is too low.** LiteSpeed’s documentation says that “Reached max children process limit” in `stderr.log` means the limit was hit. Until you see that, raising it changes nothing. If LSPHP processes pile up or never exit, see [stuck LiteSpeed lsphp processes](/guides/litespeed-stuck-lsphp-processes/); for 503 errors, [LiteSpeed 503 errors with lsphp on cPanel](/guides/litespeed-503-lsphp-cpanel/).

Check the real per-process size on your server:

```
ps -C lsphp -o rss= | awk '{s+=$1; n++} END {if (n) printf "%d lsphp processes, average %.0f MB\n", n, s/n/1024}'
```

After changing PHP settings, detached LSPHP processes keep the old configuration until they restart. LiteSpeed documents three ways: `touch /usr/local/lsws/admin/tmp/.lsphp_restart.txt` for the whole server, `touch ~user/.lsphp_restart.txt` for one account, or `killall lsphp` to stop them at once.

## Step 3: object cache and OPcache for the requests that miss

Some requests can never be page-cached: the WooCommerce cart and checkout, account pages, the admin area, and AJAX calls. They all run WordPress and its database queries. An object cache keeps the results of repeated queries in memory:

- LSCache does not cache objects itself; it connects to Redis, Memcached or LiteSpeed’s LSMCD on the **Object** tab. Object Cache is off by default, and the default method is Memcached on `localhost:11211`; set the port to `0` and give the socket path if you use a UNIX socket.

- The default object lifetime is 360 seconds. Keep it short, so that changed data is not served stale for long.

- Check that PHP’s OPcache is enabled (`php -i | grep opcache.enable` with the LSPHP binary for that site). Without it, PHP compiles every WordPress file on every request. For the database side, see [InnoDB tuning for MariaDB on shared hosting](/guides/innodb-tuning-mariadb-shared-hosting/).

## Step 4: run WP-Cron from a real cron job

By default WordPress checks for scheduled tasks during page requests. On a busy site that means extra work inside visitor requests; on a fully cached site the tasks can run late, because cached pages never start PHP. WordPress’s developer documentation describes the fix: switch off the request-triggered cron and run it on a schedule.

```
// wp-config.php, above "That's all, stop editing!"
define( 'DISABLE_WP_CRON', true );
```

```
# crontab for the site's user: run due WordPress tasks every 5 minutes
*/5 * * * * cd /home/USER/public_html && /usr/local/bin/php wp-cron.php > /dev/null 2>&1
```

Use the PHP binary and path of that site. If WP-CLI is installed, `wp cron event run --due-now` does the same job.

## Step 5: the server’s connection settings

LiteSpeed’s server tuning settings rarely limit a WordPress site before PHP or the cache does, but check them:

- **Max Connections** counts plain and TLS connections together. **Max SSL Connections** must be lower than it. When the limit is reached, keep-alive connections are closed after their current request. OpenLiteSpeed 1.9.3 ships with 10,000 for both.

- **Connection Timeout** closes connections with no traffic. LiteSpeed advises keeping it low, so dead connections are freed during an attack. The OpenLiteSpeed default is 300 seconds.

- **Keep-Alive Timeout** and **Max Keep-Alive Requests** (OpenLiteSpeed defaults 5 seconds and 10,000) rarely need changing.

- **Compression** is on by default; the dynamic GZIP level defaults to 6, and higher levels cost more CPU for little extra saving.

- On cPanel, LiteSpeed’s tuning page also recommends enabling TLS 1.3 in WHM (SSL/TLS Protocols `ALL -SSLv3 -TLSv1 -TLSv1.1`) and moving the swap and static-cache directories to fast disk.

## Step 6: measure before and after you tune LiteSpeed

Change one thing at a time and measure the same URL the same way:

```
# 3 runs of 400 requests, 20 at a time, from a machine near the server
for i in 1 2 3; do ab -q -n 400 -c 20 https://example.com/some-post/ | grep -E "Requests per second|  95%"; sleep 5; done
```

Watch `x-litespeed-cache`, the load average and LiteSpeed’s `stderr.log` while it runs. Never load-test a production server at peak time, and never load-test a site you do not own.

## How we tested this guide

The measurements above come from our test server (a cloud container with 2 vCPU and 8 GB RAM, Ubuntu 24.04, OpenLiteSpeed 1.9.3 from LiteSpeed’s repository, LSPHP 8.3.35, MariaDB 10.11.14, WordPress 7.1.3 and LiteSpeed Cache 7.9.1) on 18 October 2026, with `ab` running on the same machine. In some runs without the page cache, PHP requests stalled for up to 60 or 120 seconds and LiteSpeed logged “No request delivery notification has been received from LSAPI application, possible dead lock”. We did not find the cause in that container, so those runs are not in the figures above and we make no claim about it.

The cPanel and LiteSpeed Enterprise settings (PHP suEXEC Max Conn, the WHM paths, the detached-PHP restart files) come from LiteSpeed’s documentation and were not run on a cPanel server for this guide.

Sources: LiteSpeed’s [cPanel tuning page](https://docs.litespeedtech.com/lsws/cp/cpanel/tunings/), the LSPHP [modes](https://docs.litespeedtech.com/lsws/extapp/php/configuration/modes/) and [options](https://docs.litespeedtech.com/lsws/extapp/php/configuration/options/) pages, the OpenLiteSpeed server tuning reference (in the server’s own `docs/ServTuning_Help.html`), the LSCache for WordPress [Cache and Object](https://docs.litespeedtech.com/lscache/lscwp/cache/) and [Crawler](https://docs.litespeedtech.com/lscache/lscwp/crawler/) pages, and WordPress’s [Hooking WP-Cron Into the System Task Scheduler](https://developer.wordpress.org/plugins/cron/hooking-wp-cron-into-the-system-task-scheduler/).

## Frequently asked questions

### Should I raise PHP suEXEC Max Conn to 100?

Only if `stderr.log` shows the limit being reached and the server has the memory for it. On a small server, 100 processes of 50 MB each is 5 GB of PHP alone. A higher limit lets more requests run at once; it does not make each one faster.

### Is OpenLiteSpeed as fast as LiteSpeed Enterprise for this?

Both serve LSCache hits from the server without PHP, which is where most of the gain is. Enterprise reads Apache configuration and `.htaccess` files directly and integrates with cPanel; OpenLiteSpeed has its own configuration. We tested on OpenLiteSpeed only; the differences are in [LiteSpeed vs OpenLiteSpeed](/guides/litespeed-vs-openlitespeed/).

### Do I need a CDN as well?

A CDN takes static files and, if configured, cached pages away from the server and closer to visitors. It helps most with visitors far from the server. It does not fix pages that are cache misses at the origin.
