Fundamentals 8 min read

Understanding Zombie and Orphan Processes in Unix/Linux and Their Impact on PHP‑FPM

This article explains the concepts of zombie and orphan processes in Unix/Linux, analyzes a real‑world PHP‑FPM incident where thousands of zombie processes exhausted system resources, and presents diagnostic steps, testing procedures, and preventive coding practices to avoid such issues.

Baidu Waimai Technology Team
Baidu Waimai Technology Team
Baidu Waimai Technology Team
Understanding Zombie and Orphan Processes in Unix/Linux and Their Impact on PHP‑FPM

Abstract In Unix programming there are two special process states—zombie and orphan. Zombies retain their process descriptors, consuming PID resources and potentially causing denial‑of‑service when all PIDs are exhausted. The article investigates the causes of zombie processes and how to prevent them.

Background After upgrading to PHP 7, an online monitoring alarm showed more than 30,000 zombie processes, preventing SSH access while the PHP service remained functional. The command used to list zombies was ps -ef|grep defunct.

Zombie and Orphan Processes An orphan process occurs when its parent exits; the init process (PID 1) adopts it. A zombie occurs when a child exits but its parent does not call wait() or waitpid(), leaving the process descriptor in the system.

Problem Identification Using ps -ef|grep 20309 the team discovered that the zombie processes were children of a PHP‑FPM CGI program. Further tracing showed that four PHP‑FPM workers (PIDs 20303, 20304, 20305, 20309) were the sources.

proc_open‑Induced Fault The root cause was a fork in a PHP library that invoked a binary via proc_open. Because the parent did not call proc_close(), the child’s exit status was never collected, creating zombies. The PHP manual’s description of proc_close was referenced.

Testing A test script ( test.php) was executed under load with ab -k -c 200 -n 10000 "http://localhost:8099/test/test.php". The load generated 7,839 zombie processes, all traced back to the four workers. Killing a worker reduced the zombie count proportionally, confirming the hypothesis.

Configuration Changes The default PHP‑FPM "ondemand" mode kills idle workers after 10 seconds, causing the parent to exit and the zombies to be adopted by init. Switching to "static" mode with four workers and a request limit of 10,000 allowed observation of zombie creation and removal.

Why Zombies Disappear Zombies disappear either when the parent processes the SIGCHLD signal and calls wait(), or when the parent itself exits, allowing init to reap the orphaned zombies.

Solution The primary fix is to modify the code to use proc_close() correctly, ensuring the parent reaps child resources. Additionally, the binary call was replaced with pure PHP logic to avoid the performance penalty of forked processes.

Prevention Recommended practices include handling SIGCHLD in the parent, double‑forking to detach children, or deliberately terminating the parent after child exit. Using pclose() for popen handles, and verifying that exec or system do not leave zombies, are also advised.

Thoughts Developers should consult official documentation, understand return values and edge cases, and write robust code that explicitly manages child process termination.

Process ManagementPHPUnixSystem Administrationzombie processes
Baidu Waimai Technology Team
Written by

Baidu Waimai Technology Team

The Baidu Waimai Technology Team supports and drives the company's business growth. This account provides a platform for engineers to communicate, share, and learn. Follow us for team updates, top technical articles, and internal/external open courses.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.