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.
Growth and reclamation
Two things on disk grow with use, and they are bounded differently.
Logs rotate on their own. Each service's active log is capped at 10 MB,
after which it rotates and at most 5 numbered backups are kept — roughly
60 MB per service, ceiling. Override per service with logs.max_bytes and
logs.max_files, or globally in
supervisor.xml.
sysg logs --prune trims rotated backups further by age or total size.
State does not shrink on its own. A project's state directory persists after
its services stop — that is what makes a project a durable namespace, and what
lets sysg status still tell you what happened. Stopping a project does not
reclaim it.
Info
For a workload that creates and destroys projects — one project per job, per tenant, per slot — pair the stop with a scoped purge:
$ sysg stop -p slot-42 # take the project's services down
$ sysg purge -p slot-42 # reclaim its state and its logspurge -p deletes that project's state directory and its log directory,
and nothing else. Without it, a churning workload accumulates one directory
per project it has ever run.
See also
purge- Clear all state- Projects - How one supervisor hosts many projects
- How It Works - Architecture overview