Advanced Process Manager
for Linux

Supervise any process in any language — Node.js, Python, Go, Rust, Ruby, PHP, or anything else that runs on Linux. Proxy HTTP/WS/TCP/UDP, rate-limit, and monitor everything from a single static binary.

Linux  ·  Any language  ·  Zero config to start

terminal
$ apm run node server.js \ -instances 4 -watch "*.js" \ -server http://0.0.0.0:3000 Starting daemon Worker node started (4 instances) $ apm list NAME INST STATUS CPU MEM UPTIME node 4/4 running 1.2% 48MB 2m 14s $ apm gui GUI started at http://127.0.0.1:6789
NEW in v2.0

Workers can finally talk to each other.

APM now ships with built-in inter-worker IPC — message channels and persistent bidirectional streams, routed through the daemon, across any language. No sockets to configure, no broker to run, no ports to open. A Node.js WebSocket worker can hand a live console stream to a Python background job; a PHP request can query a Go service and get the first reply back in milliseconds.

Channels Fire-and-forget broadcast & request/reply with first-reply-wins and configurable timeout.
Streams Persistent bidirectional pipes with mediated star routing. Multi-peer attach, auto-cleanup on crash.
Cross-language Identical API across Node.js, Python, PHP, Perl, and Lua connectors. Zero extra dependencies.
NEW in v2.1

Workers fail loudly, fail once, fail with a fix.

Meet augur — APM's startup-failure diagnostician. When a worker crashes during boot, augur classifies the error (Node, Python, Perl, PHP, Ruby, Java, Go, Bash) and scans the manifest + source to list every missing dependency in one go — not one painful restart at a time. Toggle augur_full_scan true on any worker to run the scan as a pre-flight check before fork.

One binary, full stack

No config files required to get started. Everything you need is built in.

Process Supervision
Start, stop, restart, and run multiple parallel instances. Automatic crash recovery with configurable restart delays and limits.
Reverse Proxy
Built-in HTTP, WebSocket, TCP and UDP proxy, on ports or Unix sockets. Round-robin load balancing across instances. Session migration on rolling restarts.
Vanguard Firewall
IP allowlists/blocklists, path banning, and per-IP rate limiting with token bucket. Auto-ban with configurable TTL. CDN IP lists included.
File Watcher
Monitor source files with glob-style name patterns and auto-restart workers on change. Per-worker ignore patterns and debounce delay.
Live GUI
Web dashboard at localhost:6789 with real-time CPU, memory, connection stats, and per-instance LED event indicators.
StatsD Metrics
Export worker metrics over UDP to Datadog, InfluxDB, Graphite, or any StatsD-compatible receiver. Per-worker configuration.
Built-in TLS
First-class TLS for all server types — HTTP, WebSocket, TCP. Bring your own certs. Mutual TLS (mTLS) support with CA verification.
Rolling Restarts
Restart instances one at a time with zero downtime. Configurable delay between instance cycles. Session state preserved across restarts.
Inter-Worker IPC new in v2.0
Message channels and persistent bidirectional streams between workers, across any language — Node.js, Python, PHP, Perl, Lua. Routed through the daemon. No sockets, no broker.
Augur Diagnostician new in v2.1
When a worker crashes during boot, augur classifies the language (Node, Python, Perl, PHP, Ruby, Java, Go, Bash) and lists every missing dependency in one line — manifest-first, AST-fallback. Optional pre-flight mode blocks the launch before fork.
Dead-Peer Detection new in v2.6
A device that vanishes without closing — power cut, cable pull — reaches the worker's onClose in seconds, not minutes. Kernel TCP keepalive + TCP_USER_TIMEOUT, no client support needed, slow links never cut.
Fleet Liveness new in v2.12
WebSocket pings that reach the device through nginx, a unix socket or Cloudflare: a vanished client is closed and reported in seconds, with no heartbeat code in the app. Policy per worker or per connection (setPing), round-trip latency kept per device (pingStats), pings only to silent connections.
Micro-Dedupe new in v2.7
The same GET arriving twice a millisecond apart is a network bounce, not two requests. APM forwards it once and answers both copies with the one response — the app never runs a handler twice for one tap.
Config Doctor new in v2.8
apm healconf checks a config and everything it includes, explains each problem and offers the fix: a missing ;, a key brought from PM2, a boolean the daemon reads as false, a setting a new version reads differently. Runs as you, backs up before it edits, and converts PM2 ecosystem files.
APM Network v2.2 · pre-release
The same IPC verbs across machines. Daemons sharing a license token form a private mesh through one persistent WebSocket; a worker tagged apm_network answers request() from any of them. No connector changes.
Limits, Health & Crash Hooks
memory_limit via cgroups v2 (OOM-kill, then your restart policy), pull or push health checks, connection drain, and an on_crash webhook with HMAC-signed payload and the last log lines.
Parallel Boot new in v2.4.1
Config loads start workers concurrently in dependency waves instead of one at a time — a 30-worker fleet boots in 13 s instead of 129 s. start_concurrency caps the width; depends_on is honoured whatever order the file declares.
Diff-Driven Reload
apm reload works out what actually changed and applies only that — log paths, watcher, Vanguard rules, listeners — without bouncing children. Only changes the process snapshots at start (exec, env, user, path) restart it.

