What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

To run PHP as FastCGI with Apache, keep Apache responsible for HTTP and static files, run PHP workers under PHP-FPM, and connect the two with Apache’s mod_proxy_fcgi module. PHP requests are forwarded to a PHP-FPM Unix socket or TCP listener; HTML, CSS, JavaScript and image requests remain in Apache.

The reliable workflow is: install PHP-FPM and Apache’s FastCGI proxy modules, confirm the FPM listener, map only PHP requests in the virtual host, make the socket accessible to Apache, validate the configuration, reload both services as needed, and test with a small script. The exact package and service names differ by distribution and release, so verify those labels before applying commands.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What “PHP through FastCGI” means

FastCGI is a protocol for sending dynamic requests from a web server to a long-running application process. In this arrangement, Apache accepts the browser connection, chooses a virtual host, serves static content directly and forwards matching PHP requests to PHP-FPM. PHP-FPM (FastCGI Process Manager) creates and supervises PHP worker processes, executes the script and returns the response to Apache.

Apache does not launch PHP-FPM itself. Its mod_proxy_fcgi module supplies the FastCGI client side and depends on mod_proxy. The Apache Software Foundation describes it this way: “This module requires the services of mod_proxy and provides support for the FastCGI protocol.”

PHP-FPM can listen on either a Unix-domain socket, such as /run/php/php-fpm.sock, or a TCP address, commonly 127.0.0.1:9000. The listener you configure in Apache must exactly match the listener configured in the selected FPM pool.

Why use PHP-FPM with Apache?

PHP-FPM separates PHP worker management from Apache. That separation gives you controls that are difficult or impossible with an embedded PHP module: independent worker limits, separate pools for different sites, per-pool users and groups, and the ability to restart PHP without restarting Apache. It also works with Apache’s event-based MPMs, whereas embedded PHP historically imposed tighter MPM and process-model constraints.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

There is an operational cost. You manage an additional service, a listener, socket permissions and two sets of logs. A bad listener path or an inaccessible socket produces an application failure even when Apache itself is healthy. For most current Apache deployments that need isolation or pool controls, PHP-FPM is the practical default; retain an embedded module only when a documented legacy combination requires it.

Before you configure anything

Identify the platform and runtime labels

Package names, service names, FPM pool filenames, socket locations and Apache module-enabling commands vary between Linux distributions and releases. Identify the distribution, Apache version, PHP version and the account under which Apache workers run. Do not copy a service name such as php-fpm blindly if your distribution includes a version suffix.

Decide between a Unix socket and TCP

Listener Typical form Advantages Checks required
Unix socket /run/php/php-fpm.sock Local-only endpoint with filesystem permissions; no TCP port to expose. The socket must exist, and Apache must have permission to connect and traverse its parent directories.
TCP 127.0.0.1:9000 Simple to inspect and useful when the web server and FPM are separated by a local or network boundary. FPM must be listening on that address, the address must be reachable, and firewall or network policy must permit it.

Use the value in the active FPM pool’s listen directive rather than assuming either example is present on your system. If more than one PHP version is installed, confirm which pool and service own the endpoint.

Install Apache, PHP-FPM and the proxy modules

Install Apache, the PHP runtime, PHP-FPM and your distribution’s packages that provide mod_proxy and mod_proxy_fcgi. The package names are distribution-specific; use the release’s official package manager and documentation to select matching versions.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

After installation, start and enable the FPM service using the service identifier supplied by your distribution. Then check its status and inspect the pool configuration to find the active listen value. A healthy service should create the configured Unix socket or show a listening TCP endpoint before Apache is pointed at it.

Enable Apache’s proxy and proxy_fcgi modules using the mechanism provided by your distribution. If your installation does not provide an enablement helper, load the modules in Apache’s module configuration and verify that the corresponding shared objects exist. Apache must load mod_proxy as well as mod_proxy_fcgi; loading only the latter is insufficient.

Configure the PHP-FPM pool

Set the listener

Open the pool used by the site and set listen to one endpoint. For a local socket, choose the exact path you will use in Apache. For TCP, use a local address such as 127.0.0.1:9000 unless your architecture specifically requires another interface.

Set ownership and mode for a Unix socket

FPM pools expose controls such as listen.owner, listen.group and listen.mode. Set them so the Apache runtime user, or a deliberately chosen shared group, can connect to the socket. Also ensure Apache can traverse every parent directory in the path. Prefer a restrictive mode and a dedicated group; do not make the socket world-writable just to get a test working.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choose worker limits for the available memory

FPM controls how many workers can run and how they are recycled. Tune the pool’s process-management limits to the memory available after accounting for Apache, the operating system, databases and other services. A high worker count can exhaust memory; a low count can queue requests and increase latency. Change one limit at a time, observe Apache and FPM logs, and use the pool status information available on your installation rather than guessing from traffic alone.

