Point-in-time recovery, incremental backups, WAL streaming to S3/GCS/Azure, data versioning with instant zero-cost clones, and per-tenant export/import.
Absolute DB provides a layered backup strategy: continuous WAL streaming for near-zero RPO, periodic full or incremental base backups for independent restore points, and data versioning for instant logical snapshots. All backup targets (local disk, S3, GCS, Azure Blob) are accessed via pure HTTP/1.1 with native TLS 1.3 — no cloud SDK dependencies.
| Strategy | RPO | RTO | Storage Cost |
|---|---|---|---|
| WAL streaming (continuous) | Seconds | Minutes | Low (WAL deltas only) |
| Incremental backup | Hours | Minutes–hours | Low (changed pages only) |
| Full backup | Hours–days | Minutes–hours | Full database size |
| Data branch (instant clone) | Zero (logical) | Milliseconds | Zero until first write |
| Metric | Target | Notes |
|---|---|---|
| RPO (WAL streaming) | < 30 seconds | Depends on WAL archive frequency |
| RPO (incremental backup) | < 1 hour | Configurable backup interval |
| RTO (from PITR) | < 15 minutes | For databases up to 100 GB; depends on restore bandwidth |
| RTO (from full backup) | < 30 minutes | Parallelised restore with multi-part download |
| RTO (from branch) | < 100 ms | Copy-on-write instant clone — no data movement |
A full backup captures a consistent snapshot of all data files. During the backup, writes continue normally — Absolute DB uses MVCC to present a consistent read snapshot to the backup process without blocking transactions.
# Backup all databases to a local directory
absdb backup --output /backup/absdb-$(date +%Y%m%d)
# Backup a specific database
absdb backup --database myapp --output /backup/myapp-$(date +%Y%m%d)
# Backup directly to S3
absdb backup \
--database myapp \
--output s3://my-bucket/backups/myapp-$(date +%Y%m%d) \
--s3-region us-east-1
# Show backup metadata
absdb backup --info /backup/myapp-20260401
Incremental backups capture only the pages that changed since the last full or incremental backup. They are significantly faster and smaller than full backups. A restore from an incremental chain applies the full backup first, then each incremental in sequence.
# Take an initial full backup (the base)
absdb backup \
--database myapp \
--output s3://my-bucket/backups/full-base \
--label full-base
# Take an incremental from the last backup
absdb backup \
--database myapp \
--incremental \
--from-label full-base \
--output s3://my-bucket/backups/incr-$(date +%Y%m%d) \
--label incr-$(date +%Y%m%d)
# List all available backups
absdb backup --list s3://my-bucket/backups/
WAL streaming continuously ships Write-Ahead Log segments to the backup target as they are written. This enables near-zero RPO and is the foundation of point-in-time recovery. WAL segments are CRC-32C verified before being archived.
# Configure WAL archive in absdb.conf
wal_archive_enabled = true
wal_archive_target = s3://my-bucket/wal-archive/
wal_archive_interval = 60 # seconds between segment uploads
wal_retention_days = 14 # keep 14 days of WAL for PITR
# Or pass at startup
./bin/absdb-server \
--wal-archive s3://my-bucket/wal-archive/ \
--wal-archive-interval 60 \
--wal-retention-days 14
SELECT
last_archived_lsn,
last_archived_time,
archive_lag_seconds,
segments_archived_today
FROM absdb_wal_stats;
Absolute DB connects to cloud object storage directly over HTTP/1.1 with native TLS 1.3. No cloud SDK, no external library is needed.
| Provider | Auth Method | URL Scheme |
|---|---|---|
| AWS S3 | AWS Signature v4 (HMAC-SHA-256) | s3://bucket/path/ |
| Google Cloud Storage | OAuth2 service account JWT (RS256) | gcs://bucket/path/ |
| Azure Blob Storage | Shared Key (HMAC-SHA-256) | azure://container/path/ |
# AWS S3 — credentials via environment variables
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
export AWS_DEFAULT_REGION=us-east-1
# GCS — service account key file
export GOOGLE_APPLICATION_CREDENTIALS=/etc/absdb/gcs-key.json
# Azure Blob — account name and key
export AZURE_STORAGE_ACCOUNT=myaccount
export AZURE_STORAGE_KEY=base64encodedkeyhere==
Large backups are uploaded using multipart upload (parts ≥ 8 MB) with parallel upload threads, maximising throughput on high-latency connections.
PITR lets you restore the database to any point in time within the WAL retention window. The recovery process: (1) restore the nearest full base backup, (2) apply incremental backups up to the target time, (3) replay WAL segments up to the exact recovery target.
# Step 1 — Find the nearest full backup before the target time
absdb backup --list s3://my-bucket/backups/
# Step 2 — Restore to a recovery directory
absdb restore \
--from s3://my-bucket/backups/full-base \
--to /var/lib/absdb-recovery
# Step 3 — Configure PITR recovery target
cat > /var/lib/absdb-recovery/recovery.conf <
# Restore from a full local backup
absdb restore \
--from /backup/myapp-20260401 \
--to /var/lib/absdb
# Restore from S3
absdb restore \
--from s3://my-bucket/backups/myapp-20260401 \
--to /var/lib/absdb
# Restore a single database only (not all databases)
absdb restore \
--from s3://my-bucket/backups/full-base \
--database myapp \
--to /var/lib/absdb
# Verify backup integrity before restoring
absdb backup --verify s3://my-bucket/backups/myapp-20260401
Every backup includes a manifest with SHA-256 checksums for each file. The --verify flag downloads and re-checksums the backup without restoring it, confirming integrity before an actual recovery is needed.
# Verify all checksums in the backup
absdb backup --verify s3://my-bucket/backups/myapp-20260401
# Automated verification (for cron jobs)
absdb backup --verify \
s3://my-bucket/backups/myapp-$(date +%Y%m%d) \
&& echo "Backup OK" \
|| alert "Backup verification FAILED"
Retention policies automatically remove backups and WAL segments older than the configured window. This prevents unbounded storage growth while ensuring the PITR window is maintained.
# Keep full backups for 30 days, WAL for 14 days
./bin/absdb-server \
--backup-retention-days 30 \
--wal-retention-days 14
# Or in absdb.conf
backup_retention_days = 30
wal_retention_days = 14
# Manually trigger retention cleanup
absdb admin purge-old-backups \
--backup-dir s3://my-bucket/backups/ \
--older-than 30d
Absolute DB includes Git-style database branching. Creating a branch is instant (zero storage cost) because it uses copy-on-write page namespaces — pages are shared until a branch writes to them. This is ideal for testing schema migrations, running analytics against a production snapshot, or isolating staging environments.
-- Create an instant zero-cost clone of 'main'
CREATE DATABASE staging BRANCH FROM main;
-- List all branches
SELECT name, created_at, created_from, diverged_pages
FROM absdb_branches;
-- See what has changed between staging and main
SELECT table_name, operation, row_count
FROM absdb_branch_diff('staging', 'main')
ORDER BY table_name;
-- Merge staging changes back to main (DDL + DML)
MERGE DATABASE staging INTO main;
-- Drop a branch (releases its storage delta)
DROP DATABASE staging;
Branches are not a substitute for proper backups — they live on the same storage node. However, they are invaluable for development workflows: create a branch, run a migration, test it, and then merge or discard in milliseconds.
In multi-tenant deployments, individual tenants can be exported and imported independently. This is useful for data portability, tenant migration between clusters, and compliance (GDPR right-to-portability).
-- Export a single tenant to a portable archive
SELECT absdb_tenant_export(
tenant_id => 'tenant_acme',
output => 's3://my-bucket/tenant-exports/acme-20260401.tar.zst'
);
-- Import a tenant archive (on the same or a different cluster)
SELECT absdb_tenant_import(
source => 's3://my-bucket/tenant-exports/acme-20260401.tar.zst',
tenant_id => 'tenant_acme', -- target tenant name
overwrite => false -- fail if tenant already exists
);
-- List all tenants and their storage usage
SELECT tenant_id, schema_name, storage_mb, row_count
FROM absdb_tenants
ORDER BY storage_mb DESC;
Tenant exports are self-contained archives including the tenant's schema, all data, and encryption key metadata (the export itself is re-encrypted with a transfer key). The tenant's data encryption key (DEK) is not included in plain text — key handoff must be performed separately.
~154 KB binary · zero external dependencies · 2,737 tests passing · SQL:2023 100%