How to back up Apache CouchDB
CouchDB's documentation gives the simplest backup: copy its .couch files while it runs, because they are append-only, taking the view indexes in .shards before the databases in shards and the system databases beside them, plus the etc config directory. Restore by putting both back on a node with the same node name. Replication to a second CouchDB keeps a live copy, but it copies deletions too, so keep dated file copies as well.
Pick a method
CouchDB 3.5.2 is current in October 2026. Four ways to keep a copy:
| Method | What you get | Watch out for |
|---|---|---|
| Copy the data files (this guide) | Every database, the _users accounts and the indexes, taken while CouchDB runs | Restore needs the same node name; copy views before databases |
| Replication to another CouchDB | A live second copy | Deletions and bad writes replicate too |
| couchbackup (IBM, open source) | One text file per database, over HTTP | No attachments; needs Node.js 22 or 24 |
| Disk snapshot (LVM, ZFS, cloud volume) | A near-instant point-in-time copy | Freeze the file system with fsfreeze if your platform needs it |
Find the files and the node name
Packages from the CouchDB repository (Debian, Ubuntu, RHEL) install to /opt/couchdb, and /opt/couchdb/data is a symlink to /var/lib/couchdb. Back up /var/lib/couchdb itself: tar stores a symlink as a link, not the files behind it. Then ask CouchDB for its node name, which a restore must match:
curl -s -u admin http://127.0.0.1:5984/_node/_localcurl asks for the admin password. {"name":"[email protected]"} is the package default for a single node; it comes from the -name line in /opt/couchdb/etc/vm.args. What the data directory holds:
shards/<range>/<db>.<suffix>.couch: each database, split into shard files, one directory per hash range._usersand_replicatorlive here too..shards/: view and Mango index files, also sharded._dbs.couchand_nodes.couchat the top: the shard map, which records which node holds each shard, and the list of nodes.
sudo du -sh /var/lib/couchdb shows how much the archive may need.
Copy the files while CouchDB runs
CouchDB only appends to its files, so the docs say a copy taken at any time works. The order matters for recovery time: a view index a little older than its database is brought up to date on the next read, but one newer than its database is rebuilt from scratch, a slow and costly job on a large database. So copy .shards first. tar archives paths in the order you list them:
#!/bin/bash
set -eu
DATA=/var/lib/couchdb
DEST=/var/backups/couchdb
STAMP=$(date +%F-%H%M)
mkdir -p "$DEST"
cd "$DATA"
# Views first, then the databases, then the shard map and node list.
VIEWS=""
if [ -d .shards ]; then VIEWS=.shards; fi
rc=0
tar --exclude='*.compact*' -czf "$DEST/couchdb-data-$STAMP.tar.gz" $VIEWS shards *.couch || rc=$?
if [ "$rc" -gt 1 ]; then
echo "$(date -Is) data copy failed (tar exit $rc)" >&2
exit 1
fi
tar -czf "$DEST/couchdb-etc-$STAMP.tar.gz" -C /opt/couchdb etc
find "$DEST" -name 'couchdb-*.tar.gz' -mtime +1 -delete
echo "$(date -Is) created couchdb-data-$STAMP.tar.gz"tarprintsfile changed as we read itand exits with 1 when CouchDB appends to a file during the copy. That is expected here, so the script fails only on exit 2, a real error.--exclude='*.compact*'skips the temporary files compaction writes (.compact,.compact.data,.compact.meta,.compact.view); they disappear when compaction finishes.- It runs as root, since
/var/lib/couchdbis readable only by thecouchdbuser and group. - The
findline keeps about two days of archives on the server.
sudo chmod 700 /usr/local/bin/couchdb-backup.sh30 2 * * * root /usr/local/bin/couchdb-backup.sh >> /var/log/couchdb-backup.log 2>&1Then copy /var/backups/couchdb off the server (3-2-1 rule); cron schedules covers timing and failure alerts.
What the config archive holds
CouchDB reads default.ini, default.d/*.ini, local.ini and local.d/*.ini in that order, and writes changes made at runtime to the last file in that chain. Back up all of /opt/couchdb/etc, because the data alone won't come back as it was:
[admins]: server admins. They are not in_users. CouchDB replaces a plain-text password with a PBKDF2 hash when it restarts. Without an admin, CouchDB 3 refuses to start.[chttpd_auth] secret: signs session cookies (the setting moved here from[couch_httpd_auth]in 3.2). CouchDB generates and saves one when none is set; with a different secret, users have to log in again.[couchdb] uuid: the server's identifier. Replication IDs are built from it, so with a new UUID replications can't find their checkpoints and re-read their sources from the start.vm.args: the node name (-name) and the Erlang cookie (-setcookie) that cluster nodes share.
The config archive holds password hashes, the cookie secret and the Erlang cookie. Encrypt it before it leaves the server.
Restore on a new server
Install the same CouchDB version or newer from the same repository, copy both archives across, then:
- Stop CouchDB:
sudo systemctl stop couchdb. - Restore the config:
sudo tar -xzf couchdb-etc-2026-10-04-0230.tar.gz -C /opt/couchdb. On a newer version, unpack it elsewhere instead and copy acrosslocal.ini,local.d/and the-nameand-setcookielines ofvm.args, keeping the newdefault.ini. - Move the fresh install's data aside and make an empty directory:
sudo mv /var/lib/couchdb /var/lib/couchdb.fresh, thensudo install -d -o couchdb -g couchdb -m 750 /var/lib/couchdb. - Unpack the data:
sudo tar -xzf couchdb-data-2026-10-04-0230.tar.gz -C /var/lib/couchdb. - Fix ownership:
sudo chown -R couchdb:couchdb /var/lib/couchdb /opt/couchdb/etc. - Start it:
sudo systemctl start couchdb.
curl -s -u admin http://127.0.0.1:5984/_all_dbscurl -s -u admin http://127.0.0.1:5984/ordersThe first lists every database; the second returns doc_count for one, to compare with the old server. Restore onto a scratch server once a month and time it (testing restores).
Get back one database
You can't drop one database's shard files into a running node, because its entry in the shard map has to match. Restore the whole archive on a scratch server instead, then replicate the database you need across, under a new name:
curl -s -u admin -X POST http://127.0.0.1:5984/_replicate -H 'Content-Type: application/json' -d '{"source": "http://admin:<password>@scratch.example.com:5984/orders", "target": "http://admin:<password>@127.0.0.1:5984/orders_restored", "create_target": true}'Replicating the old copy back into the live database does not bring deleted documents back. A deletion is a newer revision of each document, so it wins. Replicate into a new database, check it, then point the application at it or copy the documents you need across.
Replication: a live copy, not a backup
The docs call replication to another CouchDB the simplest backup. A document in _replicator makes it persistent: it restarts with the server, while a POST to _replicate is gone after a restart.
curl -s -u admin -X PUT http://127.0.0.1:5984/_replicator/orders-to-backup -H 'Content-Type: application/json' -d '{"source": "http://admin:<password>@127.0.0.1:5984/orders", "target": "http://admin:<password>@backup.example.com:5984/orders", "create_target": true, "continuous": true}'continuouskeeps sending changes as they happen;create_targetcreates the database on the other server if it is missing.curl -s -u admin http://127.0.0.1:5984/_scheduler/docs/_replicator/orders-to-backupshows itsstate, which should berunning. Deleting the document stops it.- Each task copies one database in one direction. Replicate
_userstoo; server admins aren't in any database.
It isn't a backup on its own: documents deleted on the source are deleted on the target, and a bad bulk update arrives seconds later. For copies you can go back to, keep the file backups above, or run a one-shot replication (no continuous) each night into a dated database such as orders-2026-10-04.
couchbackup: one file per database
IBM's couchbackup (Apache 2.0, version 2.11.19) reads a database's changes feed over HTTP and writes the documents to a text file, so it doesn't depend on node names or shard layout. It does not support attachments: a backup of a database with attachments looks complete but can't be restored.
npm install -g @cloudant/couchbackupcouchbackup --db orders | gzip > /var/backups/couchdb/orders-2026-10-04.txt.gzIt reads the server from COUCH_URL, such as http://admin:<password>@127.0.0.1:5984; export it from a root-only file rather than typing it. --db names the database. Restoring needs a new, empty database:
curl -s -u admin -X PUT http://127.0.0.1:5984/orders_restoredgunzip -c /var/backups/couchdb/orders-2026-10-04.txt.gz | couchrestore --db orders_restoredCouchDB in Docker
The apache/couchdb image keeps data in /opt/couchdb/data and writes the admin (COUCHDB_USER, COUCHDB_PASSWORD) and secret (COUCHDB_SECRET) to /opt/couchdb/etc/local.d/docker.ini. Set DATA in the script to the volume's host path:
docker volume inspect --format '{{ .Mountpoint }}' couchdb_dataMount /opt/couchdb/etc/local.d to a host directory and archive that instead of /opt/couchdb/etc; otherwise runtime config, the UUID included, lives only in the container. On restore keep the same NODENAME, which sets -name couchdb@<NODENAME>: NODENAME=127.0.0.1 matches the package default when moving from a package install. More in Docker volume backups.
Clusters
Each node holds only its own shard replicas, and the shard map names nodes. Run the script on every node and restore each archive onto a node with the same name. For a different layout, replicate each database into the new cluster instead; replicating every database to a single-node backup server and backing that up also works.
Common errors
| Error | Fix |
|---|---|
internal_server_error : No DB shards could be opened. in the log, This database failed to load. in Fauxton | The node name changed, so the shard map points at a node that isn't there. Put the old -name back in vm.args and restart. |
No Admin Account Found, aborting startup. | The data came back without its config. Restore local.ini and local.d, or add an [admins] entry, and restart. |
{database_does_not_exist,[{mem3_shards,load_shards_from_db,"_users" ... | _users is missing: its shards weren't restored, or the node was never set up. Restore the whole data directory, or create _users and _replicator with curl -X PUT. |
{"error":"not_found","reason":"Database does not exist."} | Check the name in _all_dbs. If a restored database is missing from the list, restore the top-level .couch files (the shard map) too. |
{"error":"unauthorized","reason":"You are not a server admin."} | Replication and _node config requests need a server admin login. |
db_not_found: could not open <url> | The replication source or target is missing, or the URL or password is wrong. Add "create_target": true for a new target. |
eacces in the startup output | Restored files belong to root. Run sudo chown -R couchdb:couchdb /var/lib/couchdb /opt/couchdb/etc. |
Frequently asked questions
- Can I copy CouchDB database files while it is running?
- Yes. CouchDB's files are append-only, and its documentation says copying the .couch files at any time works. Copy the view indexes in .shards before the databases so views don't have to be rebuilt.
- Is CouchDB replication a backup?
- Not on its own. Deletions and bad writes replicate to the target within seconds. Keep dated copies too: file archives, or a one-shot replication into a new dated database each night.
- Why does CouchDB say No DB shards could be opened after a restore?
- The node name in vm.args differs from the one in the restored shard map. Set -name back to the old value, such as [email protected], and restart.
- Does a CouchDB backup include users?
- The _users database is in the data directory, so a file backup includes it. Server admins live in the ini files under /opt/couchdb/etc; back those up too.
- How do I restore a single CouchDB database?
- Restore the full backup on a scratch server, then replicate that one database to the live server under a new name with _replicate and create_target.
How this was checked
Commands, limits and prices were checked against these official pages, on October 4, 2026:
- Apache CouchDB 3.5 docs: Backing up CouchDB
- Apache CouchDB 3.5 docs: Introduction to configuring (file chain, runtime changes)
- Apache CouchDB 3.5 docs: Authentication and authorization ([admins], [chttpd_auth] secret)
- Apache CouchDB 3.5 docs: Base configuration (database_dir, uuid)
- Apache CouchDB 3.5 docs: Shard management (shard files, .shards, _dbs)
- Apache CouchDB 3.5 docs: Single node setup
- Apache CouchDB 3.5 docs: Installation on Unix-like systems
- Apache CouchDB 3.5 docs: Installation via Docker
- Apache CouchDB 3.5 docs: Troubleshooting an installation
- Apache CouchDB 3.5 docs: Server API (/_replicate, /_membership, /_node)
- Apache CouchDB 3.5 docs: Configuration API (_local alias)
- Apache CouchDB 3.5 docs: Introduction to replication
- Apache CouchDB 3.5 docs: Replicator database
- Apache CouchDB docs: 2.1.x release notes (node name and 'No DB shards could be opened.')
- CouchDB source, 3.5.2: vm.args, configure, couch_sup, chttpd, fabric_util, couch_replicator_ids
- apache/couchdb-pkg: Debian and RPM packaging (data directory link, postinst)
- apache/couchdb-docker: README and 3.5.2 entrypoint
- IBM couchbackup README (limitations, options, exit codes)
- tar(1) manual page: return value