Principles APM is built on

Small binary, small blast radius, small surprises. APM is the process manager most teams reach for when PM2 stops fitting the shape of their stack.

01

Zero-downtime rolling restarts

APM holds the listening socket and cycles instances behind it one at a time. A deploy finishes without a single user seeing a 502. No gateway in front, no blue/green orchestration — just restart. This is the piece teams most often wire up by hand on top of PM2 cluster mode; in APM it's how restarts work by default, for any language, not just Node.

02

High-performance Go core

The supervisor itself is a single statically-linked Go binary — 2.6 MB, no runtime, no npm tree. Goroutines and channels keep scheduling off your app's CPU, so a busy daemon doesn't steal cycles from your workers. Contrast this with Node-based managers where the supervisor competes with your app for the same event loop.

03

Built-in IPC — no Redis, no broker

Workers in any language talk to each other through the daemon: fire-and-forget channels, request/reply with first-reply-wins, and persistent bidirectional streams. A Node worker can hand a live console stream to a Python job; a PHP request can query a Go service and get a reply in milliseconds. You don't run Redis, you don't run RabbitMQ, you don't run a sidecar. The broker is the process manager you already have.

04

A file watcher that stays out of the way

One native inotify tree inside the daemon, per-worker glob include/exclude, debounced restarts. The "watcher eats my CPU" failure mode that plagues chokidar-based watchers — including PM2's --watch on large repos — does not happen here, because there is no chokidar, no polling, no per-worker watcher process.

05

Truly language-agnostic

If it runs on Linux and writes to stdout, APM can supervise it. No adapter. No "PM2 interpreter" wrapper script. Node, Python, Go, Rust, PHP-FPM workers, Bash pipelines, a compiled C++ daemon — all first-class citizens, all supervised identically, all with the same crash recovery, logs, metrics, and IPC.

06

One file to install, one file to back up

The binary goes to /usr/sbin/apm. Your config lives in /etc/apm/apm.conf. That's it — no ~/.pm2 directory full of JSON state that can corrupt, no dump.pm2 to port between hosts. Migrate a server by copying two files.

Measured APM vs PM2 on the same box, right now Author's production Linux server, kernel 5.4, x86_64. Both supervisors running live workloads — APM supervising 5 workers (Node + Go), PM2 supervising 2 (Node). Snapshot taken at build time; regenerate with ps -eo pid,rss,command.
16 MB
APM daemon RSS
vs 86 MB — PM2 God daemon
2.6 MB
APM on-disk binary
vs 26.3 MB / 5,086 files — PM2 npm install
10.8 MB
CLI invocation peak RSS
vs 68 MB — pm2 list
0
Runtime deps
vs Node.js + npm for PM2

