Logo

Complete FiveM server backup and restore

Complete FiveM server backup and restore

Back up your full FiveM server (resources, MySQL DB, config) at VeryCloud with Wisp + mysqldump + offsite, and restore in disaster scenarios.

Introduction

A FiveM server is two things: files (resources, server.cfg, txData) and the MySQL DB (identifiers, economy, characters). Both must be backed up coherently. A files-only backup without the DB = nearly useless for an RP/economy server.

Prerequisites

  • A FiveM server at VeryCloud (Wisp panel)
  • An associated MySQL DB (local or external)
  • Optional: external VPS for offsite

Step 1: What to back up

ElementImportanceMethod
/resources/CriticalWisp Backup or SFTP
/server.cfgCriticalWisp Backup
/txData/ (txAdmin)CriticalWisp Backup
MySQL DBCriticalSeparate mysqldump
LogsOptionalGDPR-dependent
FiveM cacheUselessExclude (regenerable)

Step 2: Wisp schedule for files

In Wisp → Schedules:

  1. Create Schedule
  2. Name: Daily files backup 3 AM
  3. Cron: 0 3 * * *
  4. Only when online: yes
  5. Add Task: Create Backup, name daily-{date}

Wisp snapshots /home/container/ (resources + config + txData).

Step 3: MySQL backup with mysqldump

Wisp does NOT back up the DB (it's external to the FiveM container). Do it yourself.

On your MySQL server (or external VPS with remote access):

#!/bin/bash
set -e

DB_HOST="your.mysql.host"
DB_USER="fivem_backup_user"
DB_PASS_FILE="/root/.mysql_pass"   # chmod 600
DB_NAME="fivem_db"

DEST="/backups/mysql"
mkdir -p "$DEST"

DATE=$(date +%Y%m%d_%H%M%S)
FILE="$DEST/fivem_${DATE}.sql.gz"

mysqldump \
  -h "$DB_HOST" -u "$DB_USER" -p"$(cat $DB_PASS_FILE)" \
  --single-transaction --quick --lock-tables=false \
  --routines --triggers --events \
  "$DB_NAME" | gzip > "$FILE"

echo "Backup: $FILE ($(du -h $FILE | cut -f1))"

# Rotate: keep 14 days
find "$DEST" -name "fivem_*.sql.gz" -mtime +14 -delete

Cron:

0 2 * * * /usr/local/bin/mysql-backup-fivem.sh >> /var/log/mysql-backup.log 2>&1

--single-transaction is essential to avoid locking the DB.

Step 4: Dedicated backup MySQL user

Minimal privileges:

CREATE USER 'fivem_backup_user'@'IP_BACKUP_HOST' IDENTIFIED BY 'solid_pass';
GRANT SELECT, SHOW VIEW, LOCK TABLES, EVENT, TRIGGER ON fivem_db.* TO 'fivem_backup_user'@'IP_BACKUP_HOST';
FLUSH PRIVILEGES;

No DROP, no INSERT — read-only.

Step 5: Offsite with rclone

On the backup VPS:

# One-time config
rclone config

# Daily sync
rclone sync /backups/mysql b2:mybucket/fivem-mysql \
  --transfers 4 \
  --backup-dir b2:mybucket/fivem-old/$(date +%F)

Cron:

30 4 * * * rclone sync /backups/mysql b2:mybucket/fivem-mysql --transfers 4

Step 6: Test a restore

Monthly. On a staging:

Restore files:

  1. Create a staging FiveM server
  2. Wisp → Backups → restore the latest backup to that env

Restore DB:

gunzip < /backups/mysql/fivem_20260516_020000.sql.gz > /tmp/restore.sql
mysql -h STAGING_DB_HOST -u staging_user -p staging_db < /tmp/restore.sql

Start the staging server, verify players/vehicles/houses are there.

Step 7: Incident restore procedure

Scenario: prod compromised or data lost.

Step 1 — Communicate — Announce immediate maintenance in Discord/Twitter. Block reconnections.

Step 2 — Identify restore point — Last backup BEFORE the problem. 5 min to think.

Step 3 — Restore files — Wisp → Backups → restore.

Step 4 — Restore DB:

mysql -h DB_HOST -u root -p
DROP DATABASE fivem_db;
CREATE DATABASE fivem_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
exit

gunzip < /backups/mysql/fivem_GOOD_DATE.sql.gz | \
  mysql -h DB_HOST -u root -p fivem_db

Step 5 — Restart + verify — Start server, check logs, validate (connect in-game, look at a known character).

Step 6 — Communicate return.

Step 8: Backups before major changes

Before:

  • Framework update (ESX, QBCore)
  • Importing custom scripts
  • DB schema change
  • FiveM artifacts update

Manual snapshot Wisp + manual MySQL dump.

mysqldump -u user -p --single-transaction db_name | gzip > manual_$(date +%F_%H%M).sql.gz

Step 9: 3-2-1 recap

  • 3 copies: Wisp local + backup VPS + cloud (B2/S3)
  • 2 media: Wisp + your external VPS
  • 1 offsite: remote cloud

€5-10/month in cloud storage protects hundreds of hours of accumulated gameplay.

Step 10: Monitor backups

You want to know if a backup failed:

  • Healthchecks.io: ping after each OK backup
  • Discord webhook: success/failure notification
  • Mail alert if no backup for >25h

Discord webhook in script:

curl -X POST -H "Content-Type: application/json" \
  -d "{\"content\":\"MySQL backup OK: ${FILE}\"}" \
  https://discord.com/api/webhooks/.../...

Troubleshooting

mysqldump: Got error: 1142: SELECT, LOCK TABLES command denied — backup user lacks LOCK TABLES. GRANT LOCK TABLES. Or use --lock-tables=false (combined with --single-transaction). Huge backup (several GB) — logs or cache tables too big. Truncate before backup. Enable framework log rotation. DB restore fails mid-stream — schema mismatch (collation, MySQL version). Verify same MySQL version staging/prod. Wisp backup hits quota — scale plan or reduce retention. Exclude cache (cache/ is regenerable).

Useful commands

mysqldump --single-transaction db | gzip > db.sql.gz
du -sh /backups/
gunzip < backup.sql.gz | mysql db
gunzip -t backup.sql.gz

Conclusion

Complete FiveM backup = Wisp Schedules (files) + mysqldump cron (DB) + cloud offsite. 3 independent levels, retested monthly, sleep tight. Classic trap = backing up only Wisp and forgetting the DB. An RP economy disappearing = your community leaving.

Going further: full CI automation, healthchecks + Discord/Slack alerting, dedup with restic to optimize storage.

Resources

Join our Discord community server

For any questions, suggestions, or just to chat with the community, join us on Discord!

900+Members