Businessman is pressing on the virtual screen php

The Importance of PHP Workers in WordPress Hosting

A fast site dies fast when your PHP workers are overloaded.

When a WordPress page can’t be served from cache, your server must execute PHP code to build a fresh response. That work is done by a pool of PHP workers. If the pool is too small or busy, requests queue, users wait, and revenue leaks. If you run a store, membership portal, news site, or anything dynamic, understanding PHP workers isn’t a nice to have. It’s table stakes for capacity, stability, and predictable speed.

What a PHP worker actually is

In most WordPress stacks, PHP runs under PHP-FPM, the FastCGI Process Manager. PHP-FPM maintains a pool of processes, often called “workers,” that accept PHP requests from your web server and return generated HTML or JSON. Each worker handles one request at a time. When all workers are busy, additional requests wait in a queue until a worker frees up. That’s the entire game. PHP

A few essentials from PHP-FPM itself:

  • Workers live in “pools,” each with its own settings and limits.
  • Core concurrency is set by pm.max_children, which caps how many requests can run in parallel.
  • You can choose a process manager style like dynamic, ondemand, or static, and tune startup, spare, and respawn behavior. PHP+1

The web server simply passes matching requests to PHP-FPM over a socket or TCP with fastcgi_pass. Nginx’s FastCGI module is the common path, though Apache with proxy_fcgi works too. Nginx+1

How WordPress uses PHP workers

WordPress is a hybrid of cached and dynamic behavior. Plenty of pages can be served from a page cache or CDN, which avoids PHP entirely. But there’s a long list of common requests that must hit a PHP worker:

Even on brochure sites, edits, preview, and first hits after cache expiry consume worker time. Stores and communities push far harder. The more traffic that bypasses cache, the more you lean on workers.

Caching reduces worker load, but cannot remove it

Page caching offloads a huge chunk of anonymous traffic. Properly configured cache layers sit in front of PHP and serve stored responses in milliseconds. Yet some paths must bypass cache for correctness, including cart and checkout in WooCommerce, plus any personalized content. Those requests still need a worker right now. WordPress VIP Documentation+1

Object caching is different. It accelerates PHP itself by storing expensive computed results in memory via in-process APIs and persistent backends like Redis. Object cache does reduce worker time per request, but it doesn’t reduce how many concurrent workers you need when the site is under uncached load. Page cache avoids workers; object cache helps them finish faster. That distinction trips people up alot. WordPress Developer Resources+2WordPress Developer Resources+2

The queueing math that predicts worker need

A simple, reliable way to estimate concurrency is Little’s Law from queueing theory:

Concurrent PHP requests ≈ arrival rate × average service time

If your site sees 20 uncached requests per second during a campaign and each takes 300 ms of PHP time on average, expected concurrency is 6. You’ll want at least that many PHP workers available, plus headroom. This relationship is general and doesn’t depend on arrival randomness. It’s why measuring real service time under load is so useful. Wikipedia

A quick sizing example

  • Peak uncached rate: 12 requests per second
  • Mean PHP time for those paths: 250 ms
  • Expected concurrency: 12 × 0.25 = 3 workers

Allow 50 to 100 percent headroom for spikes, background jobs, and uneven arrivals. Target 5 to 6 workers. If you improve code and caching so average service time drops to 125 ms, concurrency halves and the same pool now handles double the traffic.

Where PHP workers bottleneck performance

When the pool is starved, you’ll see:

  • Slower page build time and rising TTFB on dynamic pages
  • 502 or 504 errors if upstreams time out while waiting for a worker
  • Slow or stuck scheduled tasks when WP-Cron or Action Scheduler jobs fight with web traffic for workers
  • Intermittent admin slowdowns during editorial peaks WP Engine

These symptoms are not subtle during sale events or launches. The fix is rarely one slider. It is alignment of caching, code efficiency, and the worker pool.

Host plan limits and terminology

Many managed WordPress providers expose a plan attribute called “PHP workers,” “PHP threads,” or similar. It generally refers to the maximum number of concurrent PHP requests your site can run before requests are queued or throttled. Providers implement limits and queuing differently, but the effect is the same: once you hit the cap, performance suffers until load subsides, code speeds up, or you scale the plan. Always check your provider’s definitions, limits, and how they prioritize requests when saturated. WP Engine

