Process ID

On this page 6

A process ID (PID) is the unique positive integer that the operating system kernel assigns to each running process, and it is the handle through which administrators and tools signal, inspect, limit and terminate that process. In the management of services and processes on servers, the PID connects a running program to monitoring data, log entries, resource limits and supervisor decisions.

A PID is unique only while the process exists. After a process exits and its parent collects the exit status, the number returns to the pool and can be reused for a completely unrelated program, which is the source of several classic operational mistakes.

How the kernel assigns and releases a process ID

The kernel assigns a PID at process creation, typically during fork() or clone() on Linux and Unix systems. Linux hands out numbers in ascending order from the last assigned value and wraps around to low numbers when it reaches the configured maximum, skipping values that are still in use.

A process keeps its PID until it exits and its parent reaps it with wait() or waitpid(). Between exit and reaping, the process is a zombie: it uses no CPU or memory beyond a small kernel entry, but it still occupies its PID. A parent that never reaps its children can therefore exhaust the PID space even though nothing is actually running.

Other platforms follow the same idea with different details. Windows assigns process IDs that are multiples of four and reuses them quickly, while FreeBSD can randomize PID assignment to make values harder to predict. On every platform the rule is the same: a PID identifies a process only for its lifetime, and the maximum value is a configurable kernel limit rather than a fixed property of the system.

The table below lists the special and boundary values that every server operator encounters.

Value or limitMeaningPractical consequence
PID 0Kernel idle or swapper taskNever visible as a normal user process
PID 1Init system, often systemdAdopts orphaned processes and must not die
PID 2kthreadd on LinuxParent of kernel threads
Default pid_max32768 on older systemsCan be exhausted on busy hosts
Maximum pid_max4194304 on 64-bit LinuxCommon modern default on large systems
Notable process ID values on Linux

A PID rarely travels alone. The kernel tracks a family of identifiers that describe where a process belongs, who started it and which group receives signals together. Knowing them is essential when tracing a misbehaving daemon or worker process.

IdentifierWhat it identifiesTypical use
PPIDThe parent processTracing which service spawned a worker
PGIDThe process groupSending one signal to a pipeline or job
SIDThe sessionDetaching daemons from a terminal
TIDAn individual threadProfiling a single busy thread
TGIDThe thread groupThe value user tools report as the PID
Identifiers associated with a process

On Linux, threads are scheduled entities with their own thread IDs, and the PID shown by ps is actually the thread group ID. Inside a container, a separate PID namespace gives the main application PID 1 while the host sees a different, higher number for the same process.

Working with process IDs in server operations

Administrators use PIDs every day to send signals, read process state and apply limits. Most tools accept a PID directly, and modern service managers expose the main PID of each service so that it does not need to be looked up by name.

TaskTypical command or interfaceWhat the PID provides
Graceful reloadkill -HUP PIDTarget of the reload signal
Inspect state/proc/PID/statusMemory, threads, state and limits
List open fileslsof -p PIDFile and socket handles
Find the main service processsystemctl show -p MainPIDAuthoritative PID from the supervisor
Profile CPU usetop -p PID or perf -pScope of measurement
Common tasks that rely on a process ID

A PID file is a small file, often under /run, in which a daemon writes its own PID so that scripts can find it later. Under a process supervisor such as systemd, PID files are largely unnecessary because the supervisor tracks the process itself through control groups, which also catch children that change their PID by forking.

Pitfalls of relying on process IDs

The biggest risk is PID reuse. A script that reads a stale PID file and sends SIGKILL to that number may terminate an unrelated process that received the recycled ID. The danger grows on busy hosts where the PID counter wraps quickly.

SymptomLikely causeFix
Wrong process killedStale PID file after a crashUse the supervisor or verify the process name
Cannot fork new processesPID space or pids.max limit exhaustedReap zombies, raise limits, fix the leak
Growing zombie countParent does not call wait()Fix the parent or use a proper init in containers
Signals ignored in a containerApplication runs as PID 1 without handlersAdd signal handling or a minimal init process
Process ID problems and their fixes

Linux addresses reuse races with the pidfd interface, a file descriptor that refers to one specific process and remains valid even after the number is recycled. Tools that hold a pidfd can signal the intended process safely, which is why newer supervisors and libraries adopt it.

Limits also matter in shared environments. The cgroup setting pids.max caps how many processes and threads a service or container may create, which protects the host against fork bombs and runaway worker pools. Setting it too low, however, makes legitimate thread-heavy applications fail with resource errors that look unrelated to process counts.

In everyday language

A process ID is like a ticket number at a service counter. Every program that starts on a server gets a number, and anyone who needs to talk to that program, stop it or check on it uses the number to find it.

When the program finishes, its number goes back into the pile and may later be given to someone else. That is why an old number is not proof of who holds it now, and careful tools always check before acting.

Seen in the real world

An operations team runs a web server whose deployment script once stopped the service by reading /run/app.pid and sending a kill signal to the number inside. After an unexpected crash, the file still held an old number, and on the next deployment the script terminated the backup agent, which had received the recycled PID.

The team moves the service under systemd, removes the PID file and stops the service with systemctl stop, which uses control groups rather than a stored number. The script now asks systemd for the main PID only for diagnostics, and the accidental terminations stop entirely.