Document Deletion Not Replicated with Low revs_limit (CouchDB → PouchDB)
- Dominant language
- JavaScript
- Stars
- 17.6k
- Forks
- 1.5k
- PR merge metrics
- No merged PRs in 30d
Description
# 🔄 Document Deletion Not Replicated with Low `revs_limit` (CouchDB → PouchDB)
Hi,
I'm encountering a document deletion issue when replicating data from CouchDB to PouchDB with a low `revs_limit`.
## 🧠 Context
I'm using a one-way replication mechanism from CouchDB → PouchDB in a React Native application. Documents are updated daily in CouchDB and replicated to PouchDB. No changes are made in PouchDB — it's read-only.
Because documents were accumulating hundreds of revisions (sometimes 400+), we decided to limit the revision history by setting `revs_limit = 1` on the CouchDB database, since we do not need any revision history.
This approach generally works well — documents update fine even with multiple revision gaps.
## ❌ Problem: Deletions Are Not Propagated
However, we're running into a problem with deleted documents not being removed from PouchDB.
### 🧪 Reproduction Scenario (with `revs_limit = 3`)
1. A document is created in CouchDB.
2. It is replicated to PouchDB.
3. The document is modified 6 times in CouchDB.
4. The document is then deleted in CouchDB.
5. The replication is triggered.
➡️ At this point, the document is NOT deleted in PouchDB.
If I increase `revs_limit` to 10 with same process, the deletion propagates correctly.
## 🧩 Investigation
The deletion status is determined via this code (extracted from PouchDB):
```js
// check if a specific revision of a doc has been deleted
// - metadata: the metadata object from the doc store
// - rev: (optional) the revision to check. defaults to winning revision
function isDeleted(metadata, rev) {
if (!rev) {
rev = winningRev(metadata);
}
var id = rev.substring(rev.indexOf('-') + 1);
var toVisit = metadata.rev_tree.map(getTrees);
var tree;
while ((tree = toVisit.pop())) {
if (tree[0] === id) {
return !!tree[1].deleted;
}
toVisit = toVisit.concat(tree[2]);
}
}
```
Here’s an example of the replicated document metadata:
```json
{
"id": "header:test7",
"deleted": true,
"revisions": {
"start": 7,
"ids": [
"6f8c91dbbaeaddfc94972b3b912a8b43",
"1e0a89380ff99cc556d5f8518afb39a7",
"520f3eb9ca9c2f925f63b363c80774ae"
]
},
"rev_tree": [
{
"pos": 1,
"ids": ["637b045152350553a2ad642d05975297", { "status": "available" }, []]
},
{
"pos": 5,
"ids": [
"520f3eb9ca9c2f925f63b363c80774ae",
{ "status": "missing" },
[
[
"1e0a89380ff99cc556d5f8518afb39a7",
{ "status": "missing" },
[
[
"6f8c91dbbaeaddfc94972b3b912a8b43",
{ "status": "available", "deleted": true },
[]
]
]
]
]
]
}
],
"seq": 8840
}
```
In this case:
- The rev at `pos: 1` corresponds to the first revision (from the initial replication).
- The rev at `pos: 5` corresponds to the deleted revision.
- However, the ID passed to the function is the one from `pos: 1` (`637b045152350553a2ad642d05975297`), which doesn't match the deleted branch in the `rev_tree`.
Thus, the document never gets deleted in PouchDB.
## ❓ Question
Is this expected behavior when using a low `revs_limit`?
Is there a way to ensure that document deletions replicate correctly even when the deleted revision is from a "longer" branch that replaces a truncated one?
Contributor guide
Assessment
This issue has not been assessed yet.