Supervisor

A battle-tested client/server system for monitoring and auto-restarting UNIX processes.

Tool
PyPI
v4.3.0
9,107stars
BSD-derived (Repoze Public License)

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
47/100Fair
Development Activity0
Maintenance0
Community88
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
76/100Good
Architecture78
Code Quality75
Innovation65
Learning Curve85

Supervisor is a client/server system that lets you monitor and control a number of processes on UNIX-like operating systems. Instead of writing per-service init scripts or systemd units, you declare each program in a simple INI-style configuration file and let supervisord manage starting, stopping, and automatically restarting it on unexpected exit.

Administrators interact with the running daemon through supervisorctl (a CLI), an XML-RPC API, or a bundled web UI, all backed by the same event system that plugins and third-party tools use to react to process state changes in real time.

What You Get

  • supervisord daemon that starts, stops, and auto-restarts configured processes
  • supervisorctl command-line client for interactive process control
  • XML-RPC API for scripting supervisord from other tools and languages
  • Event notification system third-party plugins hook into for custom automation
  • Optional web UI for viewing and controlling processes from a browser

Common Use Cases

  • Keeping a Django/Flask/Celery worker alive on a VM without systemd
  • Supervising multiple long-running scripts inside a single Docker container
  • Centralizing stdout/stderr log capture for processes that don’t daemonize themselves
  • Coordinating startup/shutdown priority across a handful of interdependent services

Under The Hood

Architecture Supervisor’s runtime is organized around a single-threaded asyncore event loop driven by supervisord.py’s Supervisor class, which owns a map of ProcessGroup objects and repeatedly polls a bundled fork of asyncore (supervisor/medusa/asyncore_25.py) to multiplex I/O across every child process’s stdout/stderr pipes. Each managed program is represented by a Subprocess instance in process.py (a ~1000-line state machine driven by the ProcessStates enum in states.py) that owns fork/exec, signal delivery, and backoff/retry timing, while dispatchers.py’s PDispatcher subclasses read pipe output and translate it into ProcessLogStdoutEvent/ProcessLogStderrEvent notifications via the pub/sub bus in events.py. Two client surfaces sit on top of this core: supervisorctl.py (a Cmd-based interactive/CLI shell) and rpcinterface.py plus xmlrpc.py, which expose the identical control surface as an XML-RPC API served by http.py/web.py — meaning the CLI, XML-RPC clients, and the bundled browser UI all funnel through the same SupervisorNamespaceRPCInterface rather than duplicating control logic.

Tech Stack The project is pure Python (97% per GitHub’s language breakdown) with zero required third-party runtime dependencies on Python 3.8+ (setuptools is only pulled in as a compatibility shim on Python <3.8, per setup.py), and it vendors its own event-loop and HTTP layer (the supervisor/medusa package) rather than depending on asyncio, Twisted, or an external WSGI server — a deliberate choice given the project predates modern async Python and still targets Python 2.7 alongside 3.4+. Packaging is classic setuptools (setup.py + setup.cfg, no pyproject.toml/poetry), installed as four console_scripts entry points (supervisord, supervisorctl, echo_supervisord_conf, pidproxy), and configuration is parsed with the stdlib configparser into an INI-style format rather than YAML/TOML/JSON.

Code Quality Supervisor ships a substantial test suite — 23 files under supervisor/tests/ (test_process.py alone defines 124+ test functions), covering the process state machine, dispatchers, options parsing, the XML-RPC interface, and an end-to-end test — run via tox.ini across multiple Python versions. The codebase predates modern typing conventions: there are effectively no type hints or dataclasses, favoring plain classes with docstring-documented instance attributes (e.g. Subprocess in process.py) and manual as_string/as_bytes/PY2 shims in compat.py to keep Python 2 and 3 behavior unified. Error handling is explicit and defensive throughout (options.py alone is 2,257 lines, much of it validation and BadCommand/NotExecutable/NotFound exception paths for malformed configs), reflecting its role as system-level daemon code where silent failures are unacceptable.

API Design Getting started requires only a single INI config file and running supervisord -c <file>; the entry-point split (supervisord for the daemon, supervisorctl for interaction, echo_supervisord_conf for scaffolding a starter config) keeps each concern separate and self-documenting via —help. The XML-RPC surface (documented in docs/api.rst and docs/xmlrpc.rst) mirrors supervisorctl’s command set almost 1:1, so anything doable interactively is scriptable without learning a second vocabulary, and the event-listener protocol (docs/events.rst) gives a documented extension point for third-party automation without forking the daemon. The tradeoff is an old-school, string-keyed configuration format and an XML-RPC API rather than REST/JSON, which reads as dated next to modern process managers but has stayed stable for over a decade — the docs (installing.rst, configuration.rst, running.rst, faq.rst, and others) are thorough and the API is well-specified, even if the transport itself is less fashionable.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search