Database Operations
Back up, inspect, and clean up AGH's SQLite databases.
- Audience
- Operators running durable agent work
- Focus
- Operations guidance shaped for scanability, day-two clarity, and operator context.
Use this guide when you need to back up AGH state, inspect stored sessions, or retire old session directories.
Find the databases
Set the home path used by the commands below:
export AGH_HOME="${AGH_HOME:-$HOME/.agh}"| Path | Purpose |
|---|---|
$AGH_HOME/agh.db | Global catalog for workspaces, sessions, event summaries, token totals, permission logs, automation, bridges, extensions, tasks, tool process checkpoints, and network audit records. |
$AGH_HOME/sessions/<session-id>/events.db | Full event store for one AGH session. |
$AGH_HOME/sessions/<session-id>/meta.json | Session metadata used for listing, status, resume, and boot reconciliation. |
The global database is an index and catalog. The per-session events.db files hold the detailed
session timeline.
Rendering diagram...
Back up while the daemon is stopped
Use this for scheduled maintenance windows and before upgrades:
export AGH_HOME="${AGH_HOME:-$HOME/.agh}"
backup="$HOME/agh-backups/$(date +%Y%m%d-%H%M%S)"
agh daemon stop
mkdir -p "$backup"
cp -a "$AGH_HOME"/agh.db* "$backup"/
cp -a "$AGH_HOME/sessions" "$backup"/sessions
agh daemon startThis captures the global database, any WAL sidecars, every per-session event database, and each session metadata file.
Back up a live daemon with SQLite
Use SQLite's backup command when you cannot stop the daemon:
export AGH_HOME="${AGH_HOME:-$HOME/.agh}"
backup="$HOME/agh-backups/$(date +%Y%m%d-%H%M%S)"
mkdir -p "$backup/sessions"
sqlite3 "$AGH_HOME/agh.db" ".backup '$backup/agh.db'"
find "$AGH_HOME/sessions" -mindepth 2 -maxdepth 2 -name events.db -type f -print0 |
while IFS= read -r -d '' db; do
session_dir="$(basename "$(dirname "$db")")"
mkdir -p "$backup/sessions/$session_dir"
sqlite3 "$db" ".backup '$backup/sessions/$session_dir/events.db'"
cp -a "$(dirname "$db")/meta.json" "$backup/sessions/$session_dir/meta.json"
doneThis reads each database through SQLite instead of copying the main file without its WAL state.
Inspect the global catalog
Open the global database directly:
sqlite3 "$AGH_HOME/agh.db"List recent sessions:
select id, name, agent_name, state, stop_reason, updated_at
from sessions
order by updated_at desc
limit 20;List registered workspaces:
select id, root_dir, name, updated_at
from workspaces
order by updated_at desc;List active tool process checkpoints:
select id, source, session_id, turn_id, pid, state, updated_at
from tool_processes
where state in ('running', 'interrupting')
order by updated_at desc;The global catalog records summaries and indexes. Use the session event database when you need the ordered event stream for one session.
Inspect a session event database
Set the session ID and query its event store:
session_id="sess_1234"
sqlite3 "$AGH_HOME/sessions/$session_id/events.db"Show recent events:
select sequence, type, agent_name, timestamp
from events
order by sequence desc
limit 20;Show token usage:
select turn_id, total_tokens, cost_amount, cost_currency, timestamp
from token_usage
order by timestamp desc
limit 20;Show hook runs:
select hook_name, event, outcome, required, recorded_at
from hook_runs
order by recorded_at desc
limit 20;Clean up old session directories
AGH does not currently expose a prune command for old session directories. Use a conservative archive flow instead of deleting files in place.
-
List stopped sessions:
agh session list --all -
Stop the daemon:
agh daemon stop -
Back up
AGH_HOMEusing the cold backup procedure above. -
Move the old stopped session directory into an archive location:
export AGH_HOME="${AGH_HOME:-$HOME/.agh}" session_id="sess_1234" mkdir -p "$AGH_HOME/session-archive" mv "$AGH_HOME/sessions/$session_id" "$AGH_HOME/session-archive/$session_id" -
Start the daemon and confirm current sessions still list correctly:
agh daemon start agh session list --all
At boot, AGH reconciles the global catalog with the session directories on disk. Sessions missing
from disk are marked orphaned in the global catalog; AGH does not physically purge the global
session row.
Handle corrupt database files
When AGH opens a SQLite database and sees a recoverable corruption marker, it moves the database and
its -wal and -shm sidecars to files ending in .corrupt.<timestamp>, then retries opening a
fresh database once.
If this happens:
- Preserve the
.corrupt.<timestamp>files. - Stop the daemon.
- Restore the affected database from the latest known-good backup.
- Start the daemon and run
agh observe health.
The .corrupt.<timestamp> files are evidence for diagnosis. They are not a backup strategy.
Related pages
- Daemon Operations covers the runtime files that point to these databases.
- Session Events explains the session event stream stored in
events.db. - File Locations lists the full
AGH_HOMElayout.