Aurora DB
A lightweight, real-time embedded database for modern Rust applications.
Why Aurora?
Most embedded databases make you choose: raw key-value stores with manual everything, or heavy SQL engines with complex setup. Aurora fills the gap for building real-time applications without external services — combining storage, indexing, pub/sub, reactive queries, and background workers into a single embedded crate.
- Real-time by default. Changes propagate instantly via built-in PubSub and reactive query watchers.
- Two query styles. Fluent Rust builder API for type safety, or AQL (Aurora Query Language) for flexible GraphQL-style queries.
- Hybrid storage. Hot data lives in memory (LRU cache); the rest persists to disk via Sled with WAL crash recovery.
Installation
[]
= "5.1.0"
= { = "1", = ["full"] }
Optional features:
# REST API via Actix-web
= { = "5.1.0", = ["http"] }
Opening a Database
use ;
// Simple open
let db = open.await?;
// With full configuration
let db = with_config.await?;
Two Query APIs
Option 1 — Fluent Rust API
Best for type-safe, direct integration in Rust code.
use ;
use FieldDefinition;
// Define schema
db.new_collection.await?;
// Insert
let id = db.insert_into.await?;
// Query
let users = db.query
.filter
.order_by // false = DESC
.limit
.collect
.await?;
// First match
let user = db.query
.filter
.first_one
.await?;
// Count
let total = db.query.count.await?;
// Delete matching
let deleted = db.query
.filter
.delete
.await?;
Filter operators available on FilterBuilder:
eq · ne · gt · gte · lt · lte · in_values · contains · starts_with · between · And · Or
Option 2 — AQL (Aurora Query Language)
GraphQL-style syntax. Best for flexible queries, scripts, or network APIs.
use ExecutionResult;
let result = db.execute.await?;
if let Query = result
AQL Reference
Schema Definition
schema {
define collection users {
username: String @unique
email: String @unique
age: Int @indexed
active: Boolean
tags: [String]
}
}
Field types: String · Int · Float · Boolean · Uuid · Object · [Type] (arrays)
Directives: @unique enforces uniqueness · @indexed builds a secondary index for fast lookups
Insert
mutation {
insertInto(collection: "users", data: {
username: "alice",
email: "alice@example.com",
age: 28,
active: true,
tags: ["rust", "databases"]
}) { id }
}
Query with Filters
query {
users(
where: {
and: [
{ role: { eq: "admin" } },
{ active: { eq: true } },
{ age: { gte: 18 } }
]
},
orderBy: { age: DESC },
limit: 20,
offset: 0
) {
username
email
age
}
}
Supported filter operators:
| Operator | Description |
|---|---|
eq / ne |
Equal / not equal |
gt / gte / lt / lte |
Numeric comparisons |
in |
Value in list |
contains |
Substring match |
startsWith / endsWith |
Prefix / suffix match |
isNull / isNotNull |
Null checks |
and / or |
Logical combinators |
Cursor Pagination
query {
users(first: 10, after: "<cursor-id>", orderBy: { age: ASC }) {
edges {
cursor
node { username age }
}
pageInfo {
hasNextPage
endCursor
}
}
}
Aggregations
query {
orders {
aggregate {
count
sum(field: "amount")
avg(field: "amount")
min(field: "amount")
max(field: "amount")
}
}
}
Group By
query {
users {
groupBy(field: "role") {
key
count
aggregate {
avg(field: "age")
}
nodes {
username
age
}
}
}
}
Update & Delete
mutation {
update(
collection: "users",
data: { active: false },
where: { email: { eq: "alice@example.com" } }
) { id username }
}
mutation {
deleteFrom(
collection: "orders",
where: { status: { eq: "cancelled" } }
) { id }
}
Enqueue a Background Job
mutation {
enqueueJob(
jobType: "send_email",
payload: { to: "alice@example.com", subject: "Welcome" },
priority: HIGH,
maxRetries: 3
) { id }
}
Priority values: LOW · NORMAL · HIGH · CRITICAL
Fragments
Reusable field selections — Aurora validates fragment cycles and unknown type conditions at parse time.
fragment UserFields on users {
id
username
email
}
query {
users(where: { active: { eq: true } }) {
...UserFields
}
}
Migrations
Aurora tracks schema changes with versioned migration blocks. Each version is recorded in an internal _sys_migration store — running the same migration file multiple times is safe, already-applied versions are skipped automatically.
migrate {
"v1.1.0": {
alter collection users {
add age: Int
add role: String
}
}
"v1.2.0": {
alter collection users {
add last_login: String
}
migrate data in users {
set role = "member"
}
}
"v1.3.0": {
migrate data in users {
set role = "admin" where { email: { endsWith: "@internal.com" } }
}
}
}
Alter actions: add field: Type · drop field · rename old_name to new_name · modify field: NewType
migrate data expressions:
- String literal:
"value" - Number:
42/3.14 - Boolean:
true/false - Field reference:
other_field(copies from that field on the same document)
Result:
if let Migration = result
Reactive Queries
Watch a query live — fires instantly when matching documents are inserted, updated, or deleted.
use QueryUpdate;
let mut watcher = db.query
.filter
.debounce
.watch
.await?;
spawn;
PubSub
Low-level broadcast channel for document changes.
// Listen to a single collection
let mut listener = db.listen;
// Listen to all collections
let mut listener = db.listen_all;
spawn;
AQL Subscription
let mut stream = db.stream.await?;
while let Ok = stream.recv.await
Background Workers
Durable, prioritised job queue with persistent state.
use ;
let workers = new?;
workers.register_handler.await;
workers.start.await?;
workers.enqueue.await?;
workers.stop.await?;
Job priorities: Low · Normal · High · Critical
Job statuses: Pending · Running · Completed · Failed · DeadLetter
Configuration Reference
AuroraConfig
Architecture
┌──────────────────────────────────────────────┐
│ Application Layer │
├──────────────────────────────────────────────┤
│ PubSub │ Reactive │ Workers │ Audit │
├──────────────────────────────────────────────┤
│ AQL Engine │ Fluent Rust API │
├──────────────────────────────────────────────┤
│ Hot Cache (In-Memory LRU) │ Indexes │
├─────────────────────────────┴────────────────┤
│ WAL + Cold Storage (Sled) │
└──────────────────────────────────────────────┘
| Layer | Role |
|---|---|
| Hot Cache | LRU in-memory store for recently accessed documents |
| Cold Storage | Sled-backed persistent store for all durable data |
| WAL | Write-ahead log; replayed on startup for crash recovery |
| Write Buffer | Batches writes in memory for high-throughput ingestion |
| Indexes | Bitmap + secondary indexes for fast filtered queries |
| AQL Engine | Parses and executes GraphQL-style queries with validation |
| PubSub | Broadcast channel for low-latency change events |
| Reactive | Query watchers that diff results on each mutation |
| Workers | Persistent priority job queue with durable state |
License
MIT — see LICENSE for details.