TILLARK · TILLDEV

Prove your last N restores
all passed.

Cross-vendor backup, disaster recovery, and failover — with restore-verification you can actually prove. TillArk continuously restores your backups into throwaway sandboxes, asserts they’re intact, and puts green/red plus real RPO/RTO on a board. Backup is a trust category; we earn it by verifying, not by hoping.

PROVING · restore-verification
3-2-1 · cross-vendor · WORM · client-side aead · hybrid-pqc · verified
WHAT’S INSIDE

A control plane for recovery.

Restore-verificationBETA

Scheduled proving-restores into ephemeral, network-isolated sandboxes — integrity-asserted, then green/red plus real RPO/RTO emitted into TillPulse. The wedge nobody else offers.

› Read the docs
Three-tier durabilityBETA

Same-region quorum-sync replica, cross-vendor async replica, and continuous WAL archive to WORM object storage. Residency-aware anti-affinity puts backups on a different failure domain.

› Read the docs
Failover you can trustBETA

A role-based state machine with fencing, quorum, a confirmation window, and anti-flap. Auto-failover is opt-in; manual with approval is the default.

› Read the docs
Client-side encryptionBETA

Backups are AES-256-GCM encrypted inside the agent before they leave your environment. The storage vendor only ever sees ciphertext — with a hybrid post-quantum key path.

› Read the docs
Ransomware-proof targetsBETA

WORM / object-lock and versioning mean a backup cannot be deleted or overwritten inside its retention window — and the keys that write them live in a separate credential domain.

› Read the docs
Engines wrapped, not rebuiltBETA

restic, WAL-G, and clickhouse-backup driven by a self-hostable Go agent — across S3, R2, B2, Wasabi, GCS, Azure, and MinIO. We own the manifest, not a backup engine.

› Read the docs
THE WEDGE

Anyone can take a backup. The question is
whether it restores.

On a cadence, TillArk restores a real backup into an ephemeral, network-isolated, per-tenant sandbox, asserts its integrity — signature, schema hash, row counts, checksums — tears it down, and emits the result. Every bar below is one real restore that actually happened, with the RPO and RTO it measured.

RTO SLO · 60s← 30 DAYS · ONE PROVING-RESTORE PER DAYLATESTRTO 47sRPO 3s30 / 30 PASSED→ TillPulse board

This turns “we take backups” into “we’ve proven the last N restores worked.” A silent failure — expired credentials, a changed bucket policy, quiet corruption — surfaces as a red restore on a board, not as a discovery at 3 a.m. during the outage you were saving for.

It is the honest, monitored SLA the incumbents don’t offer — and it’s sampled and staggered at scale so proving your recovery never becomes its own cost.

Restore-verification guide →
bash · verify
$ tilldev ark verify history --source neon-primary

✓ 2026-07-11 04:00  restore ok   RPO 3s   RTO 47s   rows 10,000/10,000
✓ 2026-07-10 04:00  restore ok   RPO 2s   RTO 44s   rows  9,984/9,984
✓ 2026-07-09 04:00  restore ok   RPO 4s   RTO 51s   rows  9,102/9,102
✓ 2026-07-08 04:00  restore ok   RPO 2s   RTO 49s   rows  8,760/8,760

last 30/30 proving-restores passed · emitted to TillPulse
3-2-1, AUTOMATED

Backups land on a different failure domain.

Three durability tiers stack on top of your primary, and residency-aware anti-affinity makes sure each copy lands on a different vendor and region than the primary — but never leaves the legal region it’s allowed to sit in. A copy in the same blast radius isn’t a backup.

QUORUM-SYNCASYNC LOGICALWAL SHIPPRIMARYneon · postgres · euTIER 1 · SAME-REGION REPLICAneon · eu-alt-az · promotableRPO ≈ 0TIER 2 · CROSS-VENDOR REPLICAindependent pg · other vendor · euRPO ~sTIER 3 · WAL → WORM ARCHIVEb2 · eu · object-lock · PITRRPO walANTI-AFFINITY · DIFFERENT VENDOR + DIFFERENT REGION · SAME LEGAL RESIDENCY (eu)
yaml · policy.yaml
# One source, proven continuously — the policy is the contract.
source: neon-primary          # managed Postgres (our own primary)

