Async/Thread on PHP7 with FPM
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
PHP-FPM (FastCGI Process Manager) uses a process-based model where each request runs in a separate process with no shared memory. PHP does not support threads in FPM mode — the pthreads extension only works with the CLI SAPI, not with web server SAPIs. For async behavior in PHP-FPM, use non-blocking I/O libraries like ReactPHP or Amp, offload work to message queues (Redis, RabbitMQ), use exec() to spawn background processes, or leverage PHP 8.1+ Fibers for cooperative multitasking.
Why Threads Don't Work in FPM
PHP-FPM spawns worker processes, not threads. Each request gets its own process. The pthreads extension is explicitly disabled for web SAPIs because PHP's core data structures are not thread-safe.
Solution 1: ReactPHP (Event-Driven I/O)
ReactPHP provides an event loop for non-blocking I/O:
All three requests run concurrently on a single process using non-blocking sockets. The event loop handles I/O multiplexing.
Solution 2: Amp (Coroutines)
Amp provides async/await style programming for PHP:
Solution 3: Background Process with exec()
Fire-and-forget a background job from an FPM request:
The & at the end makes the process run in the background. The web request returns immediately while the worker runs independently.
Solution 4: Message Queue (Recommended for Production)
Use a message broker to decouple web requests from background processing:
Run the worker with supervisord or systemd to keep it alive:
Solution 5: PHP 8.1 Fibers
Fibers provide cooperative multitasking within a single process:
Fibers are the foundation for async libraries like Amp v3 and RevoltPHP. They allow cooperative scheduling but are not true threads — they run on a single OS thread.
Solution 6: curl_multi for Parallel HTTP
curl_multi runs HTTP requests in parallel using non-blocking I/O, without requiring any external libraries.
Common Pitfalls
- Trying to use
pthreadsin FPM: Thepthreadsextension only works with the CLI SAPI. It is explicitly incompatible with FPM, Apache mod_php, and other web server SAPIs. There is no workaround — PHP's core is not thread-safe under these SAPIs. - Using
exec()without output redirection:exec('php worker.php')without> /dev/null 2>&1 &blocks until the worker finishes, making the web request wait. Always redirect output and background the process. - Not handling queue worker failures: If a queue worker crashes, messages are lost unless the queue supports acknowledgments. Use RabbitMQ with manual acks or Redis with
BRPOPLPUSHfor reliable processing. - Running event loop libraries inside FPM requests: ReactPHP and Amp event loops are designed for long-running CLI processes. Running them inside a short-lived FPM request adds overhead and complexity. Use them for CLI workers, not web requests.
- Confusing Fibers with threads: Fibers are cooperative (they explicitly yield), run on a single OS thread, and do not provide parallelism. They enable async-style code but cannot use multiple CPU cores. For CPU-bound parallelism, use multiple worker processes.
Summary
- PHP-FPM does not support threads —
pthreadsis CLI-only - Use
curl_multifor parallel HTTP requests within a single FPM request - Use ReactPHP or Amp for event-driven async I/O in CLI workers
- Offload background work to message queues (Redis, RabbitMQ) with separate worker processes
- PHP 8.1 Fibers enable cooperative multitasking but are not true threads
- For production async workloads, use message queues with supervisor-managed workers

