How It Works
State
Runtime files systemg uses to track services.
Location
~/.local/share/systemg/ (user mode)
/var/lib/systemg/ (system mode with --sys)
Structure
Supervisor-wide files live at the root. Everything a project persists —
its PID map, service state, and cron history — is nested under its own
directory, keyed by project.id:
~/.local/share/systemg/
├── sysg.pid # Supervisor PID
├── control.sock # Unix socket for IPC
├── config_hint # Last config path
├── supervisor.xml # Supervisor-wide operator defaults
├── logs/
│ ├── supervisor.log # Supervisor events
│ ├── arbitration/ # Project-isolated service output
│ │ └── api.log
│ └── gamecast/
│ └── worker.log
└── projects/
├── arbitration/ # one directory per project.id
│ ├── pid.xml # Service → PID mapping
│ ├── state.xml # Service metadata
│ └── cron_state.xml # Cron run history
├── gamecast/
│ ├── pid.xml
│ ├── state.xml
│ └── cron_state.xml
└── __loose__/ # project-less (top-level `services:`) bundle
├── pid.xml
├── state.xml
└── cron_state.xml
All XML artifacts are written as nested, two-space-indented documents. Compact XML written by older releases remains readable.
Info
Each project owns its directory. A project's monitor, PID map, and state file
only ever touch projects/{project.id}/ — so two projects that both declare a
service named worker keep entirely separate records, and one project's
status can never leak into another's. Isolation is structural, not a
convention we remember to honour.
Services declared at the top level of a manifest — with no project — persist
under projects/__loose__/. See Projects for how
loose services and named projects coexist in one supervisor.
Key files
pid.xml
Maps a project's services to process IDs:
<PidFile>
<services>
<name>web</name>
<pid>67235</pid>
</services>
<services>
<name>db</name>
<pid>67236</pid>
</services>
</PidFile>
config_hint
Stores the last config path for commands that need a config-backed project
context. sysg status does not require this hint when a supervisor is running;
it asks the supervisor for the aggregate status view.
state.xml
Tracks service status, restart counts, and exit codes — keyed by service configuration hash, scoped to the project directory.
cron_state.xml
Per-project cron run history. Each project's scheduled jobs persist here; a shared scheduler loop routes every run to its own project's file.
Persistence
State survives supervisor restarts. A supervisor crash may leave service processes alive, but they are unsupervised until systemg recovers ownership; they cannot restart or enforce dependencies while no supervisor is running.
Clean shutdown removes sysg.pid, control.sock, and config_hint. Stale files after crash? Run sysg purge.
Warning
Upgrading from v0.54.x or older requires sysg purge first. The per-project
projects/{project.id}/ layout replaces the older flat pid.xml /
state.xml / cron_state.xml that lived directly under the state directory.
There is no automatic migration of the old flat files — stop your services,
run sysg purge, then start on the new release.
See also
purge- Clear all state- Projects - How one supervisor hosts many projects
- How It Works - Architecture overview