Most Odoo operators set up a backup script, confirm it runs once, and assume they're covered. Then six months later, when they actually need to restore, they discover the backups have been silently failing, the filestore was never included, or the dump is unrestorable due to a version mismatch. Here's how to build a backup strategy that holds up under real conditions.
The 3-2-1 Rule for Odoo
The 3-2-1 rule is the industry standard for backup resilience:
- 3 copies of your data
- 2 different storage media types
- 1 copy offsite
Applied to Odoo, this means:
- The live database and filestore on your production server
- A daily backup on a local secondary disk or separate volume
- An offsite copy in S3-compatible object storage (Backblaze B2, Cloudflare R2, AWS S3)
Object storage alone counts as your offsite copy, but a local backup provides a faster restore path when you need to recover quickly.
Retention Strategy
Retention is about more than disk space — it's about how far back you can recover from. A good production retention strategy:
| Backup Type | Frequency | Retention |
|---|---|---|
| Hourly snapshot | Every hour | 24 hours |
| Daily full backup | Every day at 02:00 | 30 days |
| Weekly full backup | Every Sunday | 90 days |
| Monthly full backup | 1st of each month | 12 months |
Hourly snapshots are optional but valuable for databases with high transaction volumes — they limit data loss to under an hour if you need to recover mid-day. For PostgreSQL, you can use WAL archiving for point-in-time recovery (PITR) instead of hourly full dumps.
Also see our guide on how to back up an Odoo database for the mechanics of creating each backup type.
What Must Be Included in Every Backup
A complete Odoo backup requires both:
- PostgreSQL dump — use
pg_dump -Fcfor custom format, which is compressible and supports parallel restore - Filestore — the directory at
data_dir/filestore/<dbname>/containing all binary attachments
Never back up only the database. The filestore is not in PostgreSQL — it lives on disk. A database restore without a matching filestore will leave you with broken attachments, missing invoice PDFs, and missing product images.
Testing Restores: The Most Neglected Step
A backup you have never restored is a hypothesis, not a safety net. Build restore testing into your operations:
- Monthly restore drill: Download the most recent backup and restore it to a staging environment. Verify Odoo starts, log in, check a recent invoice, open an attachment.
- Automated restore verification: Run a script that restores the backup to a throwaway container, starts Odoo, hits the health check endpoint, and logs a success/failure status. Run this weekly.
- Version consistency check: Verify the backup was created from the same Odoo version as your production instance. Store the version string in a metadata file alongside each backup.
Monitoring Backup Jobs
Silent failures are the enemy. Use a dead-man's-switch monitoring approach:
- Sign up for a free Healthchecks.io account
- Create a check with the expected schedule (e.g., daily)
- Append a
curlping to the end of your backup script:curl -fsS https://hc-ping.com/YOUR-UUID - Configure the check to alert you by email or Slack if no ping is received within the expected window
Also monitor S3 bucket size — a sudden drop in backup size or backup count is a leading indicator of a scripting error before you discover it the hard way.
Encryption Requirements
If your Odoo database contains personal data (customer names, addresses, email addresses, financial data), backup encryption is not optional under GDPR, HIPAA, and similar regulations.
At-rest encryption options:
- Enable S3 server-side encryption (SSE-S3 or SSE-KMS) on your bucket — zero overhead, managed by the provider
- Encrypt locally before upload using GPG:
gpg --symmetric --cipher-algo AES256 backup.tar.gz - Use a backup tool with built-in encryption such as Restic or Borg
In-transit encryption: Always transfer backups over SSH/SFTP or HTTPS (S3 API uses HTTPS by default). Never transfer unencrypted backup files over plain HTTP or FTP.
Common Backup Mistakes to Avoid
- Backing up to the same disk as the database (if the disk fails, both are lost)
- Forgetting the filestore in the backup script
- Using plain SQL dumps for large databases (slow, not parallelizable)
- Not testing restores until a real incident forces it
- Retaining backups on the production server but nowhere else
- Backup scripts that suppress errors and report success on failure
How DeployMonkey Implements These Best Practices
DeployMonkey builds these best practices into every managed instance automatically. Backups are scheduled, include both the database and filestore, are uploaded to your S3-compatible bucket with server-side encryption enabled, and are monitored for failures. Restore testing can be triggered from the control panel. You get a production-grade backup strategy without writing a single script. Start free — no credit card required.
Frequently Asked Questions
How much storage do I need for Odoo backups?
Estimate 2–3x your current database and filestore size for 30 days of daily backups (compression typically achieves 40–60% reduction). A 2 GB Odoo instance with daily backups for 30 days uses roughly 30–50 GB of storage at $0.006/GB/month on S3 — under $0.50/month.
Should I back up PostgreSQL with pg_dump or at the filesystem level?
Use pg_dump (logical backup) for Odoo. Filesystem-level backups (e.g., snapshotting the PostgreSQL data directory) require the database to be stopped or in hot standby mode. pg_dump works on a live database and produces a portable, version-independent format.
What is WAL archiving and should I use it for Odoo?
WAL (Write-Ahead Log) archiving enables point-in-time recovery — you can restore the database to any second in the past. It's valuable for high-transaction Odoo instances where a daily backup creates too much potential data loss. Set up WAL archiving with archive_mode = on in postgresql.conf alongside your regular full dumps.
How often should I test my Odoo backups?
At minimum, once per month. For production systems handling financial transactions, test weekly. Automate the restore verification so it runs without manual intervention — treat a failed automated restore test as an incident.