CouchDB

CouchDB is an open-source database designed for “multi-master replication”—i.e. multiple clients can modify the database and sync later, enabling offline software. It’s managed by the Apache Foundation.

CouchDB is implemented in Erlang, but PouchDB is a Javascript implementation designed to run on the browser.

The Ink and Switch authors suggest that it has the following serious issues:

  • some performance issues (unspecified)
  • some multi-device issues (unspecified)
  • challenges of conflict resolution (but it’s not clear if this only matters for fine-grained editing like in Google Docs)
  • questionable longevity, privacy, and user control

Documents can have “attachments,” which are serialized as base64 or blobs depending on backend.

It’s a flat key/value store, like LevelDB. You can use structured key IDs to create hierarchy (e.g. see DocURI)

Backend implementation

  • Sounds like it’s difficult to implement a database-per-user backend.
  • Cloudant offers a hosted server solution.
    • Seems pricey!
    • “Classic”
      • $1/GB/mo (oof!), 20GB included
      • $75/mo for each unit of 100 reads/s and 50 writes/s (i.e. 267M reads/mo max… maybe OK? That’s 8.9M reads/day…)
      • But if you have 20,000 records, this’ll be a 3 minute syncing operation. That seems like it’s obviously not OK.
    • “Transaction engine”, can scale up and down as needed
      • $0.25/GB/mo
      • $22/mo for each node (each can handle 50 reads and writes per second)
      • Transaction engine doesn’t support attachments, bluhhh
    • Max document size 1MB
    • Max attachment size 10MB (so attachments don’t want to get stored here…)
  • Bitnami has a package I can use to host CouchDB myself on GCP. Not clear what kind of cluster I would need to set up. Would one server be enough?
    • Looks like $75/mo would buy me plenty of server.
  • I can use PouchDB-server with a Firebase LevelDOWN backend to host it on Firestore… maybe?
    • Firestore is $0.036/100k doc reads. And $0.108/GB/month.
    • Maybe this could work?

One-to-N relations

A clever way to handle “parent-child” document arrangements is to structure the keys so that the whole set can be fetched as a range: e.g. parent, parent:child1, parent:child2, etc. Now you can query from parent to parent:\ufff0

Linked documents

You can “join” by including IDs as part of the emitted value in mapping functions like {_id: someOtherID} . Then when include_docs is set to true, the other document will be inserted.

Authentication considerations

Migrations

References

Last updated 2023-07-13.