Skip to main content

Daemon overview

The daemon is OpenUsage's runtime. It is a small background service that continuously collects usage data from AI providers and tool integrations, persists it to SQLite, and serves a unified read model to the TUI. The TUI is a thin client that reads from the daemon over a Unix domain socket.

Install once with:

openusage telemetry daemon install

What you get

  • Long-lived history. Events persist across TUI restarts and machine reboots, so analytics and time-window views (7d, 30d, all) reflect real activity.
  • Hook-based ingestion. Tools like Claude Code, Codex, and OpenCode push every turn, message, and tool call directly to the daemon — no polling lag, no missed events.
  • Single source of truth. All AI usage lives in one SQLite database with deduplication, retention, and provider linking.
  • Always-on collection. Provider rate-limit headers are polled on the configured interval whether or not the TUI is open.

Dataflow

+----------------------+ +---------------------+
| Collectors | | Tool hooks |
| (poll providers) | | (claude-code, |
| | | codex, opencode) |
+----------+-----------+ +----------+----------+
| |
| HTTP over Unix socket | POST /v1/hook/{source}
v v
+------------------------------------+
| openusage daemon |
| +------------------------------+ |
| | Pipeline | |
| | - dedup (tool_call_id → | |
| | message_id → turn_id → | |
| | fingerprint hash) | |
| | - provider linking | |
| | - retention | |
| +--------------+---------------+ |
| v |
| +-----------------+ |
| | SQLite store | |
| | telemetry.db | |
| +--------+--------+ |
| v |
| +-----------------+ |
| | ReadModel | |
| +--------+--------+ |
+------------------|-----------------+
| POST /v1/read-model
v
+---------------+
| TUI client |
+---------------+

Three input sources feed the pipeline:

  • Collectors — provider plugins driven by the daemon's polling loop. They ingest rate-limit headers, billing snapshots, and dashboard-scraped balances.
  • Hooks — tool integrations POST events to the daemon over its Unix socket as they happen. See Integrations.
  • Spool — when the daemon is unreachable (hook fired but socket missing), events are written to a disk queue and drained on next startup. See Storage.

Endpoints

The daemon listens on a Unix domain socket (no TCP):

MethodPathPurpose
GET/healthzLiveness probe. Returns 200 OK when the pipeline is healthy.
POST/v1/hook/{source}?account_id=…Hook ingestion. {source} matches a provider link.
POST/v1/read-modelTUI client fetches a UsageSnapshot map for the current time window.

Default socket: ~/.local/state/openusage/telemetry.sock. Override with --socket-path or the OPENUSAGE_TELEMETRY_SOCKET environment variable.

Timeouts are tight and per-caller:

  • TUI client (/v1/read-model): 2-second dial, 12-second request.
  • Hook command (POST /v1/hook/<source>): 15-second overall context. On failure the event is written to the spool and re-ingested when the daemon comes back.

The protocol is meant to be local and fast.

What the daemon is not

  • Not a network service. It is bound to a Unix socket on your machine. There is no TCP listener, no auth, no remote ingest.
  • Not multi-user. One daemon per user account. Run separate daemons for separate users.
  • Not a replacement for provider dashboards. It mirrors and aggregates; it does not bill.

Next steps