Octomind
Same model as opencode, same endpoint, same prices — octomind solved 24/25 to its 19/25, at half the cost. Open-source agent runtime: one binary, any model, runs unattended in CI. Apache 2.0.
Open-source Postgres proxy for multi-tenant SaaS: move selected customers' data into their own PostgreSQL while your app keeps one connection string.
Developer toolsGo · ShellGitHub @lokadbOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Keep each SaaS customer's rows in their own Postgres. A Postgres proxy that moves one tenant to its own database without app changes.
Translation pending
Taken from the repository README
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.
| Step | Command (abridged) | What it does |
|---|---|---|
| 1. Check | lokadb check -db DSN -org-table TABLE -write-spec spec.json -workload workload.json | Reads the schema, the workload the proxy recorded (lokadb proxy -record, see the install page) and, later, the organization's database, and reports what blocks the move, what LokaDB does not support yet, and what will behave differently. Changes nothing. |
| 2. Enable | lokadb enable -db DSN -spec spec.json -owner ROLE | Converts the chosen tables to partitioned tables in place (online preparation with enable -prepare for large tables). All organizations stay in the cloud. |
| 3. Connect | lokadb relay -config relay.json; lokadb token -cp DSN -org 1, then lokadb agent … in the organization's network | A relay in your network and an agent in the organization's: the agent opens the only connection, outbound, with a one-time token. |
| 4. Move | lokadb move-org -db DSN -spec spec.json -owner ROLE -org 1 -customer DSN -customer-app DSN -proxy-config proxy.json -direct-role ROLE | Moves one organization to its own database while the application keeps writing. At the switch-over the reads and writes of all organizations on the moved tables pause — seconds for an organization tens of milliseconds away (see Performance). |
| 5. Profile | lokadb org-profile -db DSN -org 1 fdw+direct | Chooses how the proxy reaches that organization. move-org already picks fdw+direct when the proxy has the direct path's credentials; this switches later. |
| 6. Back | lokadb move-back -db DSN -spec spec.json -org 1 -customer DSN | Returns the organization to the cloud; lokadb disable then undoes enable. |
The application only changes its connection string to point at the proxy (host, port). Relations your schema does not declare as foreign keys (common in Rails and Laravel), cross-organization reports and background jobs need a decision from you: lokadb check lists every such query with the reason no organization was found, and you declare the missing relations in the spec (routing.relations) or allow the reviewed reports. See Compatibility check and Routing.
IN and = ANY(array) on the tenant column, the row key or a foreign key, in literals and in bound parameters (text and binary); INSERT … VALUES and UNNEST (Django bulk_create); joins through equal columns; subqueries that name the organization. Relations without a foreign key, cloud tables that know the organization, and unique keys can be declared.ON CONFLICT), MERGE (one matched and one not-matched branch), COPY FROM STDIN and COPY TO, cursors including WITH HOLD, LISTEN/NOTIFY, prepared statements surviving enable and migrations.smallint, integer, bigint, uuid, text/varchar (deterministic collation), character(n) (Laravel's ulid()) and composite keys; tenant column of integer, uuid or text type (text, varchar, character(n)); tables in any schema; materialized views, views, rules, functions over the row type, row-level security of the application, identity columns, publications; extensions, enums, domains, collations and functions are created in the customer database when needed.RENAME COLUMN, CREATE INDEX (including CONCURRENTLY) are replayed in every customer database before the cloud commits; lokadb schema-diff / schema-sync reconcile a schema that drifted.repoint); disable.Scale: one partition per organization. Up to about 100 organizations there is no noticeable price; at 1000 throughput is lower (reads and updates by a third to a half, inserts by about a third) and at 3000 inserts fall to about 1,400 ops/s, so we do not recommend mixed writes at that scale yet. Details and the mechanism in Limits and isolation.
<x>_type + <x>_id); declared relations with a condition on the type.numeric, citext, bytea, dates, enums, domains, non-deterministic collations).postgres_fdw write.TRUNCATE, DROP TABLE, table renames and new constraints on the moved tables through the proxy (refused with an explanation).transaction mode between the proxy and Postgres (a pooler in front of the proxy is fine).The full list, and what is planned, is in Roadmap and Limits and isolation.
Measured on seven separate servers, not in Docker on one machine: a cloud database (8 cores, 32 GB), the proxy together with the relay (4 cores, 16 GB), a load generator (4 cores, 16 GB), and the databases of four organizations (2 cores, 4–8 GB each) at 0.19, 9.4, 38.7 and 43.3 ms round-trip time from the cloud. Postgres 18, fsync on, one scenario at a time; every point is 60 s after 15 s of warm-up, two repeats, the median. All figures are for this workload — access by primary key and by an (organization_id, id) index; another workload gives other numbers. Method, scenarios and raw results are in research/bench/; the numbers behind every chart are in charts-data.md.
Organizations that stay in the cloud. A statement costs 0.2–1 ms more through the proxy; with 32 clients the throughput is 36–80 % of a direct connection (read 66,500 → 29,800 ops/s, update 57,200 → 33,900, feed 35,500 → 28,400, insert 23,700 → 8,600). A whole Django application with 16 clients was 5–10 % slower through LokaDB than without it. That makes the cloud path suitable for a limited pilot on a compatible application — a conclusion about this workload, not a guarantee.
A new connection for every request (PHP-FPM without persistent connections, serverless; 16 clients, one read). LokaDB's built-in connection pool, on by default for all databases, gave 2,795 requests/s — about twice a direct connection to Postgres (1,321). pgbouncer in our simple setup (scram, one process, a pool of 32) gave 275 — a measurement of our setup, not a limit of pgbouncer. An application that already has its own pool sees no gain.
A moved organization pays for distance: its latency is almost linear in the round-trip time. At 43 ms a read through fdw takes 352 ms and through fdw+direct 133 ms; an update 351 and 89 ms. The same page has the ceilings by number of clients and of organizations, the pause of a move and the load limit: Performance. Where the round trips come from and what to tune is explained there too.
Improved by changes made after these measurements, not re-measured:
LokaDB promises one thing: the rows of the chosen tables of a moved organization are stored only in that organization's database.
lokadb check -proxy-hosts verifies pg_hba). Roles that bypass RLS are refused by the proxy.fdw profile, the moved rows in transit through the cloud Postgres (memory, temporary files, logs if log_statement is on). The full list is in Limits and isolation; promise customers isolation only together with that list.Report vulnerabilities as described in the security policy.
LokaDB is under active development by a small team. The core — check, enable, the proxy, move-org, the way back, migrations, the tunnel — is complete for the supported scope and is covered by an end-to-end stand and a suite of regression checks for every defect found so far. It runs in production at KeepPlain, our own Laravel SaaS on Postgres, where it started. What is next is in the Roadmap.
| Install on your database | from nothing to a proxy in front of your own Postgres, then the first organization moved |
| Quickstart | run the demo locally |
| Configuration | proxy.json (proxy), relay.json, issuer.json, the spec file, passwords |
| Compatibility check | lokadb check: findings, verdicts, suggestions, latency forecast, JSON, CI baseline |
| Routing | how the organization is found, the policy for statements without one, declarations |
| Profiles and cooperative mode | fdw, fdw+direct, direct; the application naming the organization |
| Tunnel | relay, agent, enrolment, renewal, revocation, high availability, TLS |
| Moving organizations | enable, move-org, large organizations, where the customer database comes from |
| The way back | move-back, repoint, disable |
| Migrations |
lokadb check is open and complete in every lokadb binary and image: the schema and catalog, permission probes, blockers and limitations, the workload, suggested routing declarations with a ready patch (-suggest, -patch), the latency forecast with N+1 detection (-rtt), feed index advice and JSON for CI.
lokadb/check has the GitHub Action that runs it on every pull request of your application, the report format (JSON Schema, finding codes, sample reports) and the check documentation.
lokadb.com is LokaDB Cloud, the paid part: a panel and an API that run check, enable and moves through the open runner inside your network (your database credentials stay there), the check reports readable in the panel, an installer and a portal for your customers, alerts, webhooks and billing. See LokaDB Cloud.
Issues and pull requests are welcome; see Contributing. Go code is built and tested in Docker (golang:1.25); a change that touches routing, moving or the tunnel should come with a check in e2e/defects that fails before it and passes after.
DDL replay, schema-diff/schema-sync, refs-diff/refs-sync |
| Schemas and keys | non-public schemas, UUID and text keys, composite keys, UUID organizations |
| Limits and isolation | what LokaDB does not isolate, known limitations, deployment checklist |
| Performance | round trips, profiles, pools and caches, tuning |
| Testing | the e2e stand and the regression checks |