CouchDB Cheat Sheet
CouchDB's HTTP API, document revisions, map/reduce views, and built-in replication model for offline-first JSON document storage.
HTTP API Basics
Managing databases and documents with curl.
# Create a databasecurl -X PUT http://localhost:5984/mydb# Create a documentcurl -X POST http://localhost:5984/mydb \ -H "Content-Type: application/json" \ -d '{"name": "Alice", "email": "[email protected]"}'# Get a documentcurl http://localhost:5984/mydb/<doc_id># Update requires the current _revcurl -X PUT http://localhost:5984/mydb/<doc_id> \ -d '{"_rev": "1-abc123", "name": "Alice2"}'
Views (Map/Reduce)
Querying data with a design document.
// Design document defining a view{ "_id": "_design/users", "views": { "by_email": { "map": "function (doc) { if (doc.email) { emit(doc.email, doc); } }" } }}// Query it: GET /mydb/_design/users/_view/by_email?key="[email protected]"
Core Concepts
How CouchDB stores and syncs documents.
- Document- a JSON object with a unique _id and a system-managed _rev
- _rev- revision token used for MVCC-based conflict detection on every update
- Design document- a special document (_id starts with _design/) that holds views
- MVCC- CouchDB never overwrites data in place; every update creates a new revision
- Replication- built-in, bidirectional, works over plain HTTP for offline-first sync
- _changes feed- a stream of document changes used to drive replication
Mango Queries (Declarative Find API)
Query documents with a MongoDB-style selector instead of hand-written map/reduce.
# Create an index to back the query (optional but recommended)curl -X POST http://localhost:5984/mydb/_index \ -H "Content-Type: application/json" \ -d '{"index": {"fields": ["email", "age"]}, "name": "email-age-idx"}'# Query with a selectorcurl -X POST http://localhost:5984/mydb/_find \ -H "Content-Type: application/json" \ -d '{ "selector": { "age": {"$gt": 21}, "email": {"$regex": "^a"} }, "sort": [{"age": "asc"}], "limit": 20 }'
Detecting & Resolving Replication Conflicts
CouchDB keeps all conflicting revisions after a replication merge; your app must pick a winner.
# Fetch a document including conflict metadatacurl "http://localhost:5984/mydb/<doc_id>?conflicts=true"# -> "_conflicts": ["2-b91bb807...", "2-c8b6a1e2..."]# Fetch a specific conflicting revisioncurl "http://localhost:5984/mydb/<doc_id>?rev=2-b91bb807..."# Resolve: keep the winner's content, then delete the losing revision explicitlycurl -X DELETE "http://localhost:5984/mydb/<doc_id>?rev=2-c8b6a1e2..."# CouchDB itself only picks a deterministic "winner" for reads;# it never merges field-by-field, so app-level resolution is required.
Continuous _changes Feed for Live Sync
Stream document updates in real time — the backbone of offline-first apps.
# Long-poll: waits for at least one change, then returnscurl "http://localhost:5984/mydb/_changes?feed=longpoll&since=now"# Continuous: keeps the HTTP connection open, streams newline-delimited JSONcurl "http://localhost:5984/mydb/_changes?feed=continuous&include_docs=true&since=0"# Filtered changes using a filter function in a design doccurl "http://localhost:5984/mydb/_changes?filter=app/by_type&type=order"
Reduce Functions & rereduce
Aggregate view output at scale — CouchDB re-runs reduce on already-reduced chunks.
// Design document with map + reduce{ "_id": "_design/orders", "views": { "total_by_customer": { "map": "function (doc) { if (doc.type === 'order') emit(doc.customerId, doc.amount); }", "reduce": "function (keys, values, rereduce) {\n if (rereduce) { return sum(values); }\n return sum(values);\n}" } }}// Query grouped by key (per-customer totals) instead of one grand total// GET /mydb/_design/orders/_view/total_by_customer?group=true
Replication & Cluster Concepts (CouchDB 3.x)
Terms for running CouchDB beyond a single node with the _replicator database.
- _replicator database- a special DB where each document declares a source/target pair; CouchDB manages the replication job for you
- Filtered replication- restrict what replicates using a filter function or a Mango selector on the replication doc
- Revision tree- the full branching history of a document's _rev values, not just the current winner
- Quorum (n/w/r)- clustered CouchDB writes/reads to a subset of shard copies; tunable per-request via X-Couch-Full-Commit and query params
- Compaction- reclaims disk space from old revisions and deleted docs; run per-database and per-view periodically
- Purge- permanently removes a document's revision history (unlike a normal delete, which just adds a tombstone revision)
Always send the current _rev when updating or deleting a document — CouchDB rejects writes carrying a stale _rev, which is how it surfaces conflicts instead of silently overwriting concurrent edits.