How to back up and restore Matomo
A Matomo backup is the MySQL or MariaDB database plus the Matomo directory, above all config/config.ini.php, which holds the database password and the salt that API tokens are hashed with, and the Marketplace plugins in plugins/. Dump the database with mysqldump --single-transaction. The raw log tables cannot be rebuilt; archived reports can be re-processed only for periods whose raw logs still exist.
What Matomo stores and where
Matomo, formerly Piwik, is open-source web analytics under the GPL v3 or later. This guide covers Matomo 5 (5.14.1 was released on 4 October 2026; Matomo 6 is in beta). Matomo lives in /var/www/matomo, PHP runs as www-data, and the database is matomo with the default table prefix matomo_.
| Part | Where | Back it up? |
|---|---|---|
| Raw log data | matomo_log_visit, matomo_log_link_visit_action, matomo_log_action, matomo_log_conversion, matomo_log_conversion_item | Yes. Every visit and action. Cannot be rebuilt. |
| Archived reports | matomo_archive_numeric_YYYY_MM, matomo_archive_blob_YYYY_MM | Yes. Rebuildable only from raw logs that still exist. |
| Sites, users, goals, settings | matomo_site, matomo_user, matomo_goal, matomo_option and others | Yes. |
config.ini.php | config/ | Yes, on its own and encrypted. |
| Marketplace plugins | plugins/, beside the bundled ones | Yes. |
| Custom logo and favicon | misc/user/ | Yes. |
| GeoIP databases | misc/*.mmdb | Optional. Can be downloaded again. |
| Tag Manager containers | js/container_*.js | Optional. Generated from the database. |
| Caches | tmp/ | No. Keep the folder. |
Matomo's best-practice page asks for a full database backup every day, kept 30 days, the Matomo directory daily, and backup storage of 10 times the uncompressed database size.
Raw logs, archives, and what re-archiving can rebuild
The tracker writes raw log rows. core:archive turns them into reports, stored in two tables per month, archive_numeric for metrics and archive_blob for reports. Archives can be re-processed for any period whose raw logs remain, with core:invalidate-report-data and core:archive.
On a self-hosted install Matomo deletes nothing by default, but "Regularly delete old raw data from the database" under Administration > Privacy > Anonymize data removes logs past a cutoff. From then on, the archives are the only copy of those reports, and Matomo's FAQ warns that reprocessing them loses data. Back up the archive tables. Check what takes the space:
mysql --defaults-extra-file=/etc/mysql/matomo-backup.cnf -e "SELECT table_name, ROUND((data_length + index_length) / 1048576) AS mb FROM information_schema.tables WHERE table_schema = 'matomo' ORDER BY data_length + index_length DESC LIMIT 10"On a single database server above 10 GB or 1 million actions a month, Matomo's FAQ recommends Percona XtraBackup over mysqldump; with replication, it recommends dumping a replica. See XtraBackup and backing up from a replica.
Dump the database with mysqldump
install -d -m 700 /var/backups/matomoCopy the user and password from the [database] section of config.ini.php into an option file, so the password stays out of ps:
[client]
user=matomo
password="your-password-here"
host=localhostchmod 600 /etc/mysql/matomo-backup.cnfmysqldump --defaults-extra-file=/etc/mysql/matomo-backup.cnf --single-transaction --quick --no-autocommit --no-tablespaces matomo | gzip > /var/backups/matomo/matomo-db-$(date +%F).sql.gz--single-transactionreads every table from one consistent snapshot without locking, so tracking continues. Matomo creates InnoDB tables by default.--quickstreams rows instead of buffering whole tables, which matters for the log tables.--no-autocommitwraps each table's inserts in one transaction, which speeds up the import; Matomo's FAQ uses both.--no-tablespacesavoids the globalPROCESSprivilege. On MariaDB 11 the program is calledmariadb-dump.
A complete dump ends with -- Dump completed on. Schedule it away from core:archive: a table created or optimized during the dump breaks it (error 1412, below). The mysqldump guide covers the rest.
Keep config.ini.php and the salt
config.ini.php holds the [database] settings, trusted_hosts[], any SMTP password, and the salt the installer generated. Matomo hashes every stored token_auth with the salt and signs its cookies with it. Under a new salt, every API token stops working: reports pulled by scripts, dashboards and apps fail until users create new tokens. Reinstalling Matomo over the old database, as one of Matomo's move guides describes, writes a new config.ini.php with a new salt; copying the original file avoids that.
tar -czf /var/backups/matomo/matomo-config-$(date +%F).tar.gz -C /var/www matomo/config/config.ini.phpThis file holds the database password and the salt. Store its archive apart from the dumps, encrypt it, and archive it again whenever it changes.
Archive the Matomo directory
tar -czf /var/backups/matomo/matomo-files-$(date +%F).tar.gz --exclude='matomo/tmp/*' --exclude='matomo/config/config.ini.php' -C /var/www matomoThat covers plugins, misc/user/, GeoIP files and the exact Matomo version. The official Docker image keeps everything under a volume at /var/www/html; see Docker volume backups.
Automate it with cron
#!/bin/bash
set -euo pipefail
APP_DIR="/var/www"
APP="matomo"
DB_NAME="matomo"
BACKUP_DIR="/var/backups/matomo"
KEEP_DAYS=30
STAMP="$(date +%Y-%m-%d_%H%M)"
DB="$BACKUP_DIR/$APP-db-$STAMP.sql.gz"
FILES="$BACKUP_DIR/$APP-files-$STAMP.tar.gz"
trap 'rm -f "$DB.partial" "$FILES.partial"' EXIT
mysqldump --defaults-extra-file=/etc/mysql/matomo-backup.cnf \
--single-transaction --quick --no-autocommit --no-tablespaces \
"$DB_NAME" | gzip > "$DB.partial"
gunzip -c "$DB.partial" | tail -n 1 | grep -q "Dump completed"
mv "$DB.partial" "$DB"
tar -czf "$FILES.partial" --exclude="$APP/tmp/*" \
--exclude="$APP/config/config.ini.php" -C "$APP_DIR" "$APP" || [ $? -eq 1 ]
mv "$FILES.partial" "$FILES"
find "$BACKUP_DIR" -type f \( -name "$APP-db-*" -o -name "$APP-files-*" \) -mtime +"$KEEP_DAYS" -deletechmod 755 /usr/local/bin/matomo-backup.shPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
35 3 * * * root flock -n /run/lock/matomo-backup.lock /usr/local/bin/matomo-backup.sh >> /var/log/matomo-backup.log 2>&1Pick a time your archiving cron is idle; Matomo's example runs it at minute 5 of every hour. Copy the files off the server each night, for example with rclone.
Restore on a new server
Install a web server, PHP 8 with pdo_mysql, and MySQL 8 or MariaDB. Create the database and a user with the privileges Matomo's requirements list (it also asks for the global FILE privilege, which speeds up archiving):
CREATE DATABASE matomo CHARACTER SET utf8mb4;
CREATE USER 'matomo'@'localhost' IDENTIFIED BY 'your-password-here';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, INDEX, DROP, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES ON matomo.* TO 'matomo'@'localhost';Create the option file from earlier on this server, load the dump, and put the files back:
gunzip -c /var/backups/matomo/matomo-db-2026-10-04.sql.gz | mysql --defaults-extra-file=/etc/mysql/matomo-backup.cnf matomotar -xzf /var/backups/matomo/matomo-files-2026-10-04.tar.gz -C /var/wwwtar -xzf /var/backups/matomo/matomo-config-2026-10-04.tar.gz -C /var/wwwchown -R www-data:www-data /var/www/matomoEdit [database] in config.ini.php if the host, user or password changed; keep salt and tables_prefix. If Matomo answers on a new hostname, add it, then clear the caches:
sudo -u www-data php /var/www/matomo/console config:set 'General.trusted_hosts[]="stats.example.net"'sudo -u www-data php /var/www/matomo/console core:clear-cachesA new Matomo URL also means updating the tracking code on every tracked site. Set up the archiving cron again and run it once:
sudo -u www-data php /var/www/matomo/console core:archive --url=https://stats.example.net/Visits tracked by the old server after the dump are not in the restore, so switch soon after the final dump. The directory archive brings back the same Matomo version, as Matomo's move FAQ asks; a newer one may run a database migration that takes minutes or hours. If reports are missing or wrong while the raw logs still exist, invalidate them and archive again:
sudo -u www-data php /var/www/matomo/console core:invalidate-report-data --dates=2026-01-01,2026-10-04 --sites=allTest restores and verification
A restored copy runs your scheduled email reports too. Matomo's backup FAQ suggests disabling emails on a test instance:
sudo -u www-data php /var/www/matomo/console config:set 'General.emails_enabled=0'sudo -u www-data php /var/www/matomo/console diagnostics:runmysql --defaults-extra-file=/etc/mysql/matomo-backup.cnf matomo -e "SELECT COUNT(*), MAX(visit_last_action_time) FROM matomo_log_visit"Compare the count and the newest visit with the live server, sign in, open yesterday's Visits Log, and call the API with an existing token to prove the salt survived. Testing restores explains how to schedule this.
GDPR: backups hold visitor data
The log tables hold IP addresses (Matomo 5 masks two bytes by default), visitor IDs, any User IDs you send, page URLs and titles, locations, and ecommerce orders. Every dump holds the same, so treat it as personal data under the GDPR:
- Raw-data deletion only purges the live database. With logs deleted after 180 days and backups kept 30, a visit can survive about 210 days. State that in your privacy policy and set a matching retention policy.
- GDPR Tools (Administration > Privacy) deletes a data subject from the live database only. A restore of an older backup brings those visits back: keep a log of erasure requests and run them again after any restore.
- The UK regulator's guidance accepts erased data staying in a backup until it is overwritten on schedule, if the backup is put "beyond use" meanwhile. Encrypt the backups and use them for nothing else.
Common errors
| Error | Fix |
|---|---|
A warning that starts You are now accessing Matomo from and names the configured address | Add the new hostname to trusted_hosts[]. |
Your Matomo codebase is running the old version followed by both version numbers | The dump comes from a newer Matomo. Install that version. |
Your Matomo database is out-of-date, and must be upgraded before you can continue. | The code is newer than the dump. Run console core:update --yes, with a backup in hand. |
SQLSTATE[HY000] [1045] Access denied for user | Fix [database] in config.ini.php, or the user's grants. |
An error naming a Matomo table and ending in doesn't exist | tables_prefix does not match the dump, or the import failed. |
| API calls with existing tokens are rejected | config.ini.php has a new salt. Restore the original, or create new tokens. |
mysqldump: Error 1412: Table definition has changed, please retry transaction | A table was created or optimized during the dump. Run it again outside archiving. |
Access denied; you need (at least one of) the PROCESS privilege(s) for this operation | Add --no-tablespaces. |
Frequently asked questions
- Can I leave the archive tables out of a Matomo backup?
- Only if raw-data deletion has never been on, so every report can be rebuilt from the log tables. Rebuilding means invalidating the reports and running core:archive, which can take hours on a busy site. Matomo recommends a full backup.
- What happens if I lose config.ini.php?
- Matomo can be reinstalled against the existing tables with the same table prefix, but the new file gets a new salt, so every API token stops working and users must create new ones.
- How much storage do Matomo backups need?
- Matomo recommends a backup host with 10 times the uncompressed database size, for daily full backups kept 30 days. Compressed dumps are much smaller, but the archive tables grow every month.
- Do Matomo backups contain personal data?
- Yes. They hold the same visitor data as the live database, including IP addresses (masked by default), visitor IDs and any User IDs. Encrypt them and keep them only as long as your privacy policy states.
How this was checked
Commands, limits and prices were checked against these official pages, on October 4, 2026:
- Matomo FAQ: How do I backup and restore the Matomo data?
- Matomo FAQ: Backup Matomo best practises (what to back up, how often, storage)
- Matomo FAQ: How do I backup and restore Matomo (database, config.ini.php, plugins)
- Matomo FAQ: How do I move Matomo to another server?
- Matomo FAQ: How do I move Matomo to a new domain?
- Matomo FAQ: Managing your database's size (raw data and report deletion)
- Matomo FAQ: How do I force the reports to be re-processed from the logs?
- Matomo FAQ: How to set up auto-archiving of your reports
- Matomo FAQ: Requirements (MySQL user privileges)
- Matomo FAQ: What data does Matomo track?
- Matomo developer documentation: Database schema (log data and archive tables)
- Matomo 5.14.1 release
- Matomo 5.14.1 source: config/global.ini.php (database, trusted_hosts, emails_enabled, Deletelogs)
- Matomo 5.14.1 source: SettingsPiwik::getSalt and UsersManager Model::hashTokenAuth
- Matomo 5.14.1 source: Installation controller (salt generated at install)
- Matomo 5.14.1 source: console commands config:set, core:invalidate-report-data, core:version
- Matomo 5.14.1 source: CustomLogo (misc/user)
- Matomo 5.14.1 source: PrivacyManager Config (IP anonymization defaults)
- Matomo 5.14.1 source: FrontController (database newer than code check) and language files
- Matomo Tag Manager source: container file location
- Docker Official Images documentation: matomo
- MySQL 8.4 Reference Manual: mysqldump
- MySQL 8.4 source: mysqldump.cc (error format) and error 1412
- ICO (UK GDPR guidance): Right to erasure, backup systems