Apache CouchDB is the original document database. Created by Damien Katz (ex-Lotus Notes) in 2005 and donated to the Apache Software Foundation in 2008, CouchDB pioneered JSON-document storage years before MongoDB and shipped one of the first multi-master replication models in any open database. CouchDB is the database that made “offline-first” applications possible — a mobile or browser client can read, write, and synchronize against a master database without ever blocking on the network.
CouchDB's design follows from one goal: data should be able to live on many machines that are not always connected, and still converge. Every document carries a revision history, every database can replicate with any other over HTTP, and conflicts are kept rather than discarded so the application can decide how to merge them. The same protocol is implemented by PouchDB in the browser and by Couchbase Lite on mobile devices, which is what makes offline-first sync practical.
Replication is a client of the ordinary HTTP API: it reads the source's _changes feed from its last checkpoint, asks the target which revisions it is missing (_revs_diff), and copies them with _bulk_docs. Because it is incremental and resumable, a device that was offline for a week only transfers what changed. Within a cluster, CouchDB 2.x and later split each database into q shards and keep n copies of each (default q=8 in CouchDB 2.x and q=2 since 3.0, with n=3 copies; both can be set per database at creation, e.g. PUT /db?q=4&n=3), using quorum reads and writes across nodes.
_id and a monotonically-increasing _rev for concurrency control.PUT, GET, DELETE. No driver required; curl works as a client.A revision id is a generation number plus a hash of the content. Every update must quote the current _rev; if someone else updated first, the write fails with 409 Conflict, which is optimistic concurrency on a single node. Across replicas, two peers can each accept an update to the same revision; after replication the document has two leaf revisions. CouchDB picks the same winner on every node (highest generation, then highest hash), returns it on normal reads, and exposes the others through ?conflicts=true. The application resolves by writing a merged revision and deleting the losing branch.
DB=http://admin:secret@localhost:5984
curl -X PUT $DB/notes # create a database
curl -X PUT $DB/notes/n1 -H 'Content-Type: application/json' \
-d '{"type":"note","title":"Ship log","tags":["sea"]}'
# {"ok":true,"id":"n1","rev":"1-..."}
curl $DB/notes/n1 # read, includes _rev
curl -X PUT $DB/notes/n1 -H 'Content-Type: application/json' \
-d '{"_rev":"1-...","type":"note","title":"Ship log v2","tags":["sea"]}'
# Mango query with an index
curl -X POST $DB/notes/_index -H 'Content-Type: application/json' \
-d '{"index":{"fields":["type","title"]},"name":"type-title"}'
curl -X POST $DB/notes/_find -H 'Content-Type: application/json' \
-d '{"selector":{"type":"note","tags":{"$elemMatch":{"$eq":"sea"}}},"fields":["_id","title"]}'
# Continuous replication to another server (a POST to /_replicate is not
# persisted across restarts; for a durable job, write the same JSON as a
# document into the _replicator database instead)
curl -X POST $DB/_replicate -H 'Content-Type: application/json' \
-d '{"source":"notes","target":"http://admin:secret@backup:5984/notes","continuous":true,"create_target":true}'
# Documents with conflicts
curl "$DB/notes/n1?conflicts=true"
A MapReduce view is stored in a design document. This one counts notes per tag; the built-in _count reducer is evaluated natively:
curl -X PUT $DB/notes/_design/tags -H 'Content-Type: application/json' -d '{
"views": { "by_tag": {
"map": "function (doc) { if (doc.type === \"note\") { doc.tags.forEach(function (t) { emit(t, 1); }); } }",
"reduce": "_count"
} } }'
curl "$DB/notes/_design/tags/_view/by_tag?group=true"
| Need | CouchDB | Alternative |
|---|---|---|
| Offline-first sync to browsers and devices | Core strength (with PouchDB) | Couchbase Mobile, Firebase |
| Ad hoc analytical queries | Weak | MongoDB, PostgreSQL |
| Multi-document transactions | Not supported | MongoDB, relational databases |
| Simple ops, HTTP-only clients | Strong | - |