Skip to content

Budget persistent /data retention for Railway's 0.5 GB Trial volume #160

Description

@hamzamerzic

Why

A Railway Trial instance reported /data at about 392 MB used with 33 MB free. Its observed breakdown was:

Path Size Role
/data/platform 133 MB live, agent-editable Möbius source tree
/data/platform.crashloop-prev.20260716T211243Z 95 MB recoverable prior platform tree
/data/agent-browser-profiles 95 MB per-chat Chromium cache/session state
/data/logs 18 MB mostly chat.log
auth/compiled/db/apps ~8–16 MB each normal durable state

Railway currently caps Trial volume storage at 0.5 GB and bills volume storage separately from RAM. This is distinct from the active-turn OOM/process-lifecycle work in #130 and the host Docker/build-disk admission work in #151.

Current Railway docs:

What current main already gets right

  • Chromium itself is installed in the image at build time and moved to /opt/agent-browser; it is not the 95 MB under /data.
  • /data/agent-browser-profiles is cache plus cookies/IndexedDB/session state. Current main applies Railway-aware 128 MiB/96 MiB high/low water defaults and an hourly quota sweep.
  • /data/platform is intentionally persistent and editable: every owner holds a local copy they can change to change the running app.
  • crash-loop trees are intentionally preserved for recovery, not treated as disposable cache.

So “move Chrome into the image” is already done. Moving the live platform tree out of /data would break the local-editability contract, and deleting recovery trees blindly would trade a full-volume failure for data loss.

Needed invariants

  • Surface actual volume capacity/free bytes plus a bounded top-level /data breakdown on the operator health surface. Do not conflate volume bytes with cgroup memory/RSS.
  • Before a crash-loop re-clone or any other operation that temporarily needs a second platform tree, perform a free-space admission check.
  • Reclaim proven-regenerable browser cache first; never delete an active profile, transcript, credential, DB, app data, or the only recoverable platform copy.
  • Replace count-only crash-loop retention (currently up to three full trees) with a byte/capacity-aware policy. Always preserve the newest recovery point; if older recovery history must be pruned, make that explicit and observable.
  • Consider whether older platform recovery points can be represented losslessly as a smaller git bundle/patch plus untracked-file archive. Do this only if round-trip tests prove owner edits, modes, symlinks, and untracked files survive.
  • Make the browser-profile budget proportional to the actual volume after reserving space for the live platform, DB/auth/app data, one recovery point, and clone/update headroom; keep operator overrides.
  • Keep scans off the hot path: event-trigger after known large writes plus a low-frequency reconciliation sweep.

Suggested verification

  • simulate a 0.5 GB volume with the measured directory mix and prove a crash-loop restore either admits safely or fails before moving the live tree
  • prove reclaim order is cache → older redundant recovery history, never durable owner state
  • prove the newest crash-loop recovery point round-trips local commits, dirty tracked files, untracked files, symlinks, and executable modes
  • prove active browser profiles and running chats are excluded under pressure
  • prove diagnostics report volume bytes separately from cgroup memory values

Related: #130 (RAM/active turns), #151 (host build disk).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions