Webcore

WEBCORE RESOURCES

WordPress Hosting Architecture Explained: Nginx, Apache, PHP-FPM & MySQL

Follow a WordPress request through Nginx, Apache, PHP-FPM, WordPress and MySQL, and understand what each layer of the hosting stack is responsible for.

Technical guide Updated 15 September 2026

A WordPress website may look like one application in a browser, but a request normally passes through several distinct layers before the visitor receives a page. In Webcore’s managed stack, Nginx, Apache, PHP-FPM, WordPress and MySQL each have a different job.

Understanding those boundaries makes hosting considerably easier to reason about. A slow page is not simply “slow WordPress”, and a 502 or 503 response does not automatically mean the database is broken. The point at which a request fails often tells you which part of the stack to investigate.

WordPress is the application. Nginx, Apache, PHP-FPM and MySQL are platform layers that get requests to it, execute its code and store its persistent data.

A WordPress request from browser to database

For a normal dynamic request on Webcore, the path can be simplified to:

BrowserRequests a hostname and URL over HTTP or HTTPS.
DNS + networkDirect the request to the server or edge service responsible for the hostname.
NginxAccepts the public HTTP/HTTPS connection, handles TLS and can serve static files or page-cache hits without invoking the application stack.
ApacheReceives requests that need site-level web handling, including WordPress routes and Apache-compatible rewrite behaviour.
PHP-FPMProvides the site’s managed PHP worker processes and executes WordPress PHP code.
WordPressLoads core, plugins and the theme, applies application logic and builds the response.
Redis / MySQLSupply cached application objects and persistent site data required by WordPress.

The response then travels back through Apache and Nginx to the visitor. Crucially, not every request travels all the way through this path. Nginx can answer some requests itself.

Nginx is the public-facing web layer

Nginx is the first web-server layer reached at the origin. It accepts requests for configured hostnames, handles HTTPS using the site’s certificate and decides whether a request can be satisfied at the edge of the hosting stack or needs to continue to Apache.

Traffic Nginx can handle directly

  • Static assets: suitable images, stylesheets, JavaScript, fonts and other static files can be served without involving Apache, PHP or WordPress.
  • Page-cache hits: a valid cached HTML response can be returned without starting the dynamic application path.
  • Edge web behaviour: TLS, redirects, request controls and other Nginx-level policy can operate before the application is invoked.

This is why Nginx remains useful even though Apache also exists in the stack. It handles the public connection efficiently and prevents unnecessary requests from travelling deeper into the application layers.

Where does Apache sit?

Apache sits behind Nginx. Requests that are not satisfied directly by Nginx are proxied to the site’s Apache virtual host rather than being sent straight from Nginx to PHP-FPM.

For a typical WordPress request, that means the dynamic path is Nginx → Apache → PHP-FPM → WordPress. Apache provides the site-level web-server behaviour expected by a large amount of existing WordPress software, including Apache rewrite rules and .htaccess-compatible configuration.

Traffic that normally reaches Apache

  • WordPress front-controller routes such as posts, pages, archives and other pretty permalinks.
  • Requests that need Apache rewrite or .htaccess processing.
  • PHP-backed application requests that need to continue to the site’s PHP-FPM pool.
  • Requests not matched by the static or cache handling performed at Nginx.

Apache is therefore not competing with Nginx for the same role. Nginx is the public-facing and acceleration layer; Apache is the compatibility and dynamic web-handling layer behind it.

PHP-FPM provides the PHP workers

Apache does not need to run WordPress PHP inside its own process. PHP requests are passed to PHP-FPM, the FastCGI Process Manager. PHP-FPM maintains pools of PHP worker processes that execute scripts on behalf of incoming requests.

A worker has finite CPU time and memory. A pool also has a finite number of workers. If every worker is busy with slow requests, new dynamic requests can queue or fail while Nginx may still remain perfectly capable of serving static files or cached pages.

Why PHP workers matter

  • A slow plugin or external API call can occupy a worker for much longer than a normal request.
  • Too little capacity can create queues during bursts of uncached traffic.
  • Too much unconstrained capacity can exhaust memory and make the whole server less stable.
  • Per-site pools provide useful isolation and make resource behaviour easier to attribute.

PHP OPcache also operates at this layer, retaining compiled PHP bytecode so workers do not need to compile the same WordPress, plugin and theme files for every request.

WordPress is the application layer

Once PHP begins executing the WordPress entry point, the application loads its configuration, core code, active plugins and theme. WordPress interprets the request, determines what content or action is required and generates the response.

