LuraDB is a Linux-first, REST-native multi-model database built on io_uring. One small, fast process covers the three shapes of data a typical backend needs: a key-value store (TTLs, watches), JSON documents (indexes, queries), and slim relational tables (views, left joins). Its interface is a RESTful API — no proprietary protocol, no driver stack to install: every language and standard tool can talk to it out of the box, and the API is browsable down to the individual record.
Built for the small jobs, done well.
What LuraDB is not. LuraDB does not aim to be Oracle, PostgreSQL or MySQL — nor MongoDB, Cassandra or Spark. There is no analytical engine, no distributed cluster, no data-warehouse ambition: if your project needs a Data Vault, you have outgrown LuraDB — and that is by design. Features earn their place by making the small case better, not by making LuraDB bigger.
Why "Lura"? Linux + io_uring + async — the letters the architecture is built on.
LuraDB is your friendly neighborhood database.
- Docker, any OS: drop a
.debfrom the Releases intotarget/debian/, rundocker compose up -d— packaging/docker. - Linux host:
sudo apt install ./luradb_*.deb, start the service, done — Install. - Curl it:
curl http://127.0.0.1:3000/health— then the Quick tour.
| Area | What you get |
|---|---|
| Key-value | TTL · prefix listings and counts · bulk delete · resumable watch stream (SSE) · ETag with If-Match / If-None-Match: *, optionally required per domain |
| JSON documents | versioned documents with ETag · secondary indexes · search queries · NDJSON bulk load |
| Slim relational | tables, indexes, views, left joins · /sql and row endpoints · CSV/TSV import with inferred types · KVREF/JSONREF columns linking rows to keys and documents |
| One API | domains · API keys with per-domain permissions · event stream of lifecycle and DDL changes · metrics and health · logical backups with schedules, retention and restore |
| Access paths | HTTP · native HTTPS · Unix domain socket · CORS · built-in MCP server for AI assistants |
| Durability | a write is confirmed only once it is in the write-ahead log; a failed fsync stops the service so the next start recovers from the log |
| Operations | one binary · .deb with systemd service · journald logging · multicore data shards · disk and memory watch that refuses writes before the host runs dry |
LuraDB is 0.x, pre-1.0 software. On-disk formats and the REST API can
change between minor releases. See CHANGELOG.md for what
changed in each release — entries touching the REST API are marked API:,
breaking changes are marked BREAKING.
0.5.1 changes the on-disk format: the write-ahead log becomes a directory of segments, engine files move into a shard directory, and users, API key hashes and permissions move into a separate system store. A data directory written by 0.4.0 is upgraded automatically on the first start — one way. Going back to 0.4.0 needs a backup taken before the upgrade, restored into the older version.
- Linux, amd64.
- Linux kernel 6.1 or newer (io_uring with
DEFER_TASKRUN); LuraDB refuses to start on older kernels. - systemd, if you install the
.debpackage (LuraDB runs as a systemd service).
Download the latest .deb from the newest GitHub
Release and install it:
sudo apt install ./luradb_*.debapt resolves the runtime dependencies, creates the luradb system user,
generates an admin API key and enables the systemd service without
starting it, so you can review the config (bind address, data paths) before
LuraDB first runs; a notice at the end of the install says where the config
lives and how to start. The package ships its own INSTALL.md
(/usr/share/doc/luradb/INSTALL.md) with the full walkthrough: service
management, the admin key, HTTPS, the Unix-domain-socket path, updates and
removal.
No Linux machine handy? Get a .deb — from the Releases
page or built yourself — drop
it into target/debian/ and run docker compose up -d; no Rust toolchain
or package install on the host. The container shares its host's kernel, so
the host (or the VM of Docker Desktop) needs Linux 6.1 or newer too. See
packaging/docker/README.md for the
quickstart.
git clone https://github.com/hwein/luradb.git
cd luradb
git checkout main
cargo build --releaseThe toolchain is pinned in rust-toolchain.toml; rustup picks it up
automatically. To build the .deb package:
cargo install cargo-deb # once
cargo debStart the server (cargo run or the installed binary), then:
# Health check — no auth required
curl http://127.0.0.1:3000/health
# Admin API key — dev config ships a placeholder; the .deb package
# generates a real one into /etc/luradb/luradb.toml on install
grep api_key luradb.toml
# Key-value: write and read a key in the "default" domain
curl -X PUT http://127.0.0.1:3000/store-api/kv/default/keys/hello \
-H "Authorization: Bearer lura_changeme_in_production" \
-d 'world'
curl -i http://127.0.0.1:3000/store-api/kv/default/keys/hello \
-H "Authorization: Bearer lura_changeme_in_production"
# Conditional write: replace the key only if it still has the ETag
# the read above returned (412 otherwise)
curl -X PUT http://127.0.0.1:3000/store-api/kv/default/keys/hello \
-H "Authorization: Bearer lura_changeme_in_production" \
-H 'If-Match: "<etag from the read>"' \
-d 'world, again'
# JSON documents: create one in the "default" domain
curl -X POST http://127.0.0.1:3000/store-api/json/default/documents \
-H "Authorization: Bearer lura_changeme_in_production" \
-H "Content-Type: application/json" \
-d '{"name": "jane"}'In development, a browsable Swagger UI is available at /test-ui (disabled
by default; the dev luradb.toml turns it on explicitly). With
auth.enabled = true, the UI and /api-docs/openapi.json need the same
valid API key as the rest of the API; use the UI's "Authorize" button to
set it.
Requests on one connection are processed in order (HTTP/1.1 pipelining and HTTP/2 alike); open several connections for parallelism.
LuraDB ships an MCP server for AI assistants and agents (opt-in, [mcp] in
luradb.toml). It listens on its own port (3100 by default) on the
server's bind address and offers tools to list and describe domains, read
keys and documents, search, run SQL queries and read health and metrics.
Writing keys, documents and rows (read_only = false) and creating
domains, tables, views and indexes (allow_ddl = true) are separate
opt-ins; no tool deletes a domain, table, view or index. Clients
authenticate with an API key as Bearer token; clients that only speak OAuth
sign in once on a LuraDB page with their key when oauth_enabled = true
and public_url is set. Every tool runs with the permissions of that key.
LuraDB spreads its domains over several data shards by name; each shard is one thread with its own storage engines. For one domain that means: reads scale across cores — point reads run on the connection's thread, longer reads on a pool of reader threads — while writes of one domain run on exactly one core, the thread of its shard. Write parallelism is therefore at most the number of domains being written at the same time; spread independent write traffic over several domains.
The cores are split automatically between frontend workers (HTTP/TLS), data
shards and reader threads; [multicore] in luradb.toml overrides each
part. The shard count belongs to the data directory: the automatic setting
keeps the count an existing directory was written with, also after an
upgrade or a move to a host with another core count, and
luradb --migrate-shards N changes it while the server is stopped. Sizes,
memory per shard and the migration walkthrough:
INSTALL.md "Multicore" and
"Changing the shard count".
The server checks the free space of its data volumes and its own memory
use every second. Below the warn thresholds it logs a warning and
GET /health reports degraded; below the block thresholds it refuses
writes with 507 Insufficient Storage and Retry-After while reads
continue, and resumes on its own once there is room again. While memory is
short it flushes its MemTables and returns heap to the kernel. Thresholds
are set in [resources] in luradb.toml; details in
INSTALL.md "Disk and memory shortage".
A backup (POST /store-api/backups, or a schedule in [backup]) is a
logical NDJSON archive of key-value, JSON and relational domains: keys,
documents with their index definitions, and tables with their rows,
indexes, views and AUTOINCREMENT state. The scope picks what goes in: all,
one engine (kv, json, rel), one domain of one engine (kv:<domain>,
json:<domain>, rel:<domain>) or one domain name in every engine
(domain:<name>).
KVREF and JSONREF columns link to the KV and JSON domain of the same name.
They resolve after a restore when that domain is restored too or already
exists; otherwise they read as missing and are cleared, as after deleting
that domain. A restore under a new name (into_domain) links them to the
domains of the new name.
LuraDB is Fair Source (FSL-1.1-ALv2): free to use, modify and redistribute except to compete with LuraDB; each release converts to Apache 2.0 two years after publication. See LICENSE.md for the full text.
Found a vulnerability? See SECURITY.md — please do not open a public issue. For bug reports, feature proposals and code contributions, see CONTRIBUTING.md.