Note that in PHP-FPM these are processes. Some hosts present the concept as “threads” or “workers” at an account level. Under the hood, concurrency maps to pm.max_children and related pool settings. PHP

How to measure your worker reality

You can’t tune what you can’t see. Start with:

  • APM instrumentation to find slow transactions, database calls, and external waits. New Relic’s PHP agent gives a breakdown of code paths and query time. It helps separate true PHP time from upstream pauses. New Relic Documentation+1
  • PHP-FPM status page to view active, idle, and maxed workers in real time. Restrict it to internal access only because it reveals sensitive operational data. PHP+1
  • Web server logs to check rate and response times of uncached endpoints, plus error rates from timeouts.
  • Platform cache analytics to confirm page cache hit rates on key paths like product listing and blogs. High hit rates lower worker pressure.

Tuning PHP-FPM without guesswork

Your process manager mode and pool settings define how the worker pool behaves under pressure. Focus on:

  • pm mode:
    • dynamic pre-creates a baseline of workers and scales between min and max spares.
    • ondemand creates workers only when needed, then kills idle ones after a timeout. Good for spiky sites.
    • static keeps a fixed number of workers, simplest to reason about when load is steady. PHP
  • pm.max_children: the hard cap on concurrent requests per pool.
  • pm.start_servers, pm.min_spare_servers, pm.max_spare_servers: how many initial and idle workers to keep around. Tideways

Set the cap based on measured concurrency and available CPU and memory. Too low and you underutilize hardware. Too high and you cause thrash from context switches and memory pressure.

Nginx and upstream plumbing

Make sure your Nginx FastCGI config points to the correct PHP-FPM socket or port and sets sane timeouts for slow endpoints like report exports or image generation. When your upstream waits are shorter than real work, you’ll see 502s even when workers are fine. The fastcgi_pass and FastCGI module directives are the place to confirm this. Nginx

Health and status

Enable pm.status_path on a hidden internal route and use it during load tests to confirm the pool isn’t pegged. The page exposes each worker’s state and queue length. Don’t expose it publicly. PHP

Caching strategy that helps workers most

Treat caching as layered:

  • Edge or page cache: serves whole pages without touching PHP, which is ideal. Use appropriate TTLs and smart cache invalidation. Exclude WooCommerce cart, checkout, and account pages, and any user specific dashboards. This keeps revenue paths correct. The WooCommerce Developer Blog+1
  • Object cache: persists computed data in Redis or Memcached so PHP spends less time per request. That lowers average service time, which by Little’s Law reduces concurrency need for the same throughput. WordPress Developer Resources
  • Browser cache and CDN: offload media and static assets so workers never see them.

If your cache hit rate is poor, find out why. Short TTLs, many unique query strings, or unnecessary bypass rules are common. Raising page cache TTL on safe paths can dramatically cut worker load.

Background jobs compete with web traffic

WordPress runs scheduled tasks through WP-Cron by default, which fires during page loads. Heavy jobs like email campaigns, inventory syncs, or subscription renewals will consume workers while real users wait. Offload WP-Cron to a real system cron that hits wp-cron.php every minute or use a host’s alternate cron so jobs run on schedule without waiting for visits. Use Action Scheduler for reliable queues, then monitor pending actions. WP Engine+2Action Scheduler+2

If jobs routinely take more than a minute, they may time out at the platform or be killed by upstream limits. Audit them with APM and restructure long tasks into smaller units to prevent pileups. WP Engine

Practical playbooks by site type

A content site with logged-in editors

  • Goal: keep anonymous traffic cached, protect editor experience.
  • Actions: ensure page cache for public posts, raise TTL for archive pages, add Redis object cache to speed editorial tools, set pm = dynamic with moderate max_children, and instrument the editor endpoints via APM.

A WooCommerce store

  • Goal: consistent checkout speed during spikes.
  • Actions: exclude cart, checkout, and account pages from cache, pre-warm product pages, enable Redis object cache, move WP-Cron to system cron, review Action Scheduler queues, size workers using observed peak checkout and account traffic with the Little’s Law calculation, then add headroom for payment gateway callbacks. The WooCommerce Developer Blog+1

