When comparing PM2 vs Supervisor vs systemd, I would start with the failure you need to fix: a service that stays down after a reboot, a worker running old code or an application starting twice. Replacing a manager before reproducing the fault can add work without addressing its cause.
This guide covers process supervision. If a process restarts but repeats actions or loses tasks, use the guide to recovering bot work after a restart. That problem also involves application state and queue behavior.
Choose around the environment and the team
| Option | When I would consider it | What to verify first |
|---|---|---|
| PM2 | Node.js applications whose team benefits from its configuration and instance management. | Startup under the right user, a saved process list and application-aware shutdown. |
| Supervisor | PHP, Python or Node workers with an operating procedure the team already understands. | Foreground processes, restart behavior after normal exits and failures, and enough time to stop. |
| systemd | Services on a host already using it, maintained by a team familiar with service units and system logs. | User, environment, dependencies, restart policy and shutdown limits. |
| Platform supervisor | Managed hosting or containers where the platform already controls instances. | What the platform starts and which responsibility would justify another supervisor. |
I would not migrate a documented Supervisor setup just because I prefer another tool. Nor would I assume every Linux environment uses systemd. A change should address an observable problem and leave a setup the team can maintain.
A supervision chain with explicit responsibilities
systemd can start the PM2 service while PM2 manages its applications. The PM2 startup documentation describes this integration. A conflict arises when another unit independently starts the same application as well.
I would record the whole chain: host → manager → command → queue or port. Each layer needs a clear start, stop and recovery owner. In Laravel, Horizon and Supervisor own different responsibilities; managing queue work and supervising its process are separate jobs.
Node.js APIs and Laravel workers need different checks
An API needs to stop accepting connections and handle existing ones according to its shutdown policy. PM2 cluster mode distributes connections across Node.js processes. It does not automatically make concurrent queue consumers safe. A reload can fall back to a restart if it cannot complete.
Laravel workers keep code in memory. The Laravel 12.x queue documentation explains how queue:restart asks workers to exit after their current job, with a manager needed to start them again. Check the cache used for that signal and the restart policy for normal exits. Use the documentation for the installed version.
For connections using retry_after, the worker timeout must be shorter than that interval; SQS uses its visibility timeout. The process manager also has a shutdown timeout. These controls need to fit the job duration. The guide to Laravel queues in production develops the application side.
Acceptance tests for a supervision change
I would propose these checks in a controlled environment with test data. Record the release, configuration, result and owner for each one:
- Host startup: the expected number of processes returns with the correct user and environment, without an SSH session.
- Process failure: the agreed restart policy applies and the reason for the restart remains visible.
- Persistent failure: restarts follow the agreed policy, raise an alert and allow an operator to stop the service.
- Deployment during active work: shutdown respects the agreed limit and new processes load the expected release.
- Rollback: configuration and data remain compatible, as well as the previous code or binary being available.
- Functional result: a test request or task produces the expected outcome; a “running” status is insufficient.
For Supervisor I would review autorestart, stopsignal and stopwaitsecs against its configuration reference. For systemd, I would check Restart, RestartSec and TimeoutStopSec against the service unit reference. Values should follow measured behavior rather than a generic configuration example.
What to observe after deployment
Connect restart counts and release identifiers with queue age, errors and the last valid result. The guide to scoping logs, alerts and monitoring helps define who receives a signal and what they should investigate.
The Adslyfy case documents runs, workers, alerts and screenshots for investigating activity. It demonstrates operational visibility, not a benchmark of these managers or an availability guarantee.
What to include when commissioning a review
I would ask for the operating system and versions, process map, startup configuration without secrets, deployment procedure, recurring incidents and job durations. We would agree which processes to review, which tests to run and which changes remain outside the scope.
The handover can include the corrected map, versioned configuration, test evidence and recovery procedure. Effort depends on hosts, runtimes, environment differences and the ability to test an interruption. The guide to comparing software quotes helps separate diagnosis, implementation and maintenance.
Review the failure before replacing tools
Through my fractional CTO and infrastructure work, I can review these decisions with your team and scope the implementation. Ongoing incident response needs separately agreed coverage.
If restarts or deployments interrupt operations, tell me which process fails and what work remains unfinished. That gives us a concrete starting point for a review.