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.
$ apm run node server.js \-instances4-watch"*.js" \-serverhttp://0.0.0.0:3000Starting daemonWorker node started (4 instances)$ apm list NAME INST STATUS CPU MEM UPTIMEnode4/4running1.2% 48MB 2m 14s$ apm guiGUI 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.
ChannelsFire-and-forget broadcast & request/reply with first-reply-wins and configurable timeout.
StreamsPersistent bidirectional pipes with mediated star routing. Multi-peer attach, auto-cleanup on crash.
Cross-languageIdentical API across Node.js, Python, PHP, Perl, and Lua connectors. Zero extra dependencies.
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.
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.
Why APM
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.
MeasuredAPM vs PM2 on the same box, right nowAuthor'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.
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:
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.
Language agnostic
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.
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 \
-instances4 \
-serverhttp://0.0.0.0:3000
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.
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 CodeInstall it as an agent skill — persistent APM expertise loaded on every session.
Cursor & the restAttach SKILLS_apm.md to any chat, or drop it in your repo as project context.
Always currentWritten 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
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.