rsql|

rsql

Provision and operate isolated SQLite databases behind one HTTP service.

2 min read Updated 2026-07-27 #rsql#sqlite#multi-tenant

SQLite isolation for multi-tenant systems

A SQLite database for every tenant.

rsql provisions independent SQLite databases through one HTTP service. Your gateway resolves the tenant; rsql enforces the namespace boundary, quota, and database lifecycle.

Request trace GET /contacts?status=active
  1. 01
    ApplicationAuthenticated request
    user_83
  2. 02
    GatewayResolve namespace
    tenant_acme
  3. 03
    rsqlAuthorize data route
    /v1/tenant_acme/...
  4. 04
    SQLiteOpen isolated database
    sharded namespace file
Namespace fixed before SQL execution200 OK

Benchmark results

Throughput across parallel tenant workloads.

The fixed-operation benchmark rotates across 1,000 independent databases and verifies every persisted row. Read the methodology.

Point reads
54.1k/s aggregate
Read latency
12.2 ms p95
Batched writes
114k/s rows · FULL
Parallel namespaces
1,000 tested

Median of 3 fixed-operation runs · 20-row write batches · zero request errors

Namespace boundary

Isolation is a database file, not a filter.

Each namespace owns the state and runtime resources that could otherwise leak or interfere across tenants.

Storage

Independent schema, data, and WAL

No shared tenant column and no application-level row filter defines the boundary.

hashed .db file
Runtime

Separate pools and writer lock

Reads remain concurrent while writes serialize within one database, not across the fleet.

pools on demand
Limits

Quota and health per namespace

Storage, traffic, latency, contention, schema counts, subscribers, and growth share one overview.

GET /overview
Movement

Stream changes, exports, and backups

SSE events and streamed database or CSV responses avoid buffering tenant datasets in the gateway.

SSE · CSV · SQLite

Deployment boundary

Keep identity in the gateway. Keep data in rsql.

The administrative credential never reaches tenant code. The gateway exposes only the data operations the application needs.

Your gateway

  • Authenticate the caller
  • Map user or account to namespace
  • Allow only application routes
  • Attach the private rsql token

rsql

  • Provision and migrate databases
  • Execute schema, row, and query APIs
  • Enforce storage quotas
  • Report health and stream changes

Go gateway client

Bind once to the resolved namespace.

The database client exposes schema, table, query, event, and export operations for that namespace. Namespace administration remains on the parent client.

Go client guide
client, err := rsql.New(rsql.Config{
    BaseURL: "http://rsql:8080",
    Token:   os.Getenv("RSQL_API_TOKEN"),
})
db, err := client.Database(resolvedNamespace)
contacts, err := db.Table("contacts")
rows, err := contacts.Rows.List(ctx, map[string][]string{
    "status": {"eq.active"},
})

Install

Start with the interface your system already uses.

The quickstart creates a local server, namespace, table, and first row.

Debianapt install ./rsql_1.0.0_amd64.deb
Rocky Linuxdnf install ./rsql-1.0.0-1.x86_64.rpm
TypeScriptbun add @k2b/rsql
Go clientgo get github.com/k2b-dev/rsql@v1.0.0