Use separate pools where isolation matters

A separate pool and least-privileged account can prevent one site’s PHP processes from running with another site’s permissions. This is especially useful on a multi-site server. Keep each pool’s socket, document paths and writable directories scoped to the site that owns them.

Map PHP requests in Apache

Set the virtual host and document root

Put the FastCGI mapping in the virtual host that serves the site. Set DocumentRoot to the directory containing the application, authorize that directory according to your Apache version, and define a directory index such as index.php index.html. The filesystem path in the FastCGI backend URL must correspond to the document root; a mismatch can produce confusing 404 responses or execute the wrong file.

Use a Unix-socket ProxyPassMatch rule

A common pattern for a site rooted at /var/www/html/ and an FPM socket at /run/php/php-fpm.sock is:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
ProxyPassMatch ^/(.*.php(/.*)?)$ unix:/run/php/php-fpm.sock|fcgi://localhost/var/www/html/

This rule matches PHP paths, including an optional path-info suffix, and sends only those requests to FPM. Replace both paths with the values used by your pool and virtual host. The backend document path must end in the directory that Apache exposes as the site’s document root.

Use TCP when the pool listens on an address

If the pool listens on 127.0.0.1:9000, use a TCP FastCGI backend instead of the Unix-socket form. The exact directive form depends on the Apache release and its proxy configuration syntax, so follow that release’s mod_proxy_fcgi documentation and preserve the same URL-to-document-root relationship.

Use a SetHandler form when appropriate

Apache versions and distributions also document a SetHandler-based configuration for assigning a FastCGI handler to PHP files. Choose one supported form for the target Apache release rather than combining examples from different versions. Regardless of syntax, restrict the handler to PHP requests and point it at the exact FPM listener.

Do not proxy every file

Do not send images, stylesheets, downloads or arbitrary paths to PHP-FPM. A narrow PHP match reduces overhead and limits the chance that Apache treats a non-PHP file as executable application input. Keep uploaded files and private configuration outside the document root where possible, and explicitly protect sensitive files that must remain inside it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Complete configuration checklist

  1. Confirm Apache’s DocumentRoot and the FPM pool’s listen value.
  2. Load mod_proxy and mod_proxy_fcgi.
  3. Add the PHP-only ProxyPassMatch or supported SetHandler rule to the correct virtual host.
  4. Make sure the backend filesystem path matches the document root.
  5. Set DirectoryIndex index.php index.html if the application expects directory requests to resolve to index.php.
  6. Align socket ownership, group and mode with Apache’s runtime account, without granting unnecessary write access.
  7. Keep secrets, application configuration and temporary data out of the public document tree when the application permits it.
  8. Run apachectl configtest (or the equivalent command supplied by your distribution) and fix every error before reloading.
  9. Reload Apache after a successful test. Restart or reload PHP-FPM only when its pool configuration changed, following the service’s supported operation.

Verify that Apache is executing PHP

Create a temporary diagnostic script

Place a minimal file such as health.php in the document root:

<?php
echo "fastcgi-okn";

Request it locally or through the site’s hostname:

curl -i http://example.test/health.php

Expect an HTTP success response and the text fastcgi-ok. The response headers and body confirm that Apache matched the PHP rule and obtained a response from FPM, but they do not prove that every application path is correct. Test a real front controller separately if the site uses URL rewriting or path info.

Remove diagnostics immediately

Delete the test file after verification. Do not leave phpinfo() or other diagnostic pages online: they disclose PHP settings, loaded extensions, paths and environment details useful to an attacker.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Check both log streams

When a request fails, inspect the Apache error log and the PHP-FPM service or pool log at the same time. Apache records proxy and permission failures; FPM records listener, worker and script-side failures. Correlating timestamps is usually faster than changing directives at random.

Why is Apache downloading my PHP file?

If the browser displays PHP source or downloads the file, Apache did not assign a PHP handler to that request. Check these causes in order:

  • mod_proxy or mod_proxy_fcgi is not loaded.
  • The rule is in a different virtual host than the one selected for the request.
  • The regular expression does not match the requested path, including a path-info suffix.
  • The configuration was edited but Apache was not successfully reloaded.
  • A later or more specific rule overrides the PHP handler.
  • The request is reaching a different server or container than the one you changed.

Run the configuration test, confirm the active virtual host, reload Apache and request the file again. Never leave source exposure enabled while troubleshooting; restrict access or remove the file until the handler is fixed.

Why am I getting a 502 Bad Gateway from PHP-FPM?

A 502 usually means Apache could not complete the FastCGI connection. Verify the following without changing multiple variables at once:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Confirm that the FPM service is running and that the intended pool loaded successfully.
  2. Compare Apache’s backend endpoint character-for-character with the pool’s listen value.
  3. For a Unix socket, check that the socket exists and that Apache can traverse its parent directories and connect under its runtime account.
  4. For TCP, confirm that FPM is listening on the configured address and port, and that local firewall or network policy is not blocking it.
  5. Read the Apache and FPM logs for connection-refused, missing-socket, permission-denied or worker-exhaustion messages.
  6. After a PHP upgrade, remove an obsolete socket only when you have confirmed which service owns it; then restart the intended FPM service so it recreates the configured endpoint.