APM vs PM2 — at a glance

PM2 is a great Node-first process manager. APM is what you reach for when your stack stops being Node-only, when you're tired of wiring nginx in front for rate limiting, or when you want cross-language IPC without running Redis. Here's the honest, feature-by-feature picture:

  APM v2.12.0 PM2 v5.x
Runtime Static Go binary — 2.6 MB, zero deps Node.js + npm package — 26 MB, 5,000+ files
Supervised languages Any executable — Node, Python, Go, Rust, PHP, Ruby, C/C++, Bash, Deno, Bun… Node-first; other languages need a wrapper interpreter script
Daemon footprint (idle) ~16 MB RSS supervising 5 workers ~86 MB RSS supervising 2 workers
Reverse proxy (HTTP/WS/TCP/UDP) Built in — round-robin, session migration on restart External — requires nginx or HAProxy
Rate limiting & firewall Built in (Vanguard): token bucket, IP banlists, CDN trust, path bans External — requires nginx, fail2ban, Cloudflare, or middleware
TLS termination Built in — HTTPS/WSS, mTLS, bring your own certs External — requires nginx or app-level
Cross-language IPC Channels + persistent streams, routed by daemon, identical API in Node/Python/PHP/Perl/Lua pm2.launchBus — Node-only, axon-based
File watcher Native inotify, per-worker glob patterns, debounced, one tree chokidar — historically CPU-heavy on large repos (issue history)
Zero-downtime rolling restart Default for any worker type with a shared listener Node cluster mode only (pm2 reload)
GUI / dashboard Local live GUI shipped in-binary at :6789 PM2+ SaaS (paid) or third-party dashboards
Config format apm.conf (nginx-style) or CLI flags ecosystem.config.js or CLI flags
Persistent state One config file. No hidden dump file. ~/.pm2/dump.pm2 + pm2 save / resurrect
Install curl … | bash — one file to /usr/sbin/apm npm i -g pm2 — requires Node.js + npm already installed
License Free to use (binary); source proprietary AGPL-3.0 (core); PM2+ is a paid SaaS
Is APM a drop-in PM2 replacement?

For supervising Node apps in fork mode — effectively yes. You'll re-express your ecosystem.config.js as an apm.conf block (5–10 lines per worker), install the one binary, and run. For PM2 cluster mode specifically, APM's -server flag is the equivalent: APM holds the listener and round-robins connections to instances in any language, not only Node. Features you will not find in APM: PM2+ SaaS, pre-packaged ecosystem modules (pm2-logrotate, etc.) — APM ships rotation and metrics as core, so most of those are simply obviated.

How do I convert a PM2 ecosystem file to an APM config?

Run apm convert ecosystem.config.js out.conf. APM evaluates the JavaScript ecosystem (using your local node — same one PM2 uses), or reads JSON directly (ecosystem.json), and emits one APM worker { } block per apps[] entry. Fields that have direct equivalents — name, script, cwd, instances, watch, env, max_memory_restart, log_date_format, kill_timeout, and the rest — convert silently. Anything that doesn't map cleanly (PM2 cluster mode, cron_restart, instances: 'max', multi-profile env_production / env_staging) surfaces as an inline # WARN: comment above the block it applies to, so you can review and decide. The converter is intentionally a starting point, not a behaviour-bit-for-bit clone — review the output, then cat it into your main apm.conf and apm reload.

Any language. Any runtime. One manager.

APM doesn't care what stack you use. If it compiles, interprets, or just runs on Linux — APM can start it, supervise it, proxy it, and restart it when it crashes. No plugins. No adapters. No wrapper scripts.

Node.js Python Go Rust Ruby PHP Java Elixir C / C++ Bash Deno Bun + anything else

If your app runs on Linux and talks to stdout — APM has you covered.

Up and running in seconds

1 — Install

One line. Detects your arch, downloads the right binary, asks for sudo only when it needs to copy itself to /usr/sbin/apm.