This is where application behaviour can become expensive. Plugins may perform database queries, call external services, process large data sets or execute code on every request. Themes can do the same. WordPress itself can therefore be the source of a slow request even when Nginx, Apache, PHP-FPM and MySQL are all functioning normally.

Tools such as WP-CLI operate against this application layer from the command line. They can manage WordPress directly without turning the site user into a server administrator.

Redis can reduce repeated application work

When persistent object caching is enabled, WordPress can use Redis to retain useful objects and query results between requests. That can prevent repeated database work for information the application asks for frequently.

Redis is not the database of record for a normal WordPress site. Losing an object-cache entry should mean WordPress has to retrieve or rebuild the information again, not that the site’s authoritative content has disappeared.

This is different from full-page caching at Nginx. Redis helps requests that are already running WordPress; page cache can prevent Apache, PHP-FPM and WordPress from running for a request in the first place. The WordPress caching layers guide explores those boundaries in more detail.

MySQL stores the persistent site data

WordPress stores posts, pages, users, options, metadata, comments and much plugin data in MySQL. The database is therefore persistent application state rather than simply another cache.

Database performance depends on more than server size. Query design, indexes, table size, locking, working-set memory and the number of requests reaching the database all matter. A badly behaved plugin can generate excessive queries on a powerful database server; good page and object caching can prevent many unnecessary queries from arriving at all.

Files and database form the site together

The database does not contain everything. WordPress core, plugins, themes and uploads live in the filesystem. A complete recovery or staging workflow therefore needs to understand both persistent data stores: files and database.

Three useful request paths

Static fileBrowser → Nginx → file → response. Apache, PHP-FPM and WordPress are not required.
Page-cache hitBrowser → Nginx → cached HTML → response. The dynamic stack is bypassed.
Dynamic WordPress requestBrowser → Nginx → Apache → PHP-FPM → WordPress → Redis / MySQL → response.

Thinking in these paths is more useful than imagining that every request always traverses every service on the server.

Where common failures appear

DNS or connection failure

The request may never reach the intended web server. Check hostname resolution, network routing and any proxy or CDN layer first.

TLS or certificate error

The request reaches the public HTTPS layer, but the certificate or hostname configuration cannot establish the expected secure connection.

Nginx routing or static-file problem

A wrong virtual host, missing static path, redirect rule or edge configuration can fail before Apache or WordPress is involved.

Apache or rewrite problem

If Nginx successfully proxies the request but Apache cannot process the site’s virtual-host, rewrite or .htaccess behaviour correctly, dynamic routes can fail even though Nginx itself is healthy. Redirect loops are another example where understanding the Nginx-to-Apache boundary matters.

502 / 503 around the dynamic backend

Nginx may be unable to reach Apache, or Apache may be unable to reach a healthy PHP-FPM backend. The PHP pool may also be unavailable or saturated, or a platform policy may be preventing workers from serving requests. Nginx, Apache and PHP-FPM logs help establish which hop failed.

Slow dynamic response

The request reached the dynamic stack but took too long to complete. PHP slow logs, WordPress diagnostics, database activity and external dependencies become more useful than treating Nginx as the only suspect.

Database connection error

WordPress executed far enough to attempt database access but could not establish or maintain the required connection. Credentials, service availability, limits and database health are then relevant.

Why isolation matters on multi-site hosting

A hosting platform may serve many WordPress sites on the same infrastructure. The architecture should therefore make ownership and failure boundaries clear. Separate site users, PHP-FPM pools, filesystem permissions, quotas and scoped management controls help prevent one site’s application behaviour from becoming unrestricted access to another site or to the node itself.

Isolation does not mean every site requires its own physical server. It means the shared layers need deliberate boundaries, while workloads that require stronger resource separation can move to dedicated infrastructure without changing the basic WordPress operating model.

How Webcore maps these layers

Webcore uses Nginx as the public HTTP/HTTPS and acceleration layer, with Apache behind it for compatible site-level and dynamic web handling. PHP executes in managed PHP-FPM pools, WordPress remains the application, Redis can provide persistent object caching, and MySQL stores the site’s persistent database state.

This layered design lets Webcore serve static or cached traffic without invoking the complete application path while retaining the Apache behaviour expected by existing WordPress sites when dynamic requests need it.

See Managed WordPress Hosting for the managed service, WordPress for Developers & Agencies for development workflows, the Webcore Platform for the underlying infrastructure, or Webcore Panel for the control platform.

MANAGED WORDPRESS STACK

Keep every layer working as one platform.

Webcore manages the web, PHP, caching, database and operational layers while keeping site-level controls accessible to developers.