DEV Community

Cover image for Parallel Processing with PHP: why, how, and when
Roberto B.
Roberto B.

Posted on • Edited on

25 1

Parallel Processing with PHP: why, how, and when

When we think of PHP, we typically imagine synchronous, single-threaded code that handles one task at a time.

But PHP is more versatile than it's often credited for. Thanks to the process control (pcntl) support, PHP can manage parallelism through process forking, a concept native to Unix-like operating systems.

Since process control support is common on UNIX systems, it is also compatible with Unix-like operating systems such as Linux and macOS.

What is multiprocessing, and why should you care?

Multiprocessing allows you to perform multiple operations at the same time. This is especially useful when:

  • You’re running CPU-intensive tasks that can be parallelized.
  • You need to handle multiple background jobs in parallel.
  • You want to reduce execution time by dividing a task among several processes.
  • You're writing command-line PHP scripts where performance and responsiveness matter.

When writing CLI scripts (like a command-line tool), especially for background tasks, daemons, or workers, using pcntl_fork() is a powerful technique.

Introducing pcntl_fork(): creating parallel processes in PHP

The pcntl_fork() function allows your PHP script to clone itself, creating a child process that runs parallel to the parent. This technique comes straight from the Unix world and opens the door to real multiprocessing in PHP.

Here’s a simple example that demonstrates the basic usage of pcntl_fork():

<?php

// Fork the process
$pid = pcntl_fork();

if ($pid == -1) {
    // Fork failed
    exit("Could not fork process.\n");
} elseif ($pid > 0) {
    // Parent process
    echo '<PARENT> Parent process. PID: ' . getmypid() . "\n";
    echo "<PARENT> Created child with PID: $pid\n";

} else {
    // Child process
    echo '<CHILD>  Child process. PID: ' . getmypid() . "\n";
    sleep(1); // Simulate work
    echo "<CHILD>  Child process done.\n";
    exit(0);
}

// Wait for child to exit
pcntl_waitpid($pid, $status);
echo "<PARENT> Child {$pid} has finished with status {$status}.\n";
if (pcntl_wifexited($status)) {
    echo "<PARENT> The child status code represents a normal exit.\n";
    echo '<PARENT> The child returned the code: ' . pcntl_wexitstatus($status) . "\n";
}
if (pcntl_wifsignaled($status)) {
    echo "<PARENT> The child status exit because a siginal.\n";
    echo '<PARENT> The child was terminated by signal code: ' . pcntl_wtermsig($status) . "\n";
}

Enter fullscreen mode Exit fullscreen mode

What’s happening here?

  • The script forks itself.
  • Both the parent and child processes continue running independently.
  • The child process executes its logic and exits.
  • The parent process waits for the child to terminate and analyzes the exit status.

This example gives you full control and visibility into how a child process behaves and how the parent can monitor or manage it.

Step-by-step explanation

$pid = pcntl_fork();
Enter fullscreen mode Exit fullscreen mode

The pcntl_fork() function tells the OS: "Create a clone of me to work in parallel.".

After the pctnl_fork, two processes run the same code. One process is the parent process, and the second one is the child process.

If pcntl_fork returns:

  • -1, the clone failed.
  • 0, you’re inside the child process.
  • A positive PID means you’re still the parent, and you just got the child’s ID.

if ($pid == -1) {
    exit("Could not fork process.\n");
}
Enter fullscreen mode Exit fullscreen mode

The forking operation failed. The process exits early.


elseif ($pid > 0) {
    echo '<PARENT> Parent process. PID: ' . getmypid() . "\n";
    echo "<PARENT> Created child with PID: $pid\n";
}
Enter fullscreen mode Exit fullscreen mode

You’re the parent process.
You print your own PID and the ID of the new child (returned by the fork function).


else {
    echo '<CHILD>  Child process. PID: ' . getmypid() . "\n";
    sleep(1); // Simulate work
    echo "<CHILD>  Child process done.\n";
    exit(0);
}
Enter fullscreen mode Exit fullscreen mode

You’re the child process!
This part is only executed by the child process.
The child sleeps for 1 second (like performing a specific task), prints messages, then exits.

exit(0) is important. It ensures the child doesn’t accidentally run code meant only for the parent.


pcntl_waitpid($pid, $status);
Enter fullscreen mode Exit fullscreen mode

The parent process waits for the child process to finish.
This line tells the parent to pause and wait until the specific child process (by $pid) completes.


echo "<PARENT> Child {$pid} has finished with status {$status}.\n";
Enter fullscreen mode Exit fullscreen mode

Once the child process finishes, the parent process is notified with a status code. We need to inspect the status code to understand why the child terminated the execution (e.g., whether it completed the task correctly, exited with an error, or was interrupted by a signal from the operating system).


if (pcntl_wifexited($status)) {
    echo "<PARENT> The child status code represents a normal exit.\n";
    echo '<PARENT> The child returned the code: ' . pcntl_wexitstatus($status) . "\n";
}
Enter fullscreen mode Exit fullscreen mode

Check if the child exited normally.
If so, we print the return code (0 if they completed successfully).


if (pcntl_wifsignaled($status)) {
    echo "<PARENT> The child status exit because a signal.\n";
    echo '<PARENT> The child was terminated by signal code: ' . pcntl_wtermsig($status) . "\n";
}
Enter fullscreen mode Exit fullscreen mode

Or maybe the child was interrupted.
This happens if a signal killed the process (e.g., SIGKILL, SIGTERM).

Code summary

Role Code Block Description
Parent $pid > 0 The parent creates and supervises the task execution.
Child $pid == 0 Child process does the task and exits.
Wait pcntl_waitpid() The parent process waits for the child process to finish.
Status Check pcntl_wifexited(), pcntl_wifsignaled() The parent process checks if the child process finished properly.

When and why to use forking in PHP

You might use pcntl_fork() in CLI scripts when:

  • You want to handle multiple tasks at once, like downloading files, processing queues, or running background jobs.
  • You’re writing a daemon or worker system that needs to scale and manage parallel tasks efficiently.
  • You want to reduce waiting time by handling independent tasks simultaneously.

What's next?

In PHP, once a child process is running a task, it often needs to send information back to the parent process.

The second part "Parallel Processing with PHP (Part 2): Inter-Process Communication" will explain how to build a communication channel between parent and child processes.

📘 This is Part 1 of the “Parallel Processing in PHP” series.

Continue to Part 2: Inter-Process Communication →

Skip to Part 3: Multiplexed Communication with stream_select()

Heroku

Deploy with ease. Manage efficiently. Scale faster.

Leave the infrastructure headaches to us, while you focus on pushing boundaries, realizing your vision, and making a lasting impression on your users.

Get Started

Top comments (4)

Collapse
 
hschimpf profile image
Hermann D. Schimpf

What do you think about the ext-parallel ? I've using it for more than 4 years now.
I also build an wrapper around it to enhance the developer experience: github.com/hschimpf/parallel-sdk

Collapse
 
robertobutti profile image
Roberto B.

hi @hschimpf I have in my todo list writing a post about the parallel extension. I think it is great, and taking a look at your package, looks like it solves some common and typical use cases. Amazing!!! Thank you for the suggestion!

Collapse
 
razielrodrigues profile image
Raziel Rodrigues

Nice brooo

ACI image

ACI.dev: Fully Open-source AI Agent Tool-Use Infra (Composio Alternative)

100% open-source tool-use platform (backend, dev portal, integration library, SDK/MCP) that connects your AI agents to 600+ tools with multi-tenant auth, granular permissions, and access through direct function calling or a unified MCP server.

Check out our GitHub!