A process supervisor is a program that starts, monitors and restarts other processes according to declared rules, so that long-running services stay available without manual intervention. In servers, and specifically in the area of services and processes, the supervisor is the component that owns the lifecycle of a daemon or worker process: it launches the process, keeps its process ID, notices when it exits and decides what happens next.
Common examples include systemd on most current Linux distributions, the classic runit, s6 and daemontools family, supervisord for application-level programs, and the init process (PID 1) inside containers. They differ in scope and features, but all rely on the same core idea: a parent process that is notified when a child dies is better placed to restart it than any external polling script.
How a process supervisor keeps services running
A supervisor works by being the direct parent of the supervised process. When a child process exits, the operating system delivers a SIGCHLD signal to its parent, and the parent collects the exit status with a wait call. This makes detection immediate and reliable, unlike PID files, which can become stale or point to an unrelated process after a crash and a PID reuse.
After an exit, the supervisor applies a restart policy. It may restart always, only on failure, or never, and it usually inserts a delay between restarts to avoid tight crash loops. Many supervisors also enforce a start limit, for example a maximum number of restarts within a time window, after which the service is marked as failed and an operator must intervene.
The supervisor also controls the process environment: user and group, working directory, environment variables, resource limits, standard output and error handling. Because it captures output directly, it can forward logs to a journal or a log file without the program having to manage log files and rotation itself.
- The supervisor reads the service definition and prepares the environment.
- It forks and executes the program, keeping it in the foreground.
- It waits for readiness, using a notification, a socket or a simple delay.
- It watches for exit and applies the restart policy and backoff.
- On stop, it sends a termination signal, waits a grace period, then forces termination.
Key settings of a supervised service
Every supervisor exposes a similar set of policy parameters. The names differ between tools, but the concepts map closely, and the values chosen here decide whether a failing service recovers gracefully or floods the system with restarts. The table lists the settings that matter most in practice.
| Parameter | Typical values | What it controls |
|---|---|---|
| Restart policy | Always, on failure, never | Whether an exit triggers a new start |
| Restart delay | 100 ms to 10 s, often with backoff | Pause before the next start attempt |
| Start limit | 3 to 10 starts per 10 to 60 s | When repeated crashes mark the service failed |
| Stop timeout | 5 to 90 s | Grace period between SIGTERM and SIGKILL |
| Readiness signal | Notify message, open socket, fixed wait | When dependents may start |
| Resource limits | Open files, memory, CPU share | How much the process may consume |
The stop timeout deserves particular care. A web server or queue consumer needs enough time to finish in-flight work during a graceful restart, yet a value that is too long delays deployments and system shutdown. Matching the timeout to the longest realistic request or job is the usual rule.
Common process supervisors compared
Supervisors range from full init systems that manage the whole machine to small tools that manage a handful of application processes. The choice depends on whether the supervisor must also boot the system, track dependencies and manage logs, or only keep a few programs alive.
| Supervisor | Typical role | Notable characteristics |
|---|---|---|
| systemd | System init and service manager on Linux | Units, cgroups, socket activation, journal |
| runit and s6 | Lightweight init or service tree | Small code base, directory-based services |
| supervisord | Application processes under one parent | INI configuration, process groups, web interface |
| Container init | PID 1 inside a container | Reaps zombies and forwards signals |
| Language managers | Node.js or Python worker managers | Cluster mode, zero-downtime reloads |
In orchestrated environments the role is often split across layers. A container runtime and an orchestrator restart failed containers, while a minimal init inside the container only reaps zombie processes and forwards signals. Running a second full supervisor inside a container is usually a sign that the container holds more than one concern.
Process supervisor versus related concepts
A process supervisor is easily confused with the things it manages or with external monitoring. The distinction matters because each solves a different failure mode, and a robust server normally uses several of them together.
| Concept | Main responsibility | Relation to the supervisor |
|---|---|---|
| Daemon | Provides a long-running service | Is the process being supervised |
| Worker process | Executes requests or jobs | Often supervised by a master process |
| Process ID | Identifies a running process | Tracked by the supervisor as parent |
| External monitor | Checks service health from outside | Detects hangs the supervisor cannot see |
| Cron scheduler | Runs tasks at fixed times | Starts short jobs, does not keep them alive |
The most important limitation is that a supervisor sees process death, not process health. A program that deadlocks, stops accepting connections or returns errors while still running looks healthy to a plain supervisor. Some tools add watchdog keep-alive messages or health probes to close this gap, but external checks remain necessary.
Configuring supervision in practice
The program itself must cooperate with supervision. The key rule is that a supervised program stays in the foreground and does not fork into the background, because a self-daemonizing process detaches from its parent and leaves the supervisor watching the wrong PID. Most modern servers provide a foreground or no-daemon option for exactly this reason.
| Situation | Recommended choice | Reason |
|---|---|---|
| System service on Linux | Native systemd unit | Integrates with boot, logs and cgroups |
| Several app processes per host | One unit or program entry each | Independent restarts and limits |
| Single-process container | Minimal init as PID 1 | Correct signals and zombie reaping |
| Crash on bad configuration | Start limit with backoff | Prevents endless restart loops |
| Long-running jobs | Stop timeout above longest job | Allows clean shutdown |
- Run each service as a dedicated unprivileged user, not as root.
- Send logs to standard output and let the supervisor or journal store them.
- Use readiness notification when other services depend on this one.
- Alert on repeated restarts, because a silent restart loop hides a real fault.
Pitfalls and failure modes
The classic mistake is the double fork: a program started under a supervisor detaches itself, the supervisor sees an immediate exit and starts another copy, and soon several instances compete for the same port. A second frequent problem is a restart loop that hides a configuration error behind constant restarts and a growing log.
Inside containers, a program that is not written to act as PID 1 may ignore SIGTERM and leave zombie processes unreaped, which causes slow shutdowns and forced kills. Finally, a supervisor is itself a single point of failure on its host; it protects against process crashes, not against host or hardware failure, which requires redundancy at a higher level.
A plain-language summary
A process supervisor is like a shift manager who watches the staff. Each important program on a server is one worker. If a worker suddenly leaves, the manager notices at once and calls in a replacement, so the shop stays open.
The manager also follows rules. If the same worker walks out again and again within a minute, the manager stops calling replacements and raises an alarm, because something is clearly wrong. The key point is that a supervisor brings crashed programs back automatically, but it cannot tell whether a program that is still present is actually doing its job.
An example from practice
A small company runs an online shop on a Linux server with a web server, an application server and two background queue workers. Each program is defined as its own systemd service, running in the foreground under an unprivileged user, with restart on failure, a 2-second restart delay and a start limit of five attempts per minute. The queue workers have a stop timeout of 60 seconds, longer than their slowest job.
One night, a malformed message causes a queue worker to crash several times. The supervisor restarts it each time, and the other worker keeps processing orders. When the crash count passes the start limit, the service is marked as failed and monitoring sends an alert. An engineer removes the bad message the next morning and starts the service again. No orders were lost, and the outage stayed limited to one worker instead of the whole shop.