The silent disaster
Backups fail silently. A disk fills up, a password rotates, a network changes — and your nightly cron keeps exiting non-zero without anyone knowing. When you need the backup, it does not exist. Nerve sends a push the moment it fails.
PostgreSQL (pg_dump)
#!/bin/bash
set -euo pipefail
export NERVE_DSN="nerve://TOKEN:[email protected]"
DB="production"
BACKUP_DIR="/var/backups/postgres"
TIMESTAMP=$(date +%Y%m%d_%H%M)
if pg_dump "$DB" | gzip > "$BACKUP_DIR/${DB}_${TIMESTAMP}.sql.gz"; then
SIZE=$(du -h "$BACKUP_DIR/${DB}_${TIMESTAMP}.sql.gz" | cut -f1)
echo "Backup OK: $DB ($SIZE) on $(hostname)" | nerve send
else
echo "BACKUP FAILED: pg_dump $DB on $(hostname)" | nerve send --severity critical
fi
MySQL / MariaDB (mysqldump)
#!/bin/bash
set -euo pipefail
export NERVE_DSN="nerve://TOKEN:[email protected]"
DB="app_production"
BACKUP_DIR="/var/backups/mysql"
TIMESTAMP=$(date +%Y%m%d_%H%M)
if mysqldump --single-transaction "$DB" | gzip > "$BACKUP_DIR/${DB}_${TIMESTAMP}.sql.gz"; then
echo "Backup OK: $DB on $(hostname)" | nerve send
else
echo "BACKUP FAILED: mysqldump $DB on $(hostname)" | nerve send --severity critical
fi
MongoDB (mongodump)
#!/bin/bash
set -euo pipefail
export NERVE_DSN="nerve://TOKEN:[email protected]"
DB="app"
BACKUP_DIR="/var/backups/mongo"
TIMESTAMP=$(date +%Y%m%d_%H%M)
if mongodump --db="$DB" --archive="$BACKUP_DIR/${DB}_${TIMESTAMP}.gz" --gzip; then
echo "Backup OK: mongo/$DB on $(hostname)" | nerve send
else
echo "BACKUP FAILED: mongodump $DB on $(hostname)" | nerve send --severity critical
fi
Check backup age (dead man's switch)
Catch silently broken backup crons: alert if the latest backup is older than expected.
#!/bin/bash
export NERVE_DSN="nerve://TOKEN:[email protected]"
BACKUP_DIR="/var/backups/postgres"
MAX_AGE_HOURS=26 # Nightly backup should be less than 26 hours old
LATEST=$(find "$BACKUP_DIR" -name "*.sql.gz" -type f -printf '%T@\n' | sort -n | tail -1)
if [ -z "$LATEST" ]; then
echo "NO BACKUPS FOUND in $BACKUP_DIR on $(hostname)" | nerve send --severity critical
exit 1
fi
AGE_HOURS=$(( ($(date +%s) - ${LATEST%.*}) / 3600 ))
if [ "$AGE_HOURS" -gt "$MAX_AGE_HOURS" ]; then
echo "STALE BACKUP: latest is ${AGE_HOURS}h old on $(hostname)" | nerve send --severity critical
fi
Check backup size (catch empty dumps)
LATEST_FILE=$(ls -t /var/backups/postgres/*.sql.gz 2>/dev/null | head -1)
if [ -n "$LATEST_FILE" ]; then
SIZE=$(stat -c%s "$LATEST_FILE")
if [ "$SIZE" -lt 1000 ]; then
echo "SUSPICIOUS BACKUP: $LATEST_FILE is only $SIZE bytes" | nerve send --severity alert
fi
fi
Crontab
# Nightly backup at 2:30 AM
30 2 * * * /usr/local/bin/backup-postgres-nerve.sh
# Check backup age at 8 AM
0 8 * * * /usr/local/bin/check-backup-age.sh
Quick start
go install github.com/nerve-ink/nerve-cli/cmd/nerve@latest
export NERVE_DSN="nerve://TOKEN:[email protected]"
echo "BACKUP FAILED: pg_dump production on db-1" | nerve send --severity critical
FAQ
How do I get notified when a database backup fails?
Wrap your dump command in a script that checks the exit code and pipes a failure message to nerve send.
Can I also confirm successful backups?
Yes. Send a signal on success too — if you stop getting success signals, something is wrong with the entire cron chain.
Is my database connection info exposed?
Never include credentials in the alert. Send only the database name, status, and timestamp. Nerve encrypts the payload, but keeping secrets out of the message is good hygiene.