How to back up Meilisearch
Meilisearch has two backups. A snapshot (--schedule-snapshot, or POST /snapshots) is a compressed copy of the database that imports fast but only into the exact same Meilisearch version; a dump (POST /dumps) is a portable export that rebuilds the indexes on import and moves to newer versions. Both restore only at launch, into an empty database, with --import-snapshot or --import-dump.
Snapshots or dumps
The Community Edition is MIT licensed; 1.54.3, from October 1, 2026, is current. Meilisearch Cloud has no snapshots and makes dumps only through support; this guide is for self-hosted instances.
| Snapshot | Dump | |
|---|---|---|
| What it is | Copy of the database files (data.ms), as .tar.gz | Export of documents, settings, tasks and keys, as .tar.gz |
| Import | Fast: unpacked as is | Slow: every index is rebuilt |
| Restores into | The same Meilisearch version only | The same or a newer version |
| File | <database dir>.snapshot, replaced by each new snapshot | <dumpUid>.dump, a new file each time |
| API keys | Included, in the copied auth database | Included without their secret values |
| Created by | --schedule-snapshot or POST /snapshots | POST /dumps |
Use both: snapshots for quick recovery, a dump for upgrades and as the copy any later version can read. Neither contains the master key or the instance's configuration (/etc/meilisearch.toml or the Docker environment). Back those up encrypted: without the same master key, every API key changes.
Where the files go
| Docker image | Official systemd setup | |
|---|---|---|
Database (--db-path, MEILI_DB_PATH) | /meili_data/data.ms | /var/lib/meilisearch/data |
Dumps (--dump-dir, MEILI_DUMP_DIR) | /meili_data/dumps | /var/lib/meilisearch/dumps |
Snapshots (--snapshot-dir, MEILI_SNAPSHOT_DIR) | /meili_data/snapshots | /var/lib/meilisearch/snapshots |
| Snapshot file | data.ms.snapshot | data.snapshot |
Both snapshots and dumps are first staged in TMPDIR (/tmp by default), not in their own directory. If /tmp is small, set TMPDIR to an existing directory on a disk with room for a full copy of the database. Run the image with a pinned tag and the settings in a root-only env file:
MEILI_ENV=production
MEILI_MASTER_KEY=a-long-random-master-key
MEILI_SCHEDULE_SNAPSHOT=86400docker run -d --name meilisearch --restart unless-stopped -p 127.0.0.1:7700:7700 --env-file /etc/meilisearch.env -v /srv/meili_data:/meili_data getmeili/meilisearch:v1.54.3MEILI_SCHEDULE_SNAPSHOT=86400 takes a snapshot every 86,400 seconds (24 hours); the environment variable must be a number of seconds. The first snapshot comes one interval after launch. On the command line, --schedule-snapshot with no value means 24 hours; in the TOML config file, schedule_snapshot = 86400 or true.
Each snapshot replaces the previous file, so the directory only ever holds one, and a damaged database can be snapshotted over your good copy. Copy it to a dated name elsewhere, as the script below does. Snapshots to S3 (--s3-bucket-url and related options) need the Enterprise Edition.
Create a key for backups
Keep the master key for managing keys, and give the backup script its own key with only the actions it needs:
curl -fsS -X POST "http://127.0.0.1:7700/keys" -H "Authorization: Bearer MASTER_KEY" -H "Content-Type: application/json" --data-binary '{"description": "Backups", "actions": ["dumps.create", "snapshots.create", "tasks.get", "stats.get"], "indexes": ["*"], "expiresAt": null}'Copy the key from the reply into a file only root can read (chmod 600). expiresAt is required; null means it never expires. MEILI_SNAPSHOT and MEILI_DUMPS are host paths, so for the systemd setup use /var/lib/meilisearch/snapshots/data.snapshot and /var/lib/meilisearch/dumps:
MEILI_URL=http://127.0.0.1:7700
MEILI_BACKUP_KEY=the-key-from-the-reply
MEILI_SNAPSHOT=/srv/meili_data/snapshots/data.ms.snapshot
MEILI_DUMPS=/srv/meili_data/dumpsCreate a dump and wait for it
curl -fsS -X POST "$MEILI_URL/dumps" -H "Authorization: Bearer $MEILI_BACKUP_KEY"The reply is a task with "status": "enqueued" and a taskUid. Dumps and snapshots go through the same queue as indexing, so they wait for earlier tasks. Poll the task:
curl -fsS "$MEILI_URL/tasks/42" -H "Authorization: Bearer $MEILI_BACKUP_KEY"status moves from enqueued to processing, then succeeded, failed (with the reason in error) or canceled. On success, details.dumpUid, such as 20261004-023012345, names the file 20261004-023012345.dump in the dump directory. Meilisearch never leaves a partial dump file. POST /snapshots works the same way.
Run it every night
This script takes a snapshot and a dump, waits for each, keeps dated copies in /var/backups/meilisearch, tests the dump's gzip stream and deletes copies older than two days. It needs jq. On a large instance, run the dump half weekly.
#!/bin/bash
set -euo pipefail
. /etc/meili-backup.env
AUTH="Authorization: Bearer $MEILI_BACKUP_KEY"
DEST=/var/backups/meilisearch
STAMP=$(date +%F-%H%M)
mkdir -p "$DEST"
wait_task() {
local status
while true; do
status=$(curl -fsS -H "$AUTH" "$MEILI_URL/tasks/$1" | jq -r '.status')
case "$status" in
succeeded) return 0 ;;
enqueued|processing) sleep 15 ;;
*) echo "$(date -Is) task $1 $status" >&2
curl -fsS -H "$AUTH" "$MEILI_URL/tasks/$1" | jq -c '.error' >&2
return 1 ;;
esac
done
}
uid=$(curl -fsS -X POST -H "$AUTH" "$MEILI_URL/snapshots" | jq -r '.taskUid')
wait_task "$uid"
cp "$MEILI_SNAPSHOT" "$DEST/snapshot-$STAMP.snapshot"
uid=$(curl -fsS -X POST -H "$AUTH" "$MEILI_URL/dumps" | jq -r '.taskUid')
wait_task "$uid"
dump=$(curl -fsS -H "$AUTH" "$MEILI_URL/tasks/$uid" | jq -r '.details.dumpUid')
mv "$MEILI_DUMPS/$dump.dump" "$DEST/"
gzip -t "$DEST/$dump.dump"
find "$DEST" -type f -mtime +1 -delete
echo "$(date -Is) saved snapshot-$STAMP and $dump.dump"sudo chmod 700 /usr/local/bin/meili-backup.sh30 2 * * * root /usr/local/bin/meili-backup.sh >> /var/log/meili-backup.log 2>&1To see which version wrote a dump, print its metadata: tar -xzOf 20261004-023012345.dump --wildcards '*metadata.json' shows dbVersion. Then copy the directory off the server (3-2-1 rule); cron schedules covers failure alerts.
Restore on a new server
Use the same MEILI_MASTER_KEY. An API key's secret is derived from its uid and the master key, so with the same master key every restored key keeps its value and your applications keep working. The database directory must not exist yet. For a snapshot, run the exact same image tag:
sudo mkdir -p /srv/meili_data/snapshotssudo cp snapshot-2026-10-04-0230.snapshot /srv/meili_data/snapshots/docker run -d --name meilisearch -p 127.0.0.1:7700:7700 --env-file /etc/meilisearch.env -v /srv/meili_data:/meili_data getmeili/meilisearch:v1.54.3 meilisearch --import-snapshot /meili_data/snapshots/snapshot-2026-10-04-0230.snapshotA dump restores into the same or a newer version: copy it under /srv/meili_data/dumps and replace the last argument with --import-dump /meili_data/dumps/20261004-023012345.dump. Meilisearch rebuilds every index before it accepts requests; follow docker logs -f meilisearch until it is listening.
- Compare counts with the old server:
curl -fsS -H "Authorization: Bearer $MEILI_BACKUP_KEY" http://127.0.0.1:7700/stats | jq '.indexes | map_values(.numberOfDocuments)'. - Once it is running, remove the container (
docker rm -f meilisearch) and start it again with the normal command, without the import flag. Left in place, the next restart fails because the database now exists. - With the systemd setup: stop the service, move
/var/lib/meilisearch/dataaside, runsudo -u meilisearch /usr/local/bin/meilisearch --config-file-path /etc/meilisearch.toml --import-dump <file>in the foreground, press Ctrl+C once it is listening, thensystemctl start meilisearch.
Restore into a spare server every month and time it: that is your real recovery time (testing restores).
Before upgrading
A newer binary refuses an older database until you start it with --upgrade-db (MEILI_UPGRADE_DB; before 1.51 it was --experimental-dumpless-upgrade). The docs warn the upgrade is not atomic and can corrupt the database, so take a snapshot first and keep the old image tag to roll back to. Databases from versions older than 1.12 can't be upgraded this way: create a dump with the old version and import it into the new one.
Common errors
| Error | Fix |
|---|---|
database already exists at "/meili_data/data.ms", try to delete it or rename it | An import flag with an existing database. Move data.ms aside, or drop the flag after the first import. |
snapshot doesn't exist at /meili_data/snapshots/... or dump doesn't exist at "..." | The path is read inside the container. Check the volume and use the /meili_data/... path. |
Your database version (1.53.3) is incompatible with your current engine version (1.54.3). | The image tag changed. Go back to the old tag, or snapshot and start with --upgrade-db, or import a dump. |
Launch fails: the database version is too old to be upgraded via --upgrade-db | The database predates 1.12. Reinstall its version, create a dump, import it into the new one. |
No space left on device during a snapshot or dump | TMPDIR is too small. Point it at a larger disk. |
The Authorization header is missing. It must use the bearer authorization method. | Send Authorization: Bearer <key>. |
The provided API key is invalid. | Wrong key, or the master key changed since it was created. |
processing an S3-streaming snapshot task requires the Enterprise Edition | S3 snapshots need the Enterprise Edition. Write snapshots to disk and copy them. |
Frequently asked questions
- What is the difference between a Meilisearch dump and a snapshot?
- A snapshot is a copy of the database files: fast to import, but only into the exact same version. A dump is an export that rebuilds the indexes on import and works in the same or a newer version.
- Does a Meilisearch dump include API keys?
- Yes, without their secret values. Each key's value is derived from its uid and the master key, so importing with the same master key gives the same key values.
- Can I import a dump into a running Meilisearch?
- No. Dumps and snapshots import only at launch, with --import-dump or --import-snapshot, into an empty database directory.
- Where does Meilisearch in Docker save dumps and snapshots?
- In /meili_data/dumps and /meili_data/snapshots inside the container, so in the volume you mount at /meili_data.
- Why is there only one Meilisearch snapshot file?
- Each new snapshot replaces the previous file. Copy it to a dated name after each run if you want history.
How this was checked
Commands, limits and prices were checked against these official pages, on October 4, 2026:
- Meilisearch docs: Backing up Meilisearch data (snapshots vs dumps)
- Meilisearch docs: Exporting and importing dumps
- Meilisearch docs: Exporting and using snapshots
- Meilisearch docs: Configuration reference (dump, snapshot, import and S3 options)
- Meilisearch docs: Using Meilisearch with Docker
- Meilisearch docs: Update to the latest Meilisearch version
- Meilisearch docs: Master key and API keys
- Meilisearch docs: Manage API keys (actions)
- Meilisearch docs: Monitor tasks
- Meilisearch docs: Running Meilisearch in production (paths, systemd)
- Meilisearch docs: Enterprise and Community editions
- Meilisearch docs: Error codes
- Meilisearch source, v1.54.3: snapshot and dump creation, import checks, versioning, API key derivation (messages quoted)
- Meilisearch releases on GitHub