https://github.com/microscaler/lifeguard
Lifeguard is a Database connection pool for Postgres built on non blocking coroutines with the ability handle significant query load.
https://github.com/microscaler/lifeguard
connection-pooling otel-configured-true postgresql postgresql-database
Last synced: 5 months ago
JSON representation
Lifeguard is a Database connection pool for Postgres built on non blocking coroutines with the ability handle significant query load.
- Host: GitHub
- URL: https://github.com/microscaler/lifeguard
- Owner: microscaler
- License: apache-2.0
- Created: 2025-05-15T10:34:55.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2026-01-20T19:16:19.000Z (5 months ago)
- Last Synced: 2026-01-20T19:21:39.329Z (5 months ago)
- Topics: connection-pooling, otel-configured-true, postgresql, postgresql-database
- Language: Rust
- Homepage:
- Size: 4.13 MB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# π Lifeguard: Coroutine-Driven Database Runtime for Rust
**Lifeguard** is a **complete, production-grade ORM and data access platform** built from the ground up for Rust's `may` coroutine runtime. This is not a wrapper or adapterβit's a **parallel universe ORM** that provides SeaORM-like functionality but is architected natively for coroutines.
---
## π₯ Why Lifeguard?
**Lifeguard** is a **complete, production-grade ORM and data access platform** built from the ground up for Rust's `may` coroutine runtime. This is not a wrapper or adapterβit's a **parallel universe ORM** that provides SeaORM-like functionality but is architected natively for coroutines.
**The Problem:** Existing Rust ORMs (SeaORM, Diesel, SQLx) are built for async/await and Tokio. The `may` coroutine runtime uses stackful coroutines, not async futures. These are **fundamentally incompatible architectures**βyou cannot bridge them without significant performance penalties.
**The Solution:** Build a complete ORM from scratch using `may_postgres` (coroutine-native PostgreSQL client). No async runtime. No Tokio. Pure coroutine I/O.
**Why This Matters:**
- **BRRTRouter** (the coroutine API framework) needs blistering fast database access for high-throughput applications
- High-performance microservices need predictable, low-latency database access without async overhead
- Applications with extreme scale requirements (millions of requests/second) need efficient connection pooling when database connections are limited
- Coroutines offer deterministic scheduling, lower memory overhead, and predictable latency
- But without a proper ORM, developers are forced to choose: async ORM (overhead) or raw SQL (no safety)
**Lifeguard solves this** by providing a complete data platform that matches SeaORM's feature set but is built for coroutines, plus **distributed cache coherence** (LifeReflector) that no other ORM provides.
---
## π What We're Building
### Core ORM: LifeModel & LifeRecord
A complete ORM system with two primary abstractions:
**LifeModel** (Immutable Database Rows)
- Represents database rows as immutable Rust structs
- Generated via `#[derive(LifeModel)]` procedural macro
- Provides type-safe query builders
- Automatic row-to-struct mapping
- Complete SeaORM API parity
**LifeRecord** (Mutable Change Sets)
- Separate abstraction for inserts and updates
- Generated via `#[derive(LifeRecord)]` procedural macro
- Type-safe mutation builders
- Automatic SQL generation via SeaQuery
- Change tracking (dirty fields)
```rust
#[derive(LifeModel)]
#[table = "users"]
struct User {
#[primary_key]
id: i64,
email: String,
is_active: bool,
}
#[derive(LifeRecord)]
struct NewUser {
email: String,
}
// Usage - no async/await needed!
let user = NewUser { email: "test@example.com".into() }
.insert(&pool)?;
let found = User::find_by_id(&pool, user.id)?;
let users = User::find()
.filter(User::Email.eq("test@example.com"))
.all(&pool)?;
```
### Connection Pool: LifeguardPool
A sophisticated connection pool designed for extreme scale:
- **Persistent connections:** Pre-allocated, long-lived Postgres connections (no on-demand creation)
- **Semaphore-based concurrency:** Bounded acquisition prevents connection storms
- **Health monitoring:** Automatic detection and reconnection of failed connections
- **Aggressive reuse:** Every connection handles thousands of requests per second
- **Coroutine-native:** No async runtime, pure coroutine I/O
**For High-Scale Applications:** When database connections are limited (e.g., 100-500 connections) but traffic is extreme (millions of requests per second), connection pooling becomes critical. LifeguardPool makes a small number of connections (the 300 Spartans) handle massive traffic (the Persian Empire) through aggressive connection reuse and intelligent pooling tactics.
### The Killer Feature: LifeReflector
**Distributed cache coherence system**βthis is Lifeguard's unique advantage:
A **standalone microservice** that maintains cluster-wide cache coherence:
- **Leader-elected Raft system:** Only one active reflector at a time (no duplicate work)
- **Postgres LISTEN/NOTIFY integration:** Subscribes to database change events
- **Intelligent cache refresh:** Only updates keys that exist in Redis (TTL-based active set)
- **Zero-stale reads:** Redis always reflects current database state
- **Horizontal scaling:** All microservices benefit from single reflector
**How It Works:**
1. LifeRecord writes to Postgres β triggers `NOTIFY`
2. LifeReflector (leader) receives notification
3. Checks if key exists in Redis (active item)
4. If exists β refreshes from database β updates Redis
5. If not β ignores (inactive item, TTL expired)
6. All microservices read from Redis β always fresh data
**Result:** Oracle Coherence-level cache consistency with Postgres + Redis, but lighter, faster, and open source.
### Transparent Caching System
Lifeguard provides transparent caching that uses PostgreSQL as the gods designed it:
- **Check Redis first:** Sub-millisecond reads if cached
- **Read from replicas:** When healthy (WAL lag < threshold)
- **Write to primary:** Always (as PostgreSQL was designed)
- **LifeReflector keeps cache fresh:** Automatic coherence across microservices
Your application code doesn't need to know about Redis, replicas, or cache coherence. It just calls `User::find_by_id(&pool, 42)?` and Lifeguard handles the rest.
### Replica Read Support
Advanced read routing with WAL lag awareness:
- **WAL position tracking:** Monitors `pg_current_wal_lsn()` vs `pg_last_wal_replay_lsn()`
- **Dynamic health checks:** Automatically detects replica lag
- **Intelligent routing:** Routes reads to replicas only when healthy
- **Automatic fallback:** Falls back to primary if replicas are stale
- **Strong consistency mode:** Optional causal read-your-writes consistency
**Read Preference Modes:**
- `primary` - Always read from primary
- `replica` - Use replicas when healthy
- `mixed` - Automatic selection (Redis β replica β primary)
- `strong` - Causal consistency (wait for replica to catch up)
### Complete Feature Set
**ORM Features (SeaORM Parity):**
- β
Complete CRUD operations
- β
Type-safe query builders
- β
Relations (has_one, has_many, belongs_to, many_to_many)
- β
Migrations (programmatic, data seeding, advanced operations)
- β
Transactions
- β
Raw SQL helpers
- β
Batch operations
- β
Upsert support
- β
Pagination helpers
- β
Entity hooks & lifecycle events
- β
Validators
- β
Soft deletes
- β
Auto-managed timestamps
**Competitive Features:**
- β
Schema inference (Diesel `table!` macro equivalent)
- β
Session/Unit of Work pattern (SQLAlchemy)
- β
Scopes (ActiveRecord)
- β
Model Managers (Django)
- β
F() Expressions (Django)
- β
Advanced eager loading strategies (SQLAlchemy)
**Unique Features (No Other ORM Has):**
- β
**LifeReflector** - Distributed cache coherence
- β
**Coroutine-native** - No async overhead
- β
**WAL-based replica routing** - Automatic health monitoring
- β
**TTL-based active set** - Adaptive caching
---
## ποΈ Architecture Overview
### New Architecture (Post-Rebuild)
```mermaid
graph TD
App[Application Code] --> Pool[LifeguardPool]
Pool --> Executor[LifeExecutor]
Executor --> may_postgres[may_postgres]
may_postgres --> PostgreSQL[PostgreSQL]
App --> LifeModel[LifeModel / LifeRecord]
LifeModel --> SeaQuery[SeaQuery SQL Builder]
SeaQuery --> Executor
App --> Redis[Redis Cache]
Redis --> LifeReflector[LifeReflector Service]
PostgreSQL -- NOTIFY --> LifeReflector
LifeReflector --> Redis
style App fill:#add8e6,stroke:#333,stroke-width:2px
style Pool fill:#90ee90,stroke:#333,stroke-width:2px
style Executor fill:#90ee90,stroke:#333,stroke-width:2px
style LifeModel fill:#90ee90,stroke:#333,stroke-width:2px
style SeaQuery fill:#90ee90,stroke:#333,stroke-width:2px
style may_postgres fill:#90ee90,stroke:#333,stroke-width:2px
style PostgreSQL fill:#c0c0c0,stroke:#333,stroke-width:2px
style Redis fill:#ffcccb,stroke:#333,stroke-width:2px
style LifeReflector fill:#add8e6,stroke:#333,stroke-width:2px
```
**Key Components:**
- **LifeguardPool**: Persistent connection pool with semaphore-based acquisition
- **LifeExecutor**: Database execution abstraction over `may_postgres`
- **LifeModel/LifeRecord**: Complete ORM layer (replaces SeaORM)
- **SeaQuery**: SQL building (borrowed, compatible with coroutines)
- **may_postgres**: Coroutine-native PostgreSQL client (foundation)
- **LifeReflector**: Distributed cache coherence microservice
- **Redis**: Transparent caching layer
```mermaid
graph TD
subgraph Frontend["Frontend / Clients"]
Web[Web App]
Mobile[Mobile App]
API[API Clients]
end
subgraph BFF["BFF Layer
Built with BRRTRouter"]
BFF_Service[Backend for Frontend
API Gateway / Router]
end
subgraph Backend["Backend Microservices
Your Business Logic"]
MS1[User Service]
MS2[Product Service]
MS3[Order Service]
MSN[Service N
Your Domain]
end
subgraph Lifeguard
Pool[LifeguardPool]
Executor[LifeExecutor]
LifeModel[LifeModel / LifeRecord]
SeaQuery[SeaQuery]
end
subgraph Data Layer
may_postgres[may_postgres]
PostgreSQL[(PostgreSQL)]
Redis[(Redis Cache)]
end
subgraph LifeReflector
Reflector[LifeReflector Leader]
end
Web --> BFF_Service
Mobile --> BFF_Service
API --> BFF_Service
BFF_Service --> MS1
BFF_Service --> MS2
BFF_Service --> MS3
BFF_Service --> MSN
MS1 --> Pool
MS2 --> Pool
MS3 --> Pool
MSN --> Pool
Pool --> Executor
Executor --> LifeModel
LifeModel --> SeaQuery
SeaQuery --> Executor
Executor --> may_postgres
may_postgres --> PostgreSQL
MS1 --> Redis
MS2 --> Redis
MS3 --> Redis
MSN --> Redis
PostgreSQL -- NOTIFY --> Reflector
Reflector --> Redis
style Frontend fill:#e1f5ff
style Web fill:#e1f5ff
style Mobile fill:#e1f5ff
style API fill:#e1f5ff
style BFF fill:#add8e6
style BFF_Service fill:#add8e6
style Backend fill:#d4edda
style MS1 fill:#d4edda
style MS2 fill:#d4edda
style MS3 fill:#d4edda
style MSN fill:#d4edda
style Pool fill:#90ee90
style Executor fill:#90ee90
style LifeModel fill:#90ee90
style may_postgres fill:#90ee90
style PostgreSQL fill:#c0c0c0
style Redis fill:#ffcccb
style Reflector fill:#add8e6
```
### Connection Pool Architecture
```mermaid
graph TD
subgraph LifeguardPool["LifeguardPool
The 300 Spartans"]
S[Semaphore
max_connections tokens
100-500 limit]
subgraph Slots["Connection Slots
Persistent & Reused"]
C1[Slot 1
in_use: false
ready]
C2[Slot 2
in_use: true
executing query]
C3[Slot 3
in_use: false
ready]
CN[Slot N
in_use: false
ready]
end
end
subgraph Traffic["Incoming Traffic
The Persian Empire"]
R1[Request 1]
R2[Request 2]
R3[Request 3]
RN[Request N
millions/sec]
end
Traffic -->|acquire| S
S -->|find free| Slots
Slots -->|mark in_use| C2
C2 -->|execute query| PG[PostgreSQL
The Pass]
PG -->|result| C2
C2 -->|release| S
C2 -->|mark free| Slots
C2 -->|ready for| Traffic
style LifeguardPool fill:#fff4e1
style S fill:#fff4e1
style Slots fill:#e1ffe1
style PG fill:#e1ffe1
style Traffic fill:#ffe1e1
Note[100 connections
handle millions of requests
through aggressive reuse]
LifeguardPool --> Note
```
### LifeReflector Cache Coherence
```mermaid
sequenceDiagram
participant LifeRecord
participant Postgres
participant LifeReflector
participant Redis
participant LifeModel
LifeRecord->>Postgres: Write (INSERT/UPDATE/DELETE)
Postgres->>Postgres: Commit Transaction
Postgres->>LifeReflector: NOTIFY table_changes, '{"id": 42}'
LifeReflector->>Redis: EXISTS lifeguard:model:table:42?
alt Key Exists (Active Item)
LifeReflector->>Postgres: SELECT * FROM table WHERE id = 42 (from Primary)
Postgres-->>LifeReflector: Fresh Data
LifeReflector->>Redis: SETEX lifeguard:model:table:42
else Key Not Exists (Inactive)
LifeReflector->>LifeReflector: Ignore (item not cached, TTL expired)
end
LifeModel->>Redis: Read (GET lifeguard:model:table:42)
alt Cache Hit
Redis-->>LifeModel: Cached Data (Fresh)
else Cache Miss
LifeModel->>Postgres: Read (SELECT * FROM table WHERE id = 42)
Postgres-->>LifeModel: Data
LifeModel->>Redis: SETEX lifeguard:model:table:42
end
```
---
## π» Getting Started
**Note:** Lifeguard is currently being rebuilt from scratch. The following examples show the target API (not yet implemented).
### Installation
```toml
[dependencies]
lifeguard = { git = "https://github.com/microscaler/lifeguard" }
```
### Basic Usage
```rust
use lifeguard::*;
// Create connection pool
let pool = LifeguardPool::new("postgresql://user:pass@localhost/dbname")?;
// Define model
#[derive(LifeModel)]
#[table = "users"]
struct User {
#[primary_key]
id: i64,
email: String,
is_active: bool,
}
// Query (no async/await needed!)
let user = User::find_by_id(&pool, 1)?;
let users = User::find()
.filter(User::Email.eq("test@example.com"))
.all(&pool)?;
// Insert
#[derive(LifeRecord)]
struct NewUser {
email: String,
}
let user = NewUser { email: "test@example.com".into() }
.insert(&pool)?;
```
### With Caching (Transparent)
```rust
// Caching is transparent - no code changes needed!
// Lifeguard automatically:
// 1. Checks Redis first
// 2. Falls back to database if cache miss
// 3. Caches result for future reads
// 4. LifeReflector keeps cache fresh
let user = User::find_by_id(&pool, 1)?; // May come from Redis or DB
```
### With Replicas (Automatic Health Monitoring)
```rust
// Configure read preferences
let pool = LifeguardPool::new(url)?
.with_read_preference(ReadPreference::Mixed); // Redis β replica β primary
// Lifeguard automatically:
// 1. Checks Redis first
// 2. Routes to healthy replicas
// 3. Falls back to primary if replicas lagged
// 4. Monitors WAL lag continuously
let users = User::find().all(&pool)?; // Automatically routed
```
---
## π Observability
Comprehensive instrumentation for production operations:
### Prometheus Metrics
- `lifeguard_pool_size` - Current pool size
- `lifeguard_active_connections` - Active connections
- `lifeguard_connection_wait_time` - Time waiting for connection
- `lifeguard_query_duration_seconds` - Query execution time
- `lifeguard_query_errors_total` - Query errors
- `lifeguard_cache_hits_total` - Cache hits
- `lifeguard_cache_misses_total` - Cache misses
- `lifeguard_replica_lag_bytes` - Replica lag (bytes)
- `lifeguard_replica_lag_seconds` - Replica lag (seconds)
- `lifeguard_replicas_healthy` - Number of healthy replicas
### OpenTelemetry Tracing
- Distributed tracing for database operations
- Spans for: connection acquisition, query execution, cache operations
- Integration with existing OpenTelemetry infrastructure
### LifeReflector Metrics
- `reflector_notifications_total` - Notifications received
- `reflector_refreshes_total` - Cache refreshes
- `reflector_ignored_total` - Ignored notifications (inactive items)
- `reflector_active_keys` - Active cache keys
- `reflector_redis_latency_seconds` - Redis operation latency
- `reflector_pg_latency_seconds` - PostgreSQL operation latency
- `reflector_leader_changes_total` - Leader election events
---
## π§ͺ Testing
Lifeguard includes a comprehensive testkit for testing database operations:
```rust
use lifeguard::testkit::*;
#[test]
fn test_user_operations() {
let pool = test_pool!();
let user = NewUser { email: "test@example.com".into() }
.insert(&pool)?;
assert_eq!(user.email, "test@example.com");
}
```
The testkit provides:
- Test database setup/teardown
- Transaction rollback after each test (clean state)
- Fixture loading helpers
- Test database isolation
---
## πΊοΈ Roadmap
### Epic 01: Foundation (Weeks 1-3)
- β
Remove SeaORM and Tokio dependencies
- β
Integrate `may_postgres` as database client
- β
Implement `LifeExecutor` trait
- β
Redesign `LifeguardPool` for `may_postgres`
- β
Basic metrics and observability
- β
Transaction support
- β
Raw SQL helpers
### Epic 02: ORM Core (Weeks 3-6)
- β
Build `LifeModel` derive macro
- β
Build `LifeRecord` derive macro
- β
Implement basic CRUD operations
- β
Integrate SeaQuery for SQL building
- β
Type-safe query builders
- β
Batch operations
- β
Upsert support
- β
Pagination helpers
- β
Entity hooks & lifecycle events
- β
Validators
- β
Soft deletes
- β
Auto-managed timestamps
- β
Session/Unit of Work pattern
- β
Scopes
- β
Model Managers
- β
F() Expressions
### Epic 03: Migrations (Weeks 6-8)
- β
Implement `LifeMigration` trait
- β
Build migration runner
- β
Create CLI tooling (`lifeguard migrate`)
- β
Support core PostgreSQL features
- β
Programmatic migrations and data seeding
- β
Advanced migration operations
### Epic 04: v1 Release (Weeks 8-10)
- β
Complete PostgreSQL feature support
- β
Testkit infrastructure
- β
Comprehensive documentation
- β
Integration with BRRTRouter
- β
Performance benchmarks
### Epic 05: Advanced Features (Weeks 10-14)
- β
LifeReflector (distributed cache coherence)
- β
Redis integration
- β
Replica read support with WAL lag awareness
- β
Complete relation support
- β
Materialized views
- β
Query cache support
- β
Cache statistics & monitoring
### Epic 06: Enterprise Features (Weeks 15 - 20)
- β
PostGIS support
- β
Partitioning
- β
Triggers and stored procedures
- β
Schema introspection tools (Diesel `table!` equivalent)
- β
Code generation from database
- β
Schema-first design
See [EPICS](./docs/EPICS/) for detailed stories and progress tracking.
---
## π― Competitive Metrics: Lifeguard vs Rust ORMs
*Implementation status based on current codebase analysis (see `lifeguard-derive/SEAORM_LIFEGUARD_MAPPING.md`)*
| Feature | Lifeguard Promise | Implementation Status | SeaORM | Diesel | SQLx |
|---------|-------------------|----------------------|--------|--------|------|
| **Concurrency Model** | β
Coroutine-native (`may`) | β
**Implemented** | β Async/await (Tokio) | β Sync-only | β Async/await (Tokio) |
| **Performance (Hot Paths)** | β
β
β
2-5Γ faster | π‘ **Architectural** | β οΈ Async overhead | β
Fast (sync) | β οΈ Async overhead |
| **Performance (Small Queries)** | β
β
β
10Γ+ faster | π‘ **Architectural** | β οΈ Future allocation | β
Fast | β οΈ Future allocation |
| **Memory Footprint** | β
β
Low (stackful coroutines) | π‘ **Architectural** | β οΈ Higher (heap futures) | β
Low | β οΈ Higher (heap futures) |
| **Predictable Latency** | β
β
β
Deterministic scheduling | π‘ **Architectural** | β οΈ Poll-based (variable) | β
Predictable | β οΈ Poll-based (variable) |
| **Type Safety** | β
β
β
Compile-time validation | β
**Implemented** | β
β
Compile-time validation | β
β
β
Strong compile-time | β
β
Compile-time SQL checks |
| **ORM Features** | β
β
β
Complete (SeaORM parity) | π‘ **67% Complete** (Core traits, relations, query builder) | β
β
β
Complete | β
β
Good | β Query builder only |
| **CRUD Operations** | β
β
β
Full support | β
**Implemented** (insert/update/save/delete via ActiveModelTrait) | β
β
β
Full support | β
β
Full support | β οΈ Manual SQL |
| **Relations** | β
β
β
All types (has_one, has_many, belongs_to, many_to_many) | β
**Implemented** (Complete with eager/lazy loading, composite keys, DeriveLinked) | β
β
β
All types | β
β
Basic support | β Manual joins |
| **Migrations** | β
β
β
Programmatic, data seeding, advanced ops | π‘ **Partial** (DeriveMigrationName missing, infrastructure may exist) | β
β
β
Programmatic | β
β
CLI-based | β οΈ Manual SQL |
| **Schema Inference** | β
β
β
From database (Diesel equivalent) | β **Not Implemented** | β
β
From database | β
β
β
`table!` macro | β No |
| **Query Builder** | β
β
β
Type-safe, chainable | β
**Implemented** (19/20 methods, 95% coverage) | β
β
β
Type-safe, chainable | β
β
β
Compile-time checked | β
β
Compile-time SQL |
| **Transactions** | β
β
β
Full support | β
**Implemented** (Roadmap Epic 01) | β
β
β
Full support | β
β
Full support | β
β
Full support |
| **Batch Operations** | β
β
β
insert_many, update_many, delete_many | β
**Implemented** | β
β
β
Batch support | β
β
Batch support | β οΈ Manual |
| **Upsert** | β
β
β
save(), on_conflict() | β
**Implemented** (save() method exists) | β
β
β
save(), on_conflict() | β
β
on_conflict() | β οΈ Manual SQL |
| **Pagination** | β
β
β
paginate(), paginate_and_count() | β
**Implemented** | β
β
β
Pagination helpers | β οΈ Manual | β οΈ Manual |
| **Entity Hooks** | β
β
β
before/after lifecycle events | β
**Implemented** (ActiveModelBehavior with 8 lifecycle hooks) | β
β
β
Hooks support | β No | β No |
| **Validators** | β
β
β
Field & model-level | β **Not Implemented** | β οΈ Limited | β No | β No |
| **Soft Deletes** | β
β
β
Built-in support | β **Not Implemented** | β οΈ Manual | β No | β No |
| **Auto Timestamps** | β
β
β
created_at, updated_at | β **Not Implemented** | β οΈ Manual | β No | β No |
| **Session/Unit of Work** | β
β
β
Identity map, dirty tracking | β **Not Implemented** | β No | β No | β No |
| **Scopes** | β
β
β
Named query scopes | β **Not Implemented** | β No | β No | β No |
| **Model Managers** | β
β
β
Custom query methods | β
**Implemented** (ModelManager trait + custom methods pattern) | β No | β No | β No |
| **F() Expressions** | β
β
β
Database-level expressions | β **Not Implemented** | β No | β οΈ Limited | β No |
| **Subqueries** | β
β
β
Full support | π‘ **Future** (Not yet implemented) | β
β
β
Full support | β
β
Full support | β
β
Manual SQL |
| **CTEs** | β
β
β
WITH clauses | π‘ **Future** (Not yet implemented) | β
β
β
WITH clauses | β
β
WITH clauses | β
β
Manual SQL |
| **Window Functions** | β
β
β
Full support | π‘ **Future** (Not yet implemented) | β
β
β
Full support | β
β
Full support | β
β
Manual SQL |
| **Eager Loading** | β
β
β
Multiple strategies (joinedload, subqueryload, selectinload) | β
**Implemented** (selectinload strategy with FK extraction) | β
β
β
Eager loading | β οΈ Manual | β Manual |
| **Raw SQL** | β
β
β
find_by_statement(), execute_unprepared() | β
**Implemented** (Architecture supports raw SQL) | β
β
β
Raw SQL support | β
β
β
Raw SQL support | β
β
β
Primary feature |
| **Connection Pooling** | β
β
β
Persistent, semaphore-based, health monitoring | β
**Implemented** (LifeguardPool architecture) | β
β
β
Built-in pool | β οΈ External (r2d2) | β
β
β
Built-in pool |
| **Replica Read Support** | β
β
β
WAL-based health monitoring, automatic routing | π‘ **Architectural** (Not in SeaORM mapping, may exist) | β No | β No | β No |
| **Read Preferences** | β
β
β
primary, replica, mixed, strong | π‘ **Architectural** (Not in SeaORM mapping, may exist) | β No | β No | β No |
| **Distributed Caching** | β
β
β
β
**LifeReflector (UNIQUE)** | π‘ **Architectural** (Not in SeaORM mapping, may exist) | β No | β No | β No |
| **Cache Coherence** | β
β
β
β
**Zero-stale reads (UNIQUE)** | π‘ **Architectural** (Not in SeaORM mapping, may exist) | β No | β No | β No |
| **TTL-Based Active Set** | β
β
β
β
**Adaptive caching (UNIQUE)** | π‘ **Architectural** (Not in SeaORM mapping, may exist) | β No | β No | β No |
| **PostgreSQL Features** | β
β
β
Views, materialized views, JSONB, FTS, PostGIS, partitioning | π‘ **Partial** (JSONB β
core feature, others future) | β
β
β
Most features | β
β
β
Most features | β
β
β
All features (raw SQL) |
| **Observability** | β
β
β
Prometheus, OpenTelemetry, comprehensive metrics | π‘ **Partial** (Metrics infrastructure exists) | β
β
Basic metrics | β οΈ Limited | β οΈ Limited |
| **Developer Experience** | β
β
β
Familiar API, no async/await, clear errors | β
**Implemented** (SeaORM-like API) | β
β
β
Good, async/await required | β οΈ Complex type system | β
β
Good, async/await required |
| **Learning Curve** | β
β
Moderate (familiar if you know SeaORM) | β
**Implemented** (SeaORM-like API) | β
β
Moderate | β οΈ Steep (complex macros) | β
β
Moderate |
| **Production Ready** | β
β
β
Complete observability, health checks, metrics | π‘ **Partial** (Core ORM ready, advanced features pending) | β
β
β
Production ready | β
β
β
Production ready | β
β
β
Production ready |
| **Multi-Database** | β PostgreSQL only (by design) | β
**By Design** | β
β
PostgreSQL, MySQL, SQLite | β
β
PostgreSQL, MySQL, SQLite | β
β
β
PostgreSQL, MySQL, SQLite, MSSQL |
| **Coroutine Runtime** | β
β
β
β
**Native support (UNIQUE)** | β
**Implemented** | β Incompatible | β Incompatible | β Incompatible |
### Legend
**Implementation Status Column:**
- β
**Implemented** = Feature is fully implemented and working
- π‘ **Partial/Future/Architectural** = Partially implemented, planned for future, or architectural feature (not in SeaORM mapping)
- β **Not Implemented** = Feature promised but not yet implemented
**Feature Comparison Columns:**
- β
β
β
β
= **Unique advantage** (no other ORM has this)
- β
β
β
= Excellent support
- β
β
= Good support
- β
= Basic support
- β οΈ = Limited or manual implementation required
- β = Not supported
### Implementation Status Summary
**β
Fully Implemented (Core ORM - 67% of SeaORM parity):**
- Core traits (LifeModelTrait, ModelTrait, ActiveModelTrait, ColumnTrait, PrimaryKeyTrait)
- Complete CRUD operations (insert, update, save, delete)
- Relations system (has_one, has_many, belongs_to, has_many_through) with composite key support
- Query builder (19/20 methods, 95% coverage)
- Eager/lazy loading with multiple strategies
- Pagination, batch operations, upsert
- Entity hooks (ActiveModelBehavior with 8 lifecycle hooks)
- JSON support (core feature, always enabled)
- Partial models (DerivePartialModel)
- Multi-hop relationships (DeriveLinked - competitive advantage)
**π‘ Partially Implemented / Future:**
- Migrations (infrastructure may exist, but DeriveMigrationName macro missing)
- Subqueries, CTEs, Window Functions (planned for future)
- PostgreSQL advanced features (JSONB β
, others future)
- Observability (metrics infrastructure exists, full implementation pending)
**β Not Yet Implemented (Promised but Missing):**
- Validators (field & model-level)
- Soft deletes
- Auto-managed timestamps
- Session/Unit of Work pattern
- Scopes (named query scopes)
- Model Managers (custom query methods)
- F() Expressions (database-level expressions)
- Schema inference (Diesel `table!` equivalent)
**π‘ Architectural Features (Not in SeaORM mapping, status unclear):**
- LifeReflector (distributed cache coherence)
- Replica read support with WAL-based routing
- Read preferences (primary, replica, mixed, strong)
- TTL-based active set caching
**Overall Progress:** ~67% of SeaORM feature parity achieved. Core ORM functionality is complete and production-ready. Advanced features (validators, soft deletes, scopes) and architectural features (LifeReflector, replica routing) are pending.
### Key Differentiators
**Lifeguard's Unique Advantages:**
1. **LifeReflector** - Distributed cache coherence (Oracle Coherence-level) - **NO OTHER ORM HAS THIS** (π‘ Status unclear)
2. **Coroutine-Native** - No async overhead, deterministic scheduling - **UNIQUE TO LIFEGUARD** β
3. **WAL-Based Replica Routing** - Automatic health monitoring - **UNIQUE TO LIFEGUARD** (π‘ Status unclear)
4. **TTL-Based Active Set** - Adaptive caching - **UNIQUE TO LIFEGUARD** (π‘ Status unclear)
5. **DeriveLinked Macro** - Multi-hop relationship code generation - **COMPETITIVE ADVANTAGE** β
(SeaORM doesn't have this)
6. **Session/Unit of Work** - Identity map, automatic change tracking - **NOT IN OTHER RUST ORMs** (β Not yet implemented)
**Where Lifeguard Matches or Exceeds:**
- β
Complete SeaORM API parity (67% feature coverage, core ORM complete)
- β
Relations system with composite keys and eager/lazy loading
- β
Query builder with 95% method coverage
- β
Better performance potential (2-5Γ faster on hot paths - architectural)
- β
Lower memory footprint (architectural)
- β
Predictable latency (architectural)
**Trade-offs:**
- β PostgreSQL-only (by design - enables advanced features)
- β Requires `may` coroutine runtime (not Tokio)
- β Smaller ecosystem (newer project)
- β οΈ Some promised features not yet implemented (validators, soft deletes, scopes, etc.)
### Performance Comparison (Estimated)
| Metric | Lifeguard | SeaORM | Diesel | SQLx |
|--------|-----------|--------|--------|------|
| **Simple Query Latency** | 0.1-0.5ms | 0.5-2ms | 0.2-1ms | 0.5-2ms |
| **Hot Path Throughput** | 2-5Γ faster | Baseline | 1-2Γ faster | Baseline |
| **Small Query Overhead** | Minimal | Future allocation | Minimal | Future allocation |
| **Memory per Connection** | ~100 bytes | ~1-2 KB | ~100 bytes | ~1-2 KB |
| **Concurrent Connections** | 800+ (1MB stack) | Limited by Tokio | Limited by threads | Limited by Tokio |
| **p99 Latency** | < 5ms (predictable) | 5-20ms (variable) | < 5ms (predictable) | 5-20ms (variable) |
*Note: Performance numbers are estimates based on architecture. Actual benchmarks will be published after implementation.*
### Ecosystem Compatibility
**β οΈ Important: BRRTRouter and Lifeguard are a parallel ecosystem, separate from async/await Rust.**
These are **two incompatible worlds** with the only commonality being Rust itself:
| Ecosystem | Runtime | ORM Options | Incompatible With |
|-----------|---------|-------------|-------------------|
| **BRRTRouter + Lifeguard** | `may` coroutines | Lifeguard only | SeaORM, Diesel (async), SQLx, Tokio |
| **Tokio + Async ORMs** | `async/await` | SeaORM, Diesel, SQLx | BRRTRouter, Lifeguard, `may` |
**You cannot mix and match.** If you're using BRRTRouter, you **must** use Lifeguard. The async/await ORMs (SeaORM, Diesel, SQLx) are fundamentally incompatible with the `may` coroutine runtime.
### When to Use Each Ecosystem
**Use BRRTRouter + Lifeguard if:**
- β
You're building with **BRRTRouter** (the coroutine API framework)
- β
You need **distributed cache coherence** (LifeReflector - unique to Lifeguard)
- β
You need **extreme scale** (millions of requests/second)
- β
You need **predictable latency** (API routers, real-time systems)
- β
You're **PostgreSQL-only** (enables advanced features)
- β
You want **Oracle Coherence-level functionality**
**Use Tokio + Async ORMs if:**
- β
You're using **Tokio/async-await** runtime
- β
You need **multi-database support** (PostgreSQL, MySQL, SQLite, MSSQL)
- β
You want **mature, well-documented ORMs** (SeaORM, Diesel, SQLx)
- β
You don't need distributed cache coherence
- β
You're building traditional async/await microservices
**The choice is made at the ecosystem level, not the ORM level.** Once you choose BRRTRouter, Lifeguard is your only ORM option. Once you choose Tokio, you can choose between SeaORM, Diesel, or SQLxβbut you cannot use BRRTRouter.
---
## π Performance
**Target Performance:**
- 2-5Γ faster than async ORMs on hot paths
- 10Γ+ faster on small queries (no future allocation overhead)
- Predictable p99 latency (< 5ms for simple queries)
- Lower memory footprint than async alternatives
**Real-World Use Cases:**
- **BRRTRouter**: High-throughput API routing with sub-millisecond database access (100,000+ requests/second)
- **High-Scale Microservices**: Applications requiring millions of requests/second with limited database connections
- **Low-Latency Systems**: Real-time applications needing predictable p99 latency (< 5ms) for database operations
---
## π Documentation
- [Architecture Overview](./docs/ARCHITECTURE.md)
- [Epics & Stories](./docs/EPICS/)
- [SeaORM Feature Audit](./docs/EPICS/Epic_02/SEAORM_AUDIT.md)
- [Competitive ORM Analysis](./docs/EPICS/COMPETITIVE_ORM_ANALYSIS.md)
- [Missing Features Analysis](./docs/EPICS/MISSING_FEATURES_ANALYSIS.md)
- [Blog Post](./docs/wip/LIFEGUARD_BLOG_POST.md)
---
## π€ Contributing
Lifeguard is being rebuilt from scratch. We welcome:
- π Documentation improvements
- π Bug reports
- π‘ Feature suggestions
- π§ͺ Testing and feedback
See [EPICS](./docs/EPICS/) for current development priorities.
---
## π License
Licensed under Apache-2.0.