Do not solve a permission error by making the socket world-writable. Correct the owner, group, mode or Apache account instead.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Other common failures

404 Not Found

Check that the request reaches the expected virtual host, that DocumentRoot points to the application directory and that the FastCGI backend path corresponds to that same directory. Verify URL-to-file mapping when the application uses a front controller, rewrites or path info.

403 Forbidden

Inspect filesystem read and execute permissions on every parent directory, Apache’s directory authorization rules and any access-control policy enforced by the operating system. The Apache account needs to read the script and traverse its path, but it does not need broad write permission.

Requests time out

Look for an exhausted FPM worker pool, long-running scripts, an overly restrictive request timeout or unsuitable connection reuse. Apache’s documentation warns that inappropriate connection reuse can leave PHP-FPM workers busy and contribute to request timeouts. Compare concurrent PHP demand with pool worker limits, then review Apache proxy timeout and reuse settings for your Apache release.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The wrong PHP version runs

Multiple PHP installations can leave several FPM services or sockets on the host. Confirm the socket or TCP endpoint referenced by the virtual host, identify the pool that owns it and remove stale references after an upgrade. A temporary diagnostic page can show the runtime version during testing, but remove it as soon as the endpoint is confirmed.

PHP-FPM versus mod_php

Decision factor PHP-FPM through FastCGI Embedded mod_php
Process isolation PHP workers run in a separate service and can be split into pools. PHP executes inside Apache’s process model.
Per-site users Each pool can use a least-privileged account and its own socket. Per-site separation is more constrained by the Apache process model.
Worker controls Pool settings expose worker counts, recycling and listener controls. Worker behavior follows the embedded Apache process model.
Apache MPM compatibility Fits modern event or worker MPM deployments because PHP is external. May require a legacy-compatible Apache MPM and PHP combination.
Restart independence PHP-FPM can be restarted independently of Apache. Changing PHP generally requires an Apache restart.
Memory behavior Memory is controlled through FPM workers and Apache workers as separate pools; poor limits can still exhaust the host. PHP memory use is tied more directly to Apache’s process model.
Operational complexity Higher: maintain FPM service state, listener paths, permissions and two log streams. Lower for a legacy single-site setup, but with fewer isolation and tuning options.

Choose PHP-FPM when you need pool-level controls, per-site identities, modern Apache MPM compatibility or independent PHP restarts. Keep mod_php only when an application or documented legacy environment specifically depends on it and you accept its process-model limitations.

Security and maintenance practices

  • Run each site with the least privilege practical for its files and database credentials.
  • Use separate FPM pools when sites should not share a PHP user or resource limits.
  • Keep socket ownership and mode restrictive; use a shared group only when there is a clear operational need.
  • Patch Apache, PHP and installed extensions through the operating system’s supported update process.
  • Store secrets outside the document root and deny direct access to configuration, source-control metadata, backups and private keys.
  • Constrain upload and temporary directories, and ensure uploaded content cannot be interpreted as executable application code through an overly broad handler.
  • Monitor Apache access and error logs together with FPM pool and service logs.
  • Review worker saturation, process restarts, memory pressure and repeated 5xx responses after changing traffic patterns or pool limits.
  • Remove test scripts, diagnostic output and abandoned sockets after migrations or version changes.

A repeatable deployment sequence

  1. Record the target distribution, Apache release, PHP release, Apache runtime user and the intended FPM pool.
  2. Install Apache, PHP-FPM and the distribution packages containing mod_proxy and mod_proxy_fcgi.
  3. Enable and start the correct FPM service, then record its active listen endpoint.
  4. Configure pool ownership, group, socket mode and worker limits for the site’s security and memory requirements.
  5. Enable Apache’s proxy modules and place the PHP-only mapping in the correct virtual host.
  6. Verify the document root, backend filesystem path, directory authorization and directory index.
  7. Run apachectl configtest; do not reload while it reports errors.
  8. Reload Apache and request a temporary PHP test page with curl -i.
  9. If the result is not successful, use the symptom-specific checks above and read both log streams before editing more settings.
  10. Delete the test page, confirm private files are inaccessible and document the chosen socket, pool and service names for the next upgrade.

Final operational guidance

The connection is only as reliable as its three matching pieces: Apache’s PHP request rule, the FPM listener and the filesystem permissions that join them. Keep the mapping narrow, make the backend path agree with the document root, size workers for available memory and treat socket permissions as a security boundary. With those conditions in place, Apache can serve static content efficiently while PHP-FPM manages PHP execution independently.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.