The stack
04 · App state & storage
Convex is the live backend for every app: data, functions, real-time state, and files. Object storage only when a workload justifies it.
- Dimension
- 04 · App state & storage
- Platform
- Convex + Convex Storage
- Convex
- Default persistence, reactive state, orchestration, and audit authority for EXO. Core standard · authority: EXO
- Convex Storage
- Convex-native media metadata, checksums, and lifecycle; object storage only when the workload justifies it. Core standard · authority: EXO
- Status
- App state: Live. Exo's platform data is in Convex; exceptions need an ADR-level justification. Storage: Convex file storage for small blobs; large media on S3-compatible storage (Garage) per the infrastructure split.
What it is
Convex is the default persistence, transaction, function, and reactive-state layer for every state Exo owns (ADR 0003). It holds tenants, content, roadmap, billing, releases, delivery targets, observations, and identity, and serves the live queries behind dashboards and boards (infrastructure).
Storage
Media covers uploaded files, images, and attachments. Construct's Convex deployment owns Page media metadata, checksums, lifecycle, and references. Exo uses Convex file storage for help-desk attachments and similar small blobs (infrastructure).
Platform
Convex. Exo runs two deployments, frugal-eel-930 (staging) and befitting-bullfrog-619
(production) (convex/README.md).
Storage
Convex Storage for small files and for the authoritative metadata. Large media libraries stay on S3-compatible object storage, which is "Garage today" according to the infrastructure split.
Boundary and replaceability
- Exceptions are explicit. An exception to Convex needs a concrete workload constraint, a named authority, reconciliation and rollback rules, and an exit path. Exo runs no other application database.
- Derived indexes stay derived. Specialized analytical or search indexes may live outside Convex, but they must be rebuildable and never the sole authority.
- Function discipline. Every query and mutation validates arguments and returns, derives identity server-side, enforces the resource boundary, and bounds result size. Privileged functions are internal, and retryable mutations use atomic idempotency receipts (architecture).
- No secrets in tables. Convex stores only non-secret provider coordinates and the names of runtime environment variables.
- Exit. Tenant exports use versioned JSON Schema and newline-delimited JSON with stable IDs (portability).
Storage
- Large binary objects never go in Convex documents. Blob bytes may use Convex file storage or an external object store when size, transformation, retention, egress, or interoperability requirements justify it. Convex stays authoritative for ownership, checksum, metadata, lifecycle, and the opaque object reference (ADR 0003).
- Because references are opaque, moving bytes between stores is a reconciliation job, not a schema change.
- Exports include original media files, metadata, alt text, checksums, and a media manifest (portability).
Cost notes
- Convex plan and usage: TBD.
- ADR 0006 expects exo-analyze's event table to add "a few dollars per month" of Convex storage and function usage at current portfolio scale.
Storage
Convex storage and object-storage costs: TBD. The ADR names egress as one of the valid reasons to move bytes out of Convex.
Status
- Done: Exo's data layer moved from Payload/PostgreSQL to Convex (exo-convex-backend).
- Retired: Payload and its PostgreSQL code path (removed from Exo and Construct, October 2026; the old databases are kept untouched until their data is exported), Clerk as identity, and bespoke API services (infrastructure).
Storage
- Live: Convex file storage for small blobs.
- TBD: which Apps currently keep large originals on Garage, and the measured constraint for each (the ADR requires one).
Source: content/docs/stack/app-state.mdx