schedule: "0 * * * *"          # hourly backup
retention:                     # grandfather-father-son
  hourly: 24
  daily: 30
  monthly: 12

anti_affinity:                 # a copy in the same blast radius is not a backup
  different_vendor: true       # never the same provider as the primary
  residency_zone: eu           # ...but never leaves the legal region

targets:
  - provider: r2               # cross-vendor object store
    immutable: true            # WORM / object-lock — ransomware can't delete it
    object_lock_days: 30

rpo_slo_sec: 5                 # measured + alarmed, not hoped
rto_slo_sec: 60
verify_cadence: "0 4 * * *"    # prove a real restore every day
crypto_suite: aes256gcm+x25519-mlkem768   # hybrid post-quantum key wrap
ROLES, NOT MACHINES

Failover you can actually trust.

There is a primary role and a replica role, and roles move between nodes — which dissolves the “original vs backup” confusion at the heart of a botched failback. The state machine confirms, fences, promotes, and only then repoints the app.

Auto-failover is opt-in. The default is manual with approval — because the fast wrong answer during an incident is worse than the careful right one.

Failover reference →
bash · failover
# Where does each source stand right now?
tilldev ark failover status --source neon-primary

# Promote a replica — fences the old primary first, refuses a stale one.
# Dangerous action: needs a second, distinct approver (four-eyes).
tilldev ark failover promote --source neon-primary \
  --approved-by u_ada --approval-ref INC-4821

# Come home deliberately: catch up first, then flip. Never automatic.
tilldev ark failover failback --source neon-primary
N SEC · M OBSQUORUMFENCE · REFUSE STALEOLD NODE RETURNSCATCH-UP-FIRSTDELIBERATE FLIPHEALTHYprimary servingSUSPECTconfirm windowFENCINGsuspend · rotatePROMOTEDreplica → primaryREVERSE-SYNCre-attach as replicaFAILBACKmanual · scheduled⚠ NEVER RESUME THE OLD WRITE DIRECTIONAUTO-FAILOVER: OPT-IN · ANTI-FLAP COOLDOWN + FAILOVER CAP PER WINDOW
GUARDRAILS, BY DEFAULT
confirm

Unhealthy for N seconds across M independent observers — at least one where the app sits, not only where TillArk sits. A network-partition blip is not a failover.

fence

The old primary is fenced before promotion — Neon compute suspended, its role password rotated — so it rejects writes even if it is still alive. No split-brain double-write.

quorum

A promotion needs quorum agreement and refuses a replica beyond the staleness bound. TillArk will not promote a copy too far behind to be trusted.

anti-flap

A cooldown and a failover cap per window stop ping-pong. Failback is a deliberate, catch-up-first switchover — manual by default, never an automatic flip.

SECURITY IS THE SPINE

The vendor holds bytes it
can’t read — and can’t delete.

Backups are the single highest-value target an attacker can steal once and hold forever, so TillArk is designed as if the ciphertext is already stolen. Data is encrypted inside the agent, before it leaves your environment, and written to immutable storage under keys your prod runtime never holds.

Whole classes of bug are made structurally absent, not merely filtered: command injection (CWE-78) can’t occur because the agent only ever builds argv arrays, and SSRF (CWE-918) can’t reach your metadata endpoint because every outbound host is re-resolved and IP-pinned.

THE SECURITY MODEL
Client-side AEAD

AES-256-GCM inside the agent — the storage vendor only ever sees ciphertext.

Verify before restore

Hybrid-signed manifests (Ed25519 + ML-DSA-65) are checked before a single byte is trusted.

WORM / object-lock

Object-lock + versioning: a backup can’t be deleted or overwritten inside its retention window.

