Why this document exists

Compliance and procurement teams ask the same questions about any platform that holds customer data: "What's the architecture?", "What happens when I delete something?", "How are backups handled?", "What's the recovery objective?", and most importantly, "What's guaranteed in writing vs. promised in a deck?"

This page answers those four questions in the order they're usually asked. It's intentionally honest about the difference between "architecture supports this" and "we contractually guarantee this." If you're evaluating us for a regulated use case, the regulated-industries page (/for-regulated-industries/) goes deeper on framework-specific alignment; this page is the platform-wide durability story.

Storage architecture

Append-only graph at the engine layer

The content layer runs on InvariantDB, configured in append-only mode. No record is ever overwritten in place. When you "edit" a page, the graph records a new version of that record with _valid_from set to the moment that version becomes the truth, and the prior version's _valid_to set to the same instant. Both timestamps are preserved indefinitely as part of the record.

This is the bitemporal model: valid time (when the fact applied in the real world) and transaction time (when you recorded it) are tracked independently. Retroactive corrections are first-class — they create a new version dated in the past without overwriting the version that was current at the time. The graph remembers both what was true and what you thought was true on any given date.

Immutable snapshots

Mutations land in a write-ahead log, then get compacted into immutable, versioned snapshots stored on disk. Snapshot directories are content-addressed and never modified after creation; reader instances point at a published snapshot by its sequence number. A new mutation produces a new snapshot, not an in-place edit of the prior one.

Operationally this means the snapshot files you serve at midnight on August 12 are byte-identical to the snapshot files you'd serve if you asked again at 3pm on August 14, assuming no further mutations between those times. Reproducing a past render is a matter of pointing at the appropriate snapshot, not a database restore.

Cryptographic audit chain

Every mutation is appended to a hash-chained log: h(n) = SHA-256(h(n-1) || mutation_n). The chain is verifiable end-to-end by an external auditor with read-only access. We ship the verification routine as a customer-runnable binary (bin/verify-audit-chain); a clean walk is cryptographic proof that nothing was retroactively edited, including by us.

What deletion actually means

The platform exposes deletion through a small number of named operations. Each behaves differently. The important thing for any procurement evaluation is to understand exactly which operation is doing what.

DELETE /api/content/<type>/<id>

Marks the content record as deleted by writing a new version with _valid_to set to the deletion timestamp and a tombstone marker. The prior versions remain in the graph; the record will not appear in current-time queries or in build output. Recovery is a matter of restoring the tombstone (a new version with the tombstone cleared). No data is irrevocably gone.

DELETE /api/sites/:siteId

Marks the Site record itself as deleted via the same tombstone mechanism. The site's graph data is preserved at the engine layer. By default the underlying engine graph is retained for 30 days after the Site row is tombstoned, after which it's eligible for garbage collection on the next maintenance window. Explicit retention extensions can be configured per-site at deploy time.

If you need a stronger durability guarantee here — for example, regulatory retention that mandates keeping deleted-customer data for 7 years — set retentionDays on the Site's publishConfig. Site retention is honored at the engine layer; the GC sweep skips graphs whose retention window has not expired.

POST /api/subjects/:subjectId/destroy (GDPR Article 17)

For subject erasure requests — where the right thing to do is genuinely destroy PII rather than tombstone it — we expose a separate endpoint backed by the engine's destroySubjectKey procedure. It replaces the PII with an opaque marker that preserves the audit-chain integrity while making the original content cryptographically unrecoverable. The fact that an erasure occurred remains in the chain (you can't erase the erasure); the content erased is genuinely gone.

This resolves the Article 17 ↔ Article 30 tension that breaks naive "just delete the row" implementations. See the regulated-industries page for the full erasure protocol.

What we do not do

Backup architecture

Four independent layers, in order of increasing recovery time and decreasing freshness:

1. Per-graph S3 snapshot backups (every commit)

On every successful compaction, the engine writes a copy of the new snapshot to per-graph S3. Retention defaults to 30 days; we keep at minimum the most recent 20 snapshots regardless of age. Recovery from a per-graph snapshot is a sequence-number restore: point the reader at an older sequence, and the live site serves that historical state.

2. AWS EBS snapshots via Data Lifecycle Manager (daily)

The EC2 instance hosting the engine has its EBS volumes snapshotted nightly by AWS DLM. Retention is 14 days. Recovery from an EBS snapshot rebuilds the engine box at a point-in-time consistent with the snapshot moment; useful for "the box itself melted" scenarios, less useful for "a specific graph got corrupted at 2pm yesterday."

3. Cross-account replication (continuous, paid tier)

For the Managed Atomic-Release tier, per-graph S3 snapshots are continuously replicated to a separate AWS account in a separate region under cross-account access. This protects against the "our entire AWS account is compromised or lost" failure mode that none of the in-account layers cover.

4. Customer-side export (continuous, customer-controlled)

You can export the full graph at any time via POST /api/export — produces a tarball of canonical .dat files + an integrity manifest. Customers who care about durability beyond what we contractually guarantee should run this on a schedule and store it somewhere outside our control. No vendor-lock, no proprietary format.

Recovery objectives

Honest section. Distinguishing between what the architecture supports vs. what we contractually guarantee matters here.

Current best-effort, measured

Contractual

None of the above is contractual yet. We do not currently offer a written RTO/RPO SLA — we're early-access and would rather operate honestly than offer numbers we can't yet hold under load. The Business tier roadmap includes 99.9% uptime SLA + 1-hour RTO commitments; pricing reflects the cost of holding those numbers.

If you need contractual RTO/RPO commitments today, talk to us directly — we're happy to negotiate per-customer SLAs for design-partner engagements. The architecture is solid; the contractual framework is what's still under construction.

What customers should run, regardless

Sophisticated operators don't trust any vendor's durability story completely. Three things we recommend:

  1. Run the audit-chain verifier in your CI on a schedule. npx @staticowl/verify-audit-chain --graph <name> exits 0 on a clean walk, 1 on a broken chain. Alert on non-zero. Sub-minute on a 100k-record graph. (npm-package shipping next sprint; binary in our repo today.)
  2. Export to a bucket you own on a schedule. A weekly tarball of /api/export to your own S3 means even our complete disappearance doesn't kill your access to the data. The export bundle includes the full audit chain, so an offline auditor can verify integrity without our cooperation.
  3. Test your restore path before you need it. Spin up a fresh site, restore the export, verify the content matches what you sent us. We recommend this annually; we'll help walk through the protocol on the first run.

Where to ask follow-up questions

Send your procurement questionnaire — or just the questions that aren't answered above — to founders@staticowl.com. We answer with direct citations to architecture, code, or documented limitations. Procurement responses come from a founder; usually same-day.

Related reading