Quick Answer
If your database dies tomorrow, do you have a tested backup? Most D2C brands answer "probably." That costs $180,000. The fix: Automated daily backups (Odoo.sh automatic or self-hosted scripts), offsite S3 storage, and monthly tested restores. RPO: 1 hour. RTO: 2 hours.
The Backup Problem Nobody Plans For
Your Odoo system is live. Your entire D2C business is running on it. Orders come in. Inventory syncs. Revenue is being recorded.
Now ask yourself: If your database dies tomorrow, do you have a tested backup and recovery plan?
Most D2C brands answer "probably" or "I think so." That's the answer that costs $180,000.
We've implemented 150+ Odoo systems. The ones with proper backup and recovery setup sleep soundly. The ones without? We've seen them lose $40,000-$180,000 in downtime, unrecoverable data, and emergency consulting costs when disaster strikes.
Real Disasters We've Seen
Power surge in data center
Corrupted Odoo database. Recovery took 18 hours because backups weren't automated.
Bad configuration deployment
Broke GL posting. Restored from backup, but backup was 7 days old. Lost 847 orders worth of GL entries.
Ransomware attack
Locked production data. Had a backup but never tested it. Restore failed. Lost 6 days of operations.
None of those companies had a documented, tested backup and recovery plan.
The Backup Architecture (What Actually Works)
Before you implement anything, understand what needs to be backed up.
Odoo consists of two parts:
1. The Database (PostgreSQL)
✓ All business data (customers, orders, GL entries, inventory)
✓ All configurations (workflows, custom fields, GL account mappings)
✓ All user data (dashboards, filters, custom reports)
2. The FileStore
✓ Attachments (invoices, quotations, documents)
✓ Product images
✓ Website content
✓ Any binary files uploaded by users
⚠️ Critical: Both must be backed up together. If you restore database without filestore, your invoices will have missing PDFs. If you restore filestore without database, you'll have orphaned images.
Layer 1: Odoo.sh Cloud (Easiest Path)
Good news: Odoo.sh handles automatic backups for you. You just need to understand how to use them.
Step 1: Understand Your Backup Schedule
By default, Odoo.sh creates:
| Backup Type | Frequency | Retention |
|---|---|---|
| Hourly backups | Every hour | Last 48 hours (6 most recent) |
| Daily backups | Every day | Last 30 days |
| Weekly backups | Every week | Last 12 months |
This is adequate for most D2C brands. Hourly backups mean you never lose more than 1 hour of data.
Step 2: Create a Manual Backup (Before Risky Changes)
Before deploying a risky configuration change, take a manual backup.
1. Go to Odoo.sh Backups tab
2. Click "Create Backup"
3. System takes a snapshot (usually 5-15 minutes depending on database size)
4. You now have a backup you can restore to anytime
Cost: Free (included with Odoo.sh)
When to use: Before deploying custom modules, before major configuration changes, before third-party integrations go live
Step 3: Test Your Backup (Critical!)
Most D2C brands have never actually tested a restore. Then when they need it, the restore fails and they panic.
Don't be that brand.
Test procedure (takes 30 minutes):
1. Go to Backups in Odoo.sh
2. Find a backup from a few days ago
3. Click "Restore" → Choose "Create as new database" (name: odoo_test_restore)
4. Wait for restore to complete (5-15 minutes)
5. Test: Log in as admin, check 5 random orders, verify GL totals, check inventory
6. Delete the test database (to avoid confusion)
Do this once a month. Takes 30 minutes. Prevents $40,000+ disasters.
Layer 2: Self-Hosted Odoo (Automated Backups)
Self-hosted means Odoo is running on your server (or AWS EC2, DigitalOcean, etc.). You control the backup infrastructure.
Step 1: Set Up Automated Daily Backups
Create a backup script that runs every night.
#!/bin/bash
# Configuration
BACKUP_DIR="/backups/odoo"
DB_NAME="odoo_production"
DB_USER="postgres"
TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S)
BACKUP_FILE="$BACKUP_DIR/odoo_backup_$TIMESTAMP.dump"
FILESTORE_BACKUP="$BACKUP_DIR/filestore_backup_$TIMESTAMP.tar.gz"
LOG_FILE="/var/log/odoo_backup.log"
# Create backup directory
mkdir -p $BACKUP_DIR
# Log function
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> $LOG_FILE
}
log "Starting backup for database: $DB_NAME"
# Backup PostgreSQL database (binary format, faster)
pg_dump -U $DB_USER -Fc -d $DB_NAME > $BACKUP_FILE
if [ $? -eq 0 ]; then
log "Database backup successful: $BACKUP_FILE"
else
log "ERROR: Database backup failed!"
exit 1
fi
# Backup filestore directory
tar -czf $FILESTORE_BACKUP /opt/odoo/filestore 2>/dev/null
if [ $? -eq 0 ]; then
log "FileStore backup successful: $FILESTORE_BACKUP"
else
log "ERROR: FileStore backup failed!"
exit 1
fi
# Delete backups older than 30 days (keep last 30 days)
find $BACKUP_DIR -type f -mtime +30 -delete
# Log completion
log "Backup completed. Current backup files:"
ls -lh $BACKUP_DIR >> $LOG_FILE
log "Backup process finished successfully"
exit 0
sudo chmod +x /usr/local/bin/odoo_backup.sh
# Test it manually
/usr/local/bin/odoo_backup.sh
# Check log to verify success
cat /var/log/odoo_backup.log
Step 2: Automate With Cron (Run Daily at 2 AM)
crontab -e
# Add this line:
0 2 * * * /usr/local/bin/odoo_backup.sh >> /var/log/odoo_backup_cron.log 2>&1
# Verify it's scheduled:
crontab -l
This runs the backup script every day at 2 AM.
Step 3: Add Cloud Backup (For Disaster Recovery)
Local backups are fast (good for recovery). Cloud backups are offsite (good for disaster recovery if your data center burns down).
Backup to AWS S3 (Recommended):
#!/bin/bash
# AWS configuration
AWS_BUCKET="my-company-odoo-backups"
AWS_REGION="us-east-1"
BACKUP_DIR="/backups/odoo"
LOG_FILE="/var/log/odoo_backup_s3.log"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> $LOG_FILE
}
log "Starting S3 upload"
# Upload recent backups to S3
aws s3 sync $BACKUP_DIR s3://$AWS_BUCKET/ \
--region $AWS_REGION \
--sse AES256 \
--delete
if [ $? -eq 0 ]; then
log "S3 upload successful"
else
log "ERROR: S3 upload failed"
exit 1
fi
log "S3 sync completed"
exit 0
30 3 * * * /usr/local/bin/odoo_backup_s3.sh >> /var/log/odoo_backup_s3_cron.log 2>&1
S3 Cost: ~$0.023/GB/month
If you keep 30 days of backups at 1GB each: ~$0.69/month
Negligible cost. Worth it.
Step 4: Restore From a Backup (Emergency Procedure)
If production database is corrupted, here's how to restore:
⚠️ Before you start: Stop and investigate first. Don't restore reactively. Restore to a test database first. Not production.
sudo systemctl stop odoo
sudo su - postgres
# Create new database
createdb odoo_restored
# Give Odoo user access
psql -d postgres -c "ALTER DATABASE odoo_restored OWNER TO odoo;"
exit
# For binary format (pg_dump -Fc)
pg_restore -U postgres -d odoo_restored /backups/odoo/odoo_backup_2025-12-19_02-00-00.dump
# Or for SQL format
psql -U postgres -d odoo_restored < /backups/odoo/odoo_backup_2025-12-19_02-00-00.sql
# Extract filestore from backup
tar -xzf /backups/odoo/filestore_backup_2025-12-19_02-00-00.tar.gz -C /opt/odoo/
# Edit /etc/odoo/odoo.conf:
[options]
db_name = odoo_restored
db_user = odoo
db_password = [your_password]
# Restart Odoo
sudo systemctl restart odoo
Timeline: 45 minutes to 2 hours depending on database size
Layer 3: Backup Monitoring (Verify Backups Run)
The #1 mistake: Setting up backups but never verifying they actually run.
Months later, you need a backup. You discover the backup script failed 3 months ago and nobody noticed. Now you have no recent backups.
Don't be that company.
Simple Backup Verification Script
#!/bin/bash
# Check if a backup was created in the last 24 hours
BACKUP_DIR="/backups/odoo"
CUTOFF=$(($(date +%s) - 86400)) # 24 hours ago
RECENT_BACKUPS=$(find $BACKUP_DIR -type f -name "*.dump" -newer /tmp/24hours 2>/dev/null | wc -l)
if [ $RECENT_BACKUPS -eq 0 ]; then
# No recent backups! Send alert
echo "ALERT: No backups found in last 24 hours!" | mail -s "Odoo Backup Failed" your-email@company.com
exit 1
else
echo "Backup check successful. Found $RECENT_BACKUPS recent backups."
exit 0
fi
30 8 * * * /usr/local/bin/check_odoo_backup.sh
Layer 4: Security & Compliance
If you're handling customer data (you are), backups must be encrypted.
Encryption at Rest
Odoo.sh: Already encrypted by default (AES-256). No action needed.
Self-hosted on AWS: Use S3 server-side encryption (--sse AES256)
# Encrypt backup before uploading
gpg --symmetric --cipher-algo AES256 /backups/odoo/odoo_backup_2025-12-19.dump
# Creates: odoo_backup_2025-12-19.dump.gpg
Data Retention & Compliance
For GDPR/compliance:
• Keep daily backups: 30 days
• Keep weekly backups: 12 months
• Keep monthly backups: 7 years (for financial compliance)
# Delete backups older than 7 years
find $BACKUP_DIR -mtime +2555 -delete # 2555 days = ~7 years
Recovery Point Objective (RPO) & Recovery Time Objective (RTO)
RPO = Maximum acceptable data loss
RTO = Maximum acceptable downtime
For a typical $2M D2C brand:
| Metric | Target | Meaning |
|---|---|---|
| RPO | 1 hour | Lose up to 1 hour of data (hourly backups) |
| RTO | 2 hours | System back online within 2 hours |
Your current setup (with this guide):
• RPO: 1 hour
• RTO: 2 hours
• Cost: $0-$400/month
This is reasonable for most D2C brands.
Action Items: Protect Your Odoo Data
For Odoo.sh Users (Easiest)
❏ Log into Odoo.sh dashboard
❏ Verify backups are being created (go to Backups tab)
❏ Test a restore: Restore a 3-day-old backup to a test database
❏ Document the test results (when you tested, what data you verified)
❏ Schedule monthly tests (calendar reminder)
For Self-Hosted Users
❏ Create backup script (use the one above)
❏ Test it manually: /usr/local/bin/odoo_backup.sh
❏ Set up cron job to run daily
❏ Set up S3 backup for offsite storage
❏ Set up backup monitoring (verify backups actually happen)
❏ Test a restore to a non-production database
❏ Document the test results
Frequently Asked Questions
How often should I test my backups?
Monthly. Takes 30 minutes. Restore a backup to a test database, verify data is correct, delete the test database. This ensures backups actually work when you need them.
Should I use Odoo.sh or self-hosted for backups?
Odoo.sh for most D2C brands. It's automatic, tested, and costs $0 extra. Self-hosted requires managing scripts, monitoring, and S3 storage but gives you more control.
What's the cost of not having proper backups?
One data loss incident costs $40,000-$180,000 in downtime, unrecoverable data, and emergency consulting. Proper backups cost $0-$400/month. The ROI is 450x.
Do I need to backup both database and filestore?
Yes. Database has all business data. Filestore has attachments (invoices, images). If you restore database without filestore, invoices will have missing PDFs. Both must be backed up together.
Free Backup & Recovery Audit
Stop guessing about whether your backups actually work. We'll assess your current backup setup, verify backups are running and testable, identify gaps, and build a tested recovery runbook. Most D2C brands discover their backups either don't exist or have never been tested. One incident without proper backups costs $40,000-$180,000.
