dev.toHow CouchDB and RustFS power Rentivio's property listingsRentivio connects home owners in Greece with professional short-term rental managers. Owners list homes that sit empty, managers lease them for a fixed monthly rent and run them for guests.
A listings platform comes down to two kinds of data: **records that keep changing shape** , and **lots of photos**. Here's how two open-source tools handle them for us, and why we'd pick them again.
## CouchDB: listings that can grow without migrations
A property listing never stays the same for long. We started with location, rent and photos, then added minimum lease duration, amenities, deal status, moderation flags and more. In a relational database, every one of those changes is a migration. In CouchDB, a listing is a JSON document, so a new field is simply a new field.
What worked well for us:
* **One database per concern.** Listings, users, payments and chat each live in their own CouchDB database. Each has its own indexes and its own backups, and a heavy query on one doesn't slow down the others.
* **Revisions catch conflicting edits.** Every update has to send the document's current `_rev`. If two people edit the same listing at once, the second save fails instead of silently overwriting the first. We got that safety for free.
* **The app sets up its own database.** On startup, our Node.js service creates any missing databases, design documents and indexes. A fresh environment is ready with a single `docker compose up`, and a new index ships in the same commit as the query that needs it.
* **Mango queries feel familiar.** Searching by area, price or status is a JSON selector plus an index. If you know MongoDB, you already know most of it.
## RustFS: photos that never touch our server
Listings live or die by their photos, and image traffic is the fastest way to overload a small API. We store photos in RustFS, a lightweight, self-hosted, S3-compatible object store.
The key decision: **image bytes never pass through our API.** When someone uploads or views a photo, the API checks that they're allowed to, then returns a short-lived **presigned URL**. The browser talks to RustFS directly.
The result:
* Our API only sends small JSON responses, so it stays fast even when someone scrolls through dozens of photos.
* Because RustFS speaks the S3 API, we use the standard AWS SDK. Moving to any other S3-compatible provider later is a configuration change, not a rewrite.
* It runs as one more container next to the rest of the stack, with its data on a named Docker volume. Development and production behave the same way.
* Like CouchDB, the bucket is created automatically on startup, so there's nothing to click through in a console.
## What we learned
1. **Pick storage by the shape of the data.** Documents that change go in a document database. Large binary files go in object storage, not in the database and not through the API.
2. **Let the app set up its own infrastructure.** Self-creating databases, indexes and buckets removed a whole class of "works on my machine" problems.
3. **Self-hosted doesn't have to mean complicated.** CouchDB and RustFS are each a single container with a persistent volume, and both have been low-maintenance for us.
If you're building a small marketplace and wondering whether you need a managed cloud database and storage from day one: you might not. CouchDB and RustFS have carried Rentivio comfortably so far.
Curious about the product? Have a look at rentivio.gr. Questions about the setup are welcome in the comments.
https://rentivio.gr/?utm_source=devto&utm_medium=social&utm_campaign=cm-post-6
0 reposts0 likes