Aurora DB
A lightweight, real-time embedded database for modern Rust applications.
Why Aurora?
An embedded database for Rust — persistent storage, a query language, real-time change events, and a job queue in a single crate. No server, no external dependencies.
Installation
[]
= "0.5.1"
= { = "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?;
Data Purity & System IDs
Aurora maintains a decoupled internal tracking system to ensure your application data remains "pure."
_sid(System ID): Every document has a private internal UUIDv7 tracking key used for optimized storage and pagination. This is hidden from AQL results by default.- Application
id: Your user-providedidis stored safely as a standard field in your data object. Aurora never overwrites or maps it to the internal system ID. - Audit Mode: Enable
debug_audit: truein your execution options to expose_sidin query results.
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 { // Storage db_path: PathBuf, // required hot_cache_size_mb: usize, // default: 256 eviction_policy: EvictionPolicy, // default: LRU cold_cache_capacity_mb: usize, // default: 1024 cold_mode: ColdStoreMode, // HighThroughput | LowSpace
// Workers
workers_enabled: bool, // default: false
worker_threads: usize, // default: 4
// Write buffering
... enable_write_buffering: bool, // default: true write_buffer_size: usize, // default: 10_000 write_buffer_flush_interval_ms: u64, // default: 1_000
// Durability / WAL
enable_wal: bool, // default: true
durability_mode: DurabilityMode, // None | WAL | Strict | Synchronous
checkpoint_interval_ms: u64, // default: 10_000
// Maintenance
auto_compact: bool, // default: true
compact_interval_mins: u64, // default: 60
// Audit logging
audit_log_path: Option<String>, // writes JSONL entries when set
}
---
## 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](./LICENSE) for details.