Backups¶
Database¶
PostgreSQL is the primary data store. Regular backups are critical.
pg_dump (Logical Backup)¶
Restore:
Tip
Schedule pg_dump via cron or a Temporal scheduled workflow for automated daily backups. Compress and upload to S3 for offsite storage.
Continuous Archiving (WAL)¶
For point-in-time recovery, configure PostgreSQL WAL archiving:
- Set
wal_level = replicaandarchive_mode = oninpostgresql.conf. - Configure
archive_commandto copy WAL files to S3 or a backup volume. - Use
pg_basebackupfor the initial base backup. - Restore to any point in time using
recovery_target_time.
This is the recommended approach for production deployments where data loss must be minimized.
Media Files (Object Storage)¶
Uploaded media (product images, documents) is stored in S3-compatible object storage — the bundled RustFS container in local dev, Amazon S3 or another S3-compatible provider (via a storage extension) in production.
Replication¶
For production, use S3 cross-region replication (or your provider's server-side replication equivalent) to maintain copies in a secondary region.
Manual Backup¶
Or with the mc client, which works against any S3-compatible store — including the dev RustFS container:
mc alias set rustfs http://localhost:9000 rustfsadmin rustfsadmin
mc mirror rustfs/vectis-uploads ./media-backup/
Valkey¶
Valkey (Redis-compatible) stores sessions and cache. While losing Valkey is not catastrophic (sessions expire, cache rebuilds), you may want to persist session data:
- RDB snapshots — periodic point-in-time snapshots, the default Valkey behavior (Redis RDB format).
- AOF — append-only file for crash recovery with minimal data loss.
Note
If Valkey is lost, users will need to re-authenticate (session data gone) and the price cache will rebuild on the next request. No permanent data is lost.
Temporal¶
Temporal stores workflow execution history in its own database (typically a separate PostgreSQL instance). Back up the Temporal database using the same pg_dump strategy.
Temporal data is required to resume in-progress workflows after a restore. Without it, running workflows are lost and must be manually re-triggered.
Search (Meilisearch + Typesense)¶
Vectis runs two co-equal search engines: Meilisearch for admin search and Typesense for the storefront. Both are derived stores — their indexes can be rebuilt from the primary database at any time:
The reindexer targets whichever engine each surface is configured to use, so a single reindex restores both admin (Meilisearch) and storefront (Typesense) indexes.
Backing up search data is optional since it can always be regenerated. For faster recovery, Meilisearch supports snapshot exports:
Typesense supports document export/import for the same purpose:
curl -H "X-TYPESENSE-API-KEY: $TYPESENSE_API_KEY" \
'http://localhost:8108/collections/storefront_products/documents/export' > storefront_products.jsonl
Backup Schedule Recommendations¶
| Data | Frequency | Retention | Method |
|---|---|---|---|
| PostgreSQL | Daily full + continuous WAL | 30 days | pg_dump + WAL archiving |
| Media (S3) | Continuous replication | Indefinite | S3 cross-region replication |
| Valkey | Optional — rebuilds automatically | N/A | RDB snapshots |
| Temporal DB | Daily | 14 days | pg_dump |
| Search (Meilisearch + Typesense) | Optional — rebuilds from DB | N/A | Reindex on recovery |
Disaster Recovery¶
- Provision infrastructure — new database, Valkey, S3.
- Restore PostgreSQL from latest backup.
- Restore media from S3 replica.
- Run Alembic —
alembic upgrade head(idempotent, ensures schema is current). - Reindex search — rebuild both Meilisearch (admin) and Typesense (storefront) indexes from DB.
- Start services — API, workers, consumers, frontends.
- Verify — check
{ health }query, test a login, browse products.
DR Runbook¶
A full DR runbook lives in the application repo at vectis/docs/DR_RUNBOOK.md with:
- A reference
pg_dumpscript atvectis/backend/scripts/backup_postgres.shfor daily logical backups - A weekly verify procedure (
vectis/backend/scripts/verify_backup_restore.py) that restores the latest dump into an ephemeral container and asserts a known-good state — catches silent backup corruption before you need it - Step-by-step restoration procedures for each component (Postgres, Valkey, Redpanda, Temporal, Meilisearch, Typesense, object storage)
- Cross-region replication recipes (S3 → S3, Postgres logical replication, Redpanda mirror-maker)
Schedule the weekly verify as a Temporal cron — it's part of why you have backups at all.
Webhook Secret Rotation¶
Webhook signing secrets, gateway API keys, and any other Fernet-encrypted value stored in the settings table follow the rotation pattern in Deployment → Crypto Secrets. Include the current and rotating-from keys in your backup recovery procedure — without them, encrypted rows can't be decrypted after restore.