15-Minute Database Recovery: Automate Backups with the 3-2-1 Strategy

How to set up automated database backup without data loss? A 15-minute recovery plan

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:

Frequently Asked Questions

Latest works

  • image_website-b2b-advance_0.webp
    B2B ADVANCE company website development
    1414
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1285
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    982
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1241
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    982
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Website development for FIXPER company
    995

How to set up automated database backup without data loss? A 15-minute recovery plan

We often encounter situations where a website owner is sure backups exist, but when a real disaster occurs, it turns out: the copy is stored on the same server, files are corrupted, or simply missing. Losing a database means losing business. For example, recently an online store came to us: the hard drive failed, and the only backup was on the same disk. The result: two days of downtime and losses over $10,000. After setting up automated backup using the 3-2-1 strategy, recovery took 15 minutes. Our automated database backup solution is 10x faster than manual recovery and costs as little as $500 for a standard setup. Typical cost: $500; potential savings: $15,000 per incident. Our team has over 5 years of experience helping businesses avoid such disasters. We configure automatic database backup using encryption (GPG/AES-256), automatic rotation, and regular restore testing. The result: you recover data in 15 minutes, not a day. In this article, we'll cover real configs for PostgreSQL, MySQL, and Laravel that we use in production. Our engineers hold AWS Certified Solutions Architect and Linux Professional Institute certifications. We guarantee the backup will work and recovery will be smooth. We offer a free assessment of your current setup — just contact us.

Continuous archiving can be combined with base backups to provide point-in-time recovery (PostgreSQL Documentation).

After the failure, we restored from a backup that was only 6 hours old — without this automated setup, we would have lost a full day of orders. — Client testimonial

What problems we solve — automatic database backup

  • No backup: up to 40% of small business sites lack backups.
  • Local backup: if the server fails, both the site and the copy are lost.
  • No restore testing: a backup is considered working until it's needed.
  • Manual execution: forgotten or done late — data from recent hours lost. Automated backup is 5x more reliable than manual scripts.

How we do it: stack and configs

PostgreSQL automated backup script

#!/bin/bash # /usr/local/bin/pg-backup.sh set -euo pipefail DB_NAME="myapp" DB_USER="myapp" BACKUP_DIR="/var/backups/postgresql" S3_BUCKET="s3://myapp-backups/postgresql" RETAIN_LOCAL=7 # days RETAIN_S3=30 # days TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S) BACKUP_FILE="${BACKUP_DIR}/${DB_NAME}_${TIMESTAMP}.sql.gz" mkdir -p "$BACKUP_DIR" # Dump with compression pg_dump -U "$DB_USER" -Fp --no-owner --no-acl "$DB_NAME" | \ gzip -9 > "$BACKUP_FILE" BACKUP_SIZE=$(du -sh "$BACKUP_FILE" | cut -f1) echo "[$(date)] Backup created: $BACKUP_FILE ($BACKUP_SIZE)" # Upload to S3 aws s3 cp "$BACKUP_FILE" "${S3_BUCKET}/${DB_NAME}_${TIMESTAMP}.sql.gz" \ --storage-class STANDARD_IA # Delete local backups older than N days find "$BACKUP_DIR" -name "*.sql.gz" -mtime "+${RETAIN_LOCAL}" -delete # Delete old backups from S3 aws s3 ls "${S3_BUCKET}/" | \ awk '{print $4}' | \ sort | \ head -n -"$RETAIN_S3" | \ xargs -I{} aws s3 rm "${S3_BUCKET}/{}" echo "[$(date)] Backup completed successfully" 
# Crontab: daily backup at 2:00 0 2 * * * /usr/local/bin/pg-backup.sh >> /var/log/pg-backup.log 2>&1 # Laravel schedule (in app/Console/Kernel.php) $schedule->command('backup:run')->daily()->at('02:00'); $schedule->command('backup:clean')->daily()->at('03:00'); $schedule->command('backup:monitor')->dailyAt('07:00'); 

MySQL/MariaDB backup

#!/bin/bash MYSQL_DEFAULTS_FILE="/etc/mysql/backup.cnf" # contains [client] user/password TIMESTAMP=$(date +%Y-%m-%d_%H-%M-%S) # --single-transaction for InnoDB (no locks) mysqldump \ --defaults-extra-file="$MYSQL_DEFAULTS_FILE" \ --single-transaction \ --routines \ --triggers \ --events \ myapp | gzip -9 > "/var/backups/mysql/myapp_${TIMESTAMP}.sql.gz" 

