Backup and Restore
The export procedure below has been executed against a live deployment, not merely written down. The verification step exists because a backup nobody has restored is not a backup.
Taking a backup
npx convex export --path snapshot.zipFor production:
npx convex export --prod --path snapshot-prod.zipTo include uploaded files — school logos, profile images, safeguarding certificates:
npx convex export --prod --include-file-storage --path snapshot-prod.zipWithout --include-file-storage the archive contains data only. Restoring
it gives you a working system with broken images and missing documents.
What is in the archive
A snapshot of this system contains 28 tables, including:
users,schools,leaguestournaments,teams,rounds,debatesjudging_scores— every ballotranking_snapshots,school_tierspayments,audit_logs_components— the workpool, cache and retrier state
Verify an archive before trusting it:
python -c "import zipfile; z=zipfile.ZipFile('snapshot.zip'); print(len(z.namelist()), 'entries')"An archive with only a handful of entries did not export properly.
Restoring
Restore to a scratch deployment first
Never restore straight into production. Create or reuse a development deployment and restore there.
npx convex import snapshot.zipCheck the restore
Sign in and confirm:
- A tournament you know exists, with its teams
- A submitted ballot, with its speaker scores intact
- Rankings, if any were released
Only then restore to production
npx convex import --prod --replace-all snapshot-prod.zipThe import modes
| Flag | Effect |
|---|---|
--append | Adds to existing tables |
--replace | Replaces the tables present in the archive |
--replace-all | Replaces everything, deleting tables absent from the archive |
--replace-all is the correct choice for disaster recovery and the wrong choice
for anything else.
How often
- Before any schema change or major deploy — always
- Before and after every tournament — a tournament’s ballots cannot be reconstructed from memory
- Weekly during an active season
Keep at least one backup off the machine that made it.
What a backup does not cover
Environment variables are not in the archive. Record them separately:
npx convex env listA restore into an empty deployment with no environment variables will start but will not send email, deliver push notifications, or reach Gemini.
Recovery checklist
- Restore the data with
--replace-all - Set every environment variable from Environment Variables
- Redeploy the frontend
- Sign in and check a tournament, a ballot, and the rankings
- Send one test email to confirm SMTP is configured