A membership or e-learning site

  • Goal: many authenticated views, low cache hit.
  • Actions: invest heavily in object cache and query optimization, break long-running report endpoints into paged APIs, increase workers based on observed authenticated concurrency, and limit per-user heavy operations with rate controls.

A headless WordPress API

  • Goal: fast REST API under mobile app load.
  • Actions: cache GET responses at the edge where possible, tune PHP-FPM for API concurrency, and monitor REST routes with APM to keep average service time low. WordPress Developer Resources

Common mistakes that starve workers

  • Treating object cache as a replacement for page cache
  • Using SMS or email during sales to trigger heavy webhooks on the same server as production traffic
  • Leaving WP-Cron to run only on page views, which bunches jobs into traffic spikes
  • Raising pm.max_children far beyond CPU and memory, which leads to swapping and worse latency
  • Ignoring the status page and APM until the incident

Fixing any one of these can return more throughput than adding raw servers.

Cost control without surprises

Upgrading for more workers increases capacity, but so does lowering service time. Before you scale a plan:

  • Confirm cache hit rates and raise TTLs where safe
  • Use APM to find and fix slow database queries and remote calls
  • Move cron to system cron or a dedicated runner
  • Split unusually heavy admin operations into background tasks

If you still saturate the pool, then add workers or distribute workloads across pools or servers. That way your spend follows measured need, not guesswork. New Relic Documentation

Implementation checklist

  • Inventory uncached endpoints and estimate peak uncached RPS
  • Measure average PHP time for those endpoints with APM
  • Size pm.max_children with Little’s Law and add headroom
  • Confirm FastCGI timeouts align with realistic service time
  • Turn on the PHP-FPM status page for controlled monitoring
  • Configure page and object caching correctly
  • Migrate WP-Cron to system cron and audit Action Scheduler queues
  • Re-test and adjust every quarter or before major campaigns PHP+2Nginx+2

Troubleshooting signals

  • Rising TTFB on dynamic pages: likely starved workers or slow queries
  • 502/504 spikes: FastCGI timeouts too aggressive or long backend waits
  • Pending scheduled actions: insufficient worker headroom or long task blocks
  • Low cache hit rate: cache rules or TTLs need tuning

Few minutes with APM and the status page will separate code issues from capacity limits. New Relic Documentation

Final Takeaway

PHP workers are capacity, plain and simple. Know how many uncached requests you face at peak, how long they take, and how your worker pool is configured. Use page cache to avoid PHP whenever possible, object cache to shorten the work when you must, and job queues plus real cron to keep background load from colliding with users. Add monitoring so you see the queue form before customers feel it. Then set your PHP-FPM pool to match reality, not hope. Do those steps and the the checkout line stays short even on your busiest days.

Frequently Asked Questions

Are PHP workers the same as CPU cores?

No. Workers are PHP-FPM processes that execute requests. They compete for CPU cores, but they aren’t the cores themselves. If you run more workers than your CPU can serve, context switching and memory pressure can slow everything down. Size the pool against measured concurrency and available resources. PHP

How do I know if my site is hitting the PHP worker limit?

Watch APM traces for rising queue time or slow transactions during peak moments. Check the PHP-FPM status page for active workers at max and a growing queue. If the queue rises while CPU isn’t pegged, you may simply need more workers or shorter service times. PHP+1

Does object caching reduce the number of workers I need?

Indirectly. Object cache cuts service time for PHP requests, which lowers concurrency for the same throughput. You’ll still need enough workers to handle unavoidable uncached load. Pair object cache with page cache for the biggest gain. WordPress Developer Resources

Should I switch WP-Cron to a real cron job?

Yes for most production sites. Real cron fires on schedule without waiting for traffic, prevents large job bunching, and reduces contention with user requests. Many hosts offer an alternate cron, or you can use system cron to hit wp-cron.php every minute. WP Engine

What’s a safe default for pm.max_children?

There isn’t a universal number. Start from measured peak uncached concurrency using Little’s Law, then add 50 to 100 percent buffer for spikes and long tasks. Validate during load tests and confirm memory and CPU headroom to avoid swapping. Wikipedia

Can I cache WooCommerce checkout pages to save workers?

No. Cart, checkout, and account pages must bypass page cache to remain correct and secure. Focus on optimizing code, object cache, and worker headroom around those flows instead. The WooCommerce Developer Blog

References

Links

Similar Posts