$ curl -fsSL https://processmanager.dev/install.sh | bash
wget alternative
$ wget -qO- https://processmanager.dev/install.sh | bash

Prefer to inspect first? Download manually →

Already running APM? sudo apm upgrade installs the new version and then checks your config with apm healconf. Since v2.8 a root-owned path needs a user and the CLI needs root or group apm. Since v2.11 the web GUI always asks for a password — with no gui_password set, a generated one is printed in the daemon log and by apm gui — and a listener behind a proxy can name its trusted_proxies so forwarded client IPs are only believed from them.

2 — Start a process

# Simple start
$ apm run node server.js

# With proxy + multi-instance
$ apm run node server.js \
    -instances 4 \
    -server http://0.0.0.0:3000

3 — Config file

# /etc/apm/apm.conf
worker {
    name       myapp;
    exec       node;
    params     server.js;
    instances  4;
    restart    true;
    watch      *.js;
    server     http://0.0.0.0:3000;
}

4 — Load & manage

$ apm load /etc/apm/apm.conf
$ apm list
$ apm restart myapp
$ apm reload /etc/apm/apm.conf
$ apm monitor
$ apm gui
$ apm stop myapp

Get APM v2.12.0

Linux static binaries — copy, chmod +x, run. All releases →

Windows Defender false positive — Microsoft Defender may flag APM binaries as Wacatac.B!ml. This is a known false positive: its ML heuristic misfires on statically compiled Go binaries and UPX-compressed executables. It has been reported to Microsoft for review. All other major antivirus engines report these files as clean — see the VirusTotal links below for full scan results.
Linux
x86_64 / amd64
apm-v2.12.0-x64 standard 9.1 MB
SHA-256: e3fd4a464c71b020a8e913d469dc3f620c2c855b77b670173ab30bfab95cc549 VirusTotal (pending)
apm-v2.12.0-x64-upx UPX 2.8 MB
SHA-256: 14a87b79d2f146a2cbbaa7ea0e402940d04a5d8d83721883a6a024f731d0abdd VirusTotal (pending)
Linux
ARM64 / aarch64
apm-v2.12.0-arm64 standard 8.4 MB
SHA-256: 24ed1bf2f679e39e712eb0b254b66f3eead71eeb7469a63abfe81e0a7ae0d68a VirusTotal (pending)
apm-v2.12.0-arm64-upx UPX 2.4 MB
SHA-256: edaa4ca51e5a6b2231c5de1ed36bbf723881095e3eae9343412eea563ddc028f VirusTotal (pending)
Linux
ARMv7 / armhf
apm-v2.12.0-armhf standard 8.8 MB
SHA-256: ae55d78bf5498087f07829396438dc7f84f070e9f2ddb74b22bb7c3d912971f8 VirusTotal (pending)
apm-v2.12.0-armhf-upx UPX 2.4 MB
SHA-256: 810a13be8d58832612eb41f6ae584c4e9907956cbc7effa62715505d40f11f01 VirusTotal (pending)
For your AI

Download APM skills for your AI.

Hand your coding assistant a single Markdown file and it knows APM end to end — every apm command, the full config syntax, the Vanguard firewall, native TLS, the file watcher, rolling restarts, inter-worker IPC, and the connector API for all five languages. No outdated guesses, no hallucinated flags.

Claude Code Install it as an agent skill — persistent APM expertise loaded on every session.
Cursor & the rest Attach SKILLS_apm.md to any chat, or drop it in your repo as project context.
Always current Written for v2.12.0 and updated with every release — your AI never falls behind.
# Install as a Claude Code skill
$ mkdir -p ~/.claude/skills/apm && curl -fsSL https://processmanager.dev/SKILLS_apm.md \
       -o ~/.claude/skills/apm/SKILL.md
Questions & Feature Requests
Join the Discord to ask questions, report issues, or suggest new features. Responses may take a little while — this is a one-person project and I can't be online all day, but I do read everything.
Join Discord
As seen on