DBDelve
Dive deep into your data. A fast, native, multi-engine database client written in Rust. Free and open source, no telemetry.
翻訳待ち
Keep each SaaS customer's rows in their own Postgres. A Postgres proxy that moves one tenant to its own database without app changes.
翻訳待ち
Loading the full README.
Read the full README ↗Let your SaaS customers keep their data in their own Postgres — without rewriting your app.
lokadb.com · Documentation · Playground
Enterprise customers increasingly ask a multi-tenant SaaS for the same thing: "our data stays in our database." The usual answers are expensive — a single-tenant deployment per customer, or a rewrite of the data layer so every query knows which database to talk to.
LokaDB is a Postgres wire-protocol proxy that takes a third way. Your application keeps one database connection string and keeps sending the SQL it sends today. LokaDB stores the rows of the tables you choose, for the organizations you choose, in each organization's own Postgres, and leaves everything else in your cloud database. Moving an organization out, and back, happens online while the application writes.
Status: early, in production at KeepPlain, our own Laravel SaaS on Postgres, where LokaDB started. LokaDB works with any application that talks to Postgres over its protocol, in any language and with any ORM: only the connection string changes. What decides is your schema and your queries, not the framework, and
lokadb checktells you before anything is changed. Every build is tested end to end under load with three unmodified applications (Laravel, Django, Go) and against more than 300 failure scenarios. See What's supported, Limits and the roadmap.
LokaDB converts the chosen tables of your cloud database into tables partitioned by organization, without copying rows. An organization that stays in the cloud lives in a local partition. An organization that moves gets a partition that is a postgres_fdw foreign table pointing at its own database. The proxy parses every statement with the real Postgres parser, finds the organization in it (the tenant column, a row id, a foreign key, a declared relation), and tells Postgres which partition to use; a statement that names no organization is refused by default rather than sent to every customer database. The cloud never connects into the customer's network: an agent inside that network opens an outbound mutual-TLS tunnel to a relay in your cloud, and all traffic to the customer database goes through it. For organizations far from the cloud, the proxy can send statements that touch only that organization's tables straight to its database through the same tunnel, skipping the extra round trips of postgres_fdw.
flowchart LR
subgraph app [Your SaaS]
A[Application<br/>Laravel / Django / Go / ...]
end
subgraph cloud [Your cloud]
P[LokaDB proxy]
C[(Cloud Postgres<br/>documents PARTITION BY LIST org)]
R[relay]
C -- "org 2, 3, ...: local partitions" --- C
C -- "org 1: foreign partition<br/>(postgres_fdw)" --> R
end
subgraph cust [Customer network]
G[agent]
D[(Customer Postgres<br/>org 1 rows only)]
end
A -- "same SQL, new host:port" --> P
P -- "fdw" --> C
P -. "fdw+direct / direct:<br/>single-org statements" .-> R
G == "outbound mTLS tunnel<br/>(opened by the agent)" ==> R
G --> D
Each moved organization has a routing profile. It matters only after an organization has moved, and move-org picks fdw+direct for you; skip this table on a first read.
| Profile | Path | Use when |
|---|---|---|
fdw | every statement goes to the cloud Postgres, which reads the organization through postgres_fdw | the organization is close to the cloud, or the workload joins its tables with cloud tables a lot |
fdw+direct (default when direct credentials are configured) | statements that touch only this organization's tables go straight to its database; the rest go through postgres_fdw | the usual choice for a remote organization |
direct | no postgres_fdw path at all; the cloud database holds no credentials for the organization | the application names the organization itself (cooperative mode) |
In the browser. the online demo runs a demo stand: a cloud database, organizations in their own databases, a demo application, and the compatibility report — nothing to install.
Locally, with Docker. One command starts a cloud Postgres, one organization's Postgres behind the relay and the agent, the proxy, and a small application that keeps writing for two organizations; it then runs check, enable and move-org and shows where each organization's rows ended up (Quickstart). It is a demo on throwaway databases; to put LokaDB in front of your own, see Install on your database. Run it from the root of this repository:
git clone https://github.com/lokadb/lokadb && cd lokadb
docker compose -f quickstart/compose.yml up --build
The full test stand — three applications and several hundred end-to-end and defect checks — is bash e2e/run.sh (see Testing).
The main steps, each of which can be stopped and undone. Install on your database has every command in full, and says which machine runs it.
This is the beginning of the README. Read the rest at the original. Read the full README ↗