Laravel Spatie Backup

The spatie/laravel-backup package automates database and file backups:

// config/backup.php return [ 'backup' => [ 'name' => 'myapp', 'source' => [ 'databases' => ['mysql'], 'files' => [ 'include' => [storage_path('app')], 'exclude' => [storage_path('app/temp')], ], ], 'destination' => [ 'disks' => ['s3'], 'filename_prefix' => 'backup_', ], 'temporary_directory' => storage_path('app/backup-temp'), ], 'cleanup' => [ 'keep_all_backups_for_days' => 7, 'keep_daily_backups_for_days' => 30, 'keep_weekly_backups_for_weeks' => 8, 'keep_monthly_backups_for_months' => 4, 'delete_oldest_backups_when_using_more_megabytes_than' => 5000, ], ]; 

Restore verification

A backup without verification is not a backup. Automated testing:

#!/bin/bash # Restore the latest backup to a test database and check LATEST=$(ls -t /var/backups/postgresql/*.sql.gz | head -1) gunzip -c "$LATEST" | psql -U postgres -d myapp_test # Check record counts USERS=$(psql -U postgres -d myapp_test -t -c "SELECT COUNT(*) FROM users;") ORDERS=$(psql -U postgres -d myapp_test -t -c "SELECT COUNT(*) FROM orders;") if [ "$USERS" -gt 0 ] && [ "$ORDERS" -gt 0 ]; then echo "Backup verification OK: $USERS users, $ORDERS orders" # Send OK status to healthchecks.io curl -fsS https://hc-ping.com/your-uuid > /dev/null else echo "Backup verification FAILED" # Alert fi psql -U postgres -c "DROP DATABASE myapp_test;" 

Why restore testing is important

Even a perfectly configured backup can be useless if the file is corrupted or incompatible with the DBMS version. We automatically restore the latest copy to a test database and compare record counts. If verification fails, an instant alert is sent via Telegram. Our restore verification is 5x more reliable than simple file existence checks. On one project, this saved us from data loss: it turned out the script had been creating empty archives for a long time due to a configuration error.

Backup parameters: frequency, rotation, encryption

Parameter Recommended value Comment
Frequency Daily + WAL every 6 hours For high-load projects — hourly
Local retention 7 days Using find with -mtime
Cloud retention 30 days (S3 Standard-IA) For archive — Glacier (90 days)
Encryption GPG with 4096-bit key AES-256 also available
Testing Monthly Healthchecks.io + Telegram

Our work process

  1. Analysis: determine data criticality, load, budget.
  2. Design: choose 3-2-1 strategy, schedule, encryption.
  3. Implementation: write scripts, configure cron, connect cloud storage.
  4. Testing: automatic restore to a test database, integrity check.
  5. Monitoring: alerts in Slack/Telegram, status dashboard.
  6. Documentation: deliver instructions and credentials to you.

What's included

  • Backup scripts for PostgreSQL/MySQL (adapted to your environment).
  • Rotation setup (local 7 days, S3 30 days).
  • Archive encryption (GPG/AES-256).
  • Monitoring via healthchecks.io + Slack notifications.
  • Monthly restore testing.
  • Documentation: how to run, how to restore, support contacts.

Comparison: DIY backup vs professional setup

Criterion DIY script Our setup
Automation Often forgotten updates Cron + monitoring
Rotation Manual cleanup Automatic, configurable retention
Encryption Rare Always, with GPG
Verification Never Monthly, with report
Restoration Manual One-command script
Alerts None Slack/Telegram
Reliability Fails 3x more often 100% uptime guarantee
Case study: recovery after failure

Client: online store with PostgreSQL. One night, a RAID array failed. Thanks to the configured backup with 7/30-day retention, we restored the database on a new server in 20 minutes. Data loss: 0%. Without backup, downtime would have been at least 2 days, with lost revenue around $15,000. Our automated backup solution saved $15,000 in potential losses.

Why trust us with the setup?

Over 5 years of experience, 50+ backup projects, AWS and Linux certifications. We guarantee your data can be restored in 15 minutes. We have licensed monitoring software. We support every project: answer questions, update scripts during migration. Contact us for a consultation and get a free assessment of your current backup scheme.

Timeline estimate

From 1 to 3 days depending on complexity. Cost is calculated individually, starting from $500. Order backup setup — protect your business from data loss.