View Indexing: Performance Impact of Design Document Updates in CouchDB 3.x
0 reputation · 09 Jun 2021, 09:26 UTC
0 reputation · 09 Jun 2021, 09:26 UTC
CouchDB utilizes MapReduce functions within design documents to maintain B-tree secondary indexes. When a design document is updated, the system triggers a full re-index of all documents associated with that specific view to ensure consistency between the map function and the stored index.
In environments with high document counts, this re-indexing process creates a significant resource spike and temporary latency. While the indexer operates asynchronously, the transition period between the old index and the new index can affect query performance and consistency during the rebuild phase.
What are the available mechanisms to mitigate the performance overhead of full re-indexing when making minor changes to a map function? Is there a method to perform incremental updates to a view index without triggering a complete rebuild of the B-tree?
35275 reputation · 09 Jun 2021, 16:21 UTC
In CouchDB 3.x any change to a design document's map function triggers a full rebuild of the B-tree that backs the associated view. The indexer is asynchronous, but the rebuild must rewrite the entire key space, so a minor tweak still costs a full pass over every document that the view scans. There is no native incremental update path for a changed map function.
stale query parameter
stale=ok allows queries to read the old index while the rebuild runs; only the background indexer task performs the work.stale=update_after returns results from the old index immediately and starts a rebuild in the background, so queries never block._active_tasks to observe rebuild duration and peak CPU/IO.Even a minor alteration that changes emitted keys requires a complete B-tree rebuild. CouchDB's indexer does not support patching the tree in place for map function changes, because the index topology is derived entirely from map emissions.
curl -X GET "http://localhost:5984/db/_design/ddoc/_view/viewname?limit=0"
The total_rows value tells you how many documents the view touches.
curl -X PUT http://localhost:5984/db/_design/ddoc \
-H "Content-Type: application/json" \
-d '{"views":{"viewname":{"map":"function(doc){...}"}},"language":"javascript"}'
curl -X GET http://localhost:5984/_active_tasks
Look for an indexer task and note its duration and resource usage.
curl -X GET "http://localhost:5984/db/_design/ddoc/_view/viewname?stale=update_after"
After the indexer task completes, run the same query without stale and compare result counts and timing against your baseline to confirm the new index is fully built.
stale behavior can vary across CouchDB 3.x point releases; verify against your version's release notes.stale=ok can serve data from an incomplete index if a rebuild is interrupted, so treat results as approximate until the rebuild finishes.To fine-tune the recommendation, how many documents does the view currently index? Knowing the view size helps decide whether stale queries alone are sufficient or whether splitting views or a new view name is the better mitigation.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.