Separate credential domain

Backup-writing keys never live in prod — a full prod compromise still can’t erase your backups.

Crypto-agility + PQC

Every envelope names its suite, so primitives rotate without breaking old backups. Hybrid post-quantum ready.

Four-eyes on danger

Restore and failover are RBAC-gated and approval-gated — a second, distinct admin has to sign off.

OWN THE CONTROL PLANE, NOT THE BYTES

Engines wrapped, not rebuilt.

A homegrown backup engine’s failure mode is silent data loss you discover at restore time. TillArk doesn’t build one — it drives proven engines with a self-hostable Go agent (a single static binary that runs in your environment and can act on cached policy even if the control plane is unreachable). Our originality goes into the manifest, the verification, and the orchestration.

CONTENT-ADDRESSED · INCREMENTAL-FOREVER
restic

Dedup, compression, and encrypt-then-upload straight to object storage. The workhorse for files, buckets, and most datastores.

POSTGRES · PHYSICAL + PITR
WAL-G / pgBackRest

Parallel physical backups and continuous WAL archive for Postgres — the foundation under point-in-time recovery.

CLICKHOUSE · FREEZE-CONSISTENT
clickhouse-backup

Snapshot-consistent ClickHouse backups to S3-compatible storage — the high-value observability store, natively covered.

STORE IT ANYWHERE — CROSS-VENDOR BY DESIGN
S3R2B2WasabiGCSAzureMinIOSFTP
WHAT BEING THE BACKUP UNLOCKS

Two things only the backup can do.

OBSERVABILITY-NATIVE
BETA

Ransomware canary

A backup system sees every byte’s compressibility — so when a datastore turns high-entropy and the dedup ratio collapses, that’s an attacker encrypting your data. TillArk alarms on the entropy drop mid-encryption, before it finishes. Nobody offers this natively; we can, because TillPulse is already watching.

HOW IT WORKS · Every backup’s Shannon entropy is signed into its manifest and charted on your Recovery Board. The instant entropy and dedup move together — judged against each source’s own baseline — the canary fires.

DEV VALUE
BETA

PII-scrubbed instant clones

Spin up a masked, prod-like environment from any backup, reusing the exact same PII rules as the SDK’s on-device scrub (M-Pesa, national-ID, phone, email). Realistic staging data from last night’s backup — without copying real customer data into a dev box.

HOW IT WORKS · The clone restores into a throwaway scratch target, rewrites every PII column in place, and ships with a proof of exactly which columns were neutralised. It auto-expires on a TTL; a raw (unmasked) clone is four-eyes-gated.

NOT A SILO

Same workspace. Same login.

TillArk isn’t a separate DR appliance to run — it’s the recovery layer of the TillDev workspace you already have. It reuses TillSecrets for keys, TillAuth for approvals, and reports every number to TillPulse.

01 · REPORTS TO

TillPulse

Live RPO/RTO, replication lag with SLO alarms, restore-verification green/red history, and failover transitions land in the same observability surface as the app they protect.

02 · BUILT ON

The suite

Keys come from TillSecrets, RBAC and four-eyes approvals from TillAuth, and outbound safety from the shared SSRF guard. TillArk is enterprise-grade because the suite already is.

03 · RECORDS

One audit log

Every backup, restore, promotion, fence, and key rotation appends to the shared, tamper-evident TillDev audit log — the compliance backbone, next to your Pulse, Auth, and Shield events.

WE ARE TENANT #1

Backup is a trust category, so we earn it the only honest way: TillArk protects our own data first, and it won’t open as something you can buy until it has survived a real recovery event — not just a passing test suite.

TURN IT ON

Stop hoping your backups restore. Prove it — cross-vendor, encrypted before it leaves your box, immutable at rest, and verified on a schedule you can watch.

PART OF TILLDEV

It closes the loop.

TillArk protects the rest of the suite — same workspace, same audit log, same login. Add what you need when you need it.