PHP Concurrency Options
debt(d7/e7/b7/t7)
Closest to 'only careful code review or runtime testing' (d7). The detection_hints indicate automated detection is 'no' and the tools listed (Blackfire, Datadog) are profilers/APM tools that can surface latency patterns but won't flag architectural concurrency mismatches. The code_pattern described — sequential HTTP calls where concurrency would help, or CPU-bound work blocking FPM workers — only becomes visible under load or with careful profiling review. There is no linter rule that catches 'should be async here.'
Closest to 'cross-cutting refactor across the codebase' (e7). The quick_fix mentions multiple distinct remediation paths (RoadRunner, Swoole, pcntl queue workers) depending on the use case, and shifting from synchronous sequential code to an async model (ReactPHP/Fibers) or process-based concurrency touches request handling, error handling, database connections, and dependency compatibility throughout the application. This is not a single-file change; it reshapes how I/O is structured.
Closest to 'strong gravitational pull' (e7). The term applies_to web, cli, and queue-worker contexts — nearly all PHP runtime contexts. Choosing a concurrency model (Swoole, RoadRunner, Fibers/ReactPHP, pcntl) shapes how the entire application bootstraps, handles state, manages connections, and what third-party libraries are compatible. Every new feature must account for the chosen concurrency model, creating a persistent architectural constraint.
Closest to 'serious trap' (t7). The canonical misconception is 'PHP cannot do concurrent programming,' which causes developers to either abandon concurrency entirely or reach for the wrong tool (e.g., Fibers for CPU-bound work, pcntl_fork in web requests). The common_mistakes list confirms multiple ways a competent developer unfamiliar with PHP's concurrency landscape will guess wrong: Fibers behave unlike threads, pcntl_fork in FPM causes orphan processes, and Swoole has hidden coroutine-compatibility requirements — all contradicting expectations set by threading models in other languages.
Also Known As
TL;DR
Explanation
PHP concurrency options: (1) Fibers (PHP 8.1) — cooperative multitasking within a single thread, enables async/await patterns; (2) pcntl_fork() — true process forking for CPU-bound parallel work, each fork has its own memory; (3) parallel extension — true threads with shared memory (CLI only, experimental); (4) ReactPHP / Amp / Swoole — event loop frameworks that manage non-blocking I/O over Fibers or traditional callbacks; (5) PHP-FPM multiple workers — the standard PHP concurrency model — each request in a separate worker process. True parallelism in PHP requires multiple processes or Swoole's coroutines.
Common Misconception
Why It Matters
Common Mistakes
- Fibers for CPU-bound work — Fibers are cooperative concurrency for I/O, not parallel CPU execution.
- pcntl_fork() in web requests — forking in FPM creates orphan processes and database connection issues.
- Not handling child process exit in pcntl_fork() — zombie processes accumulate.
- Using Swoole without testing all dependencies for coroutine compatibility.
Code Examples
// Sequential HTTP requests — 10 * 1 second = 10 seconds total:
$results = [];
foreach ($urls as $url) {
$results[] = file_get_contents($url); // Blocks for each URL
}
// Total time: N * latency per request
// ReactPHP concurrent HTTP — all requests in parallel:
use React\Http\Browser;
use React\EventLoop\Loop;
$browser = new Browser();
$promises = [];
foreach ($urls as $url) {
$promises[] = $browser->get($url); // Non-blocking
}
// Wait for all to complete:
\React\Promise\all($promises)->then(function(array $responses) {
foreach ($responses as $response) {
echo $response->getBody();
}
});
Loop::run(); // Total time: ~1 * max(individual latencies)