Skip to content

Backups

Cloudflare D1 keeps a 30-day point-in-time history (Time Travel) with nothing to configure:

Terminal window
wrangler d1 time-travel restore your-cms-db --timestamp=...

For an off-platform copy, export the database. It briefly makes D1 unavailable while it runs:

Terminal window
wrangler d1 export your-cms-db --remote --output backup.sql

Restore with wrangler d1 execute your-cms-db --remote --file backup.sql. There is no built-in scheduling; run it by hand or from a scheduler you control.

R2 has no built-in versioning or point-in-time recovery. The repository includes a script that walks the media table and downloads or uploads each object with Wrangler:

Terminal window
cd apps/api
pnpm backup-media -- --remote --out ./media-backup
pnpm restore-media -- --remote --from ./media-backup

Use --local for local development. The backup is a directory with manifest.json and an objects/ tree. Restoring only repopulates R2, so restore it together with the matching D1 backup. The script’s BUCKET_NAME constant defaults to kenresoft-cms-media, which is only correct if you created that exact bucket, not if Cloudflare auto-generated the name. Check it.

R2 is S3-compatible, so a sync tool such as rclone also works.