Aurora DB
A lightweight, real-time embedded database designed for modern applications
Why Aurora Exists
Most embedded databases force you to choose: either simple key-value storage with manual indexing and caching, or heavy SQL databases with complex setup. I wanted something different.
Aurora was born from a simple need: a database that just works for building real-time applications. No external services, no complex configuration, no choosing between twenty different storage engines. Just install it, open it, and start building.
The Philosophy
Real-time by default. Data changes should propagate instantly. Your UI shouldn't poll—it should react. Background jobs should process reliably without external queues. This isn't optional; it's how modern applications work.
Lightweight without compromise. Embedded doesn't mean primitive. Aurora handles indexing, caching, pub/sub, reactive queries, and background workers—all built-in. You get production-grade features without the operational overhead.
Performance through intelligence. The hybrid hot/cold architecture wasn't an accident. Frequently accessed data lives in memory (200K ops/sec), everything else persists to disk (10K ops/sec). Schema-aware selective indexing means I only index what you actually query. Smart defaults, intelligent caching, zero configuration to get started.
The Design
Every feature in Aurora solves a real problem:
- PubSub → Because polling databases is wasteful
- Reactive Queries → Because UIs should update automatically
- Durable Workers → Because background jobs shouldn't need Redis
- Computed Fields → Because derived data shouldn't duplicate storage
- Write Buffering → Because high-throughput writes shouldn't kill performance
- Schema-Aware Indexing → Because indexing every field is insane
This wasn't scope creep—it was intentional. Building real-time apps requires all these pieces, and they should work together seamlessly.
What's Next
The current bottleneck is in-memory index management. I'm currently looking into how DiceDB, Redis, and RocksDB handle high-performance in-memory structures, exploring:
- Lock-free index structures inspired by DiceDB's concurrent patterns
- Memory-efficient data structures from Redis's designs
- RocksDB's LSM-tree approach for better write amplification
- Smarter cache eviction using access pattern analysis
Table of Contents
Getting Started
- Schema Management - Define collections and field types
- CRUD Operations - Create, read, update, and delete documents
- Querying - Filter, sort, and retrieve data
Advanced Features
- PubSub System - Real-time change notifications
- Reactive Queries - Auto-updating query results
- Durable Workers - Background job processing
- Computed Fields - Derived values from existing data
Optimization
- Performance Guide - Tuning, caching, and best practices
Quick Start
Installation
[]
= "0.3.0"
Basic Usage
use ;
async
Feature Overview
Collections & Schema
Define structured collections with type-safe fields and unique constraints.
db.new_collection?;
Powerful Querying
Filter, sort, paginate, and search your data with an intuitive API.
let products = db.query
.filter
.order_by
.limit
.collect
.await?;
Real-time Updates
Subscribe to data changes with the PubSub system.
let mut subscription = db.subscribe.await?;
while let Ok = subscription.recv.await
⚡ Reactive Queries
Automatically update query results when data changes.
let active_users = db.reactive_query
.filter
.build
.await?;
// Results automatically update when users go online/offline
let current_users = active_users.get_results.await?;
Background Jobs
Process tasks asynchronously with automatic retries.
// Define a job handler
;
// Start worker
let mut executor = new;
executor.register_handler;
executor.start.await?;
// Enqueue job
db.enqueue_job.await?;
Computed Fields
Derive values automatically from document data.
let mut registry = new;
// Full name from first + last
registry.register;
db.set_computed_fields;
High Performance
Optimized architecture with hot/cold storage and intelligent caching.
| Operation | Throughput |
|---|---|
| Hot Cache Read | ~200K ops/sec |
| Indexed Insert | ~17K ops/sec |
| Indexed Query | ~50K ops/sec |
Architecture
Aurora uses a hybrid storage architecture:
┌─────────────────────────────────────────┐
│ Application Layer │
├─────────────────────────────────────────┤
│ PubSub │ Reactive │ Workers │ Computed │
├─────────────────────────────────────────┤
│ Query Engine │
├─────────────────────────────────────────┤
│ Hot Cache (In-Memory) │ Indices │
├──────────────────────────┴───────────────┤
│ Cold Storage (Sled - On Disk) │
└─────────────────────────────────────────┘
Storage Layers
- Hot Cache: In-memory cache for frequently accessed data (~200K ops/sec)
- Cold Storage: Persistent disk storage using Sled (~10K ops/sec)
- Indices: In-memory indices for fast lookups (O(1) complexity)
Advanced Features
- PubSub: Real-time change notifications
- Reactive Queries: Auto-updating query results
- Durable Workers: Background job processing with retries
- Computed Fields: Virtual fields calculated at query time
Configuration
Customize Aurora's behavior with AuroraConfig:
use ;
let config = AuroraConfig ;
let db = open_with_config?;
Use Cases
Real-time Applications
- Chat applications with live message updates
- Collaborative editing with reactive queries
- Live dashboards with auto-updating metrics
- Gaming leaderboards
Background Processing
- Email delivery with retry logic
- Image processing pipelines
- Data exports and reports
- Webhook delivery
Data-Intensive Apps
- E-commerce with inventory tracking
- Analytics with computed metrics
- Content management systems
- IoT data collection
Best Practices
1. Index Strategy
// DO: Index frequently queried fields
db.create_index.await?;
db.create_index.await?;
// DON'T: Index every field
// Only index what you query
2. Query Optimization
// DO: Use projections and limits
let users = db.query
.select // Only needed fields
.limit // Bounded result set
.collect
.await?;
// DON'T: Unbounded queries
let users = db.query.collect.await?;
3. Write Performance
// DO: Use batch operations
db.batch_insert.await?;
// DON'T: Individual inserts in loops
for entry in log_entries
4. Real-time Updates
// DO: Use reactive queries for UI state
let online_users = new.await?;
// DON'T: Poll the database
loop
Examples
Check out the examples/ directory for complete examples:
reactive_demo.rs- Reactive queries in actioncontains_query_demo.rs- Advanced queryingindexing_performance.rs- Performance testingindex_demo.rs- Index usage patterns
Run an example:
API Reference
For detailed API documentation:
Community & Support
- GitHub: github.com/bethel-nz/aurora
- Issues: github.com/bethel-nz/aurora/issues
- Crates.io: crates.io/crates/aurora-db
Version History
v0.3.0 (Current)
- Schema-aware selective indexing (3-5x faster inserts)
- Schema caching for reduced overhead
- Optimized benchmark suite
- Fixed compiler warnings
- Comprehensive documentation
v0.2.1
- PubSub system for real-time updates
- Reactive queries
- Durable workers with retry logic
- Computed fields
- Write buffer optimization
- Multiple cache eviction policies
v0.1.x
- Initial release
- Basic CRUD operations
- Collections and schema
- Query system
- Transactions
License
MIT License - see LICENSE file for details
Ready to build? Start with the Schema Management guide!