etch
A fast, embedded database for Rust. 7 dependencies. No C code. No build scripts.
Your Rust structs live in memory, reads are direct field access through an RwLock, and a WAL keeps everything crash-safe on disk. No query engine, no serialization on read — just your types, persisted and durable.
What it is
- Schema is a Rust struct — derive two traits and you're done
- Reads are direct struct access behind an
RwLock— no deserialization, no disk I/O - Writes are atomic and crash-safe via WAL with xxh3 integrity checksums
- 1.7M durable writes/s, 79M reads/s (per record)
- 7 dependencies, pure Rust, compiles in seconds
- Rust-only — your data is your types, with zero-overhead typed access
What it is not
- Not a SQL database — no query language, no query engine, no joins
- Data must fit in memory — your entire state lives in a struct
- Single-process — no replication, no networking, no multi-process access
- No schema migrations — you version your types however you like
Installation
Or add to your Cargo.toml:
[]
= "0.3"
Quick start
Define your schema as a struct and derive Replayable + Transactable:
use ;
use ;
use BTreeMap;
That's it — the derive macros handle the rest.
// Open a file-backed store (or Store::<Music>::memory() for tests)
let store = open_wal.unwrap;
// Write — tx.artists is a Collection with typed get/put/delete
store.write.unwrap;
// Read — direct struct access, no deserialization
let state = store.read;
assert_eq!;
See the full examples:
| Example | What it shows |
|---|---|
hello_derive |
In-memory todo list — derive macros |
hello |
In-memory todo list — manual trait impls |
contacts |
Persistent contacts book — CRUD with WAL that survives restarts |
Features
- Derive macros —
#[derive(Replayable, Transactable)]eliminates ~60 lines of boilerplate per state type - Async support —
AsyncStore::open_wal+ asyncwrite/flushfor tokio runtimes viablock_in_place - Snapshot compaction — WAL auto-compacts after a configurable threshold, with optional zstd compression (
compressionfeature) - Two flush modes — immediate fsync or grouped batching for throughput
- Zero-clone writes —
Overlay+Transactablecaptures changes without cloning state - BTreeMap and HashMap — generic key types (
String,Vec<u8>, integers) viaEtchKeytrait - Pluggable backends —
WalBackend,NullBackend, or bring your own - Corruption recovery — truncates incomplete WAL entries, keeps valid prefix
Performance
Apple M4 Pro, --release. Run yourself: cargo bench
Each operation is one record — a single struct read or written.
| Operation | Throughput |
|---|---|
| Read | 79M/s |
| Insert | 2.4M/s |
| Update | 2.2M/s |
| WAL insert (1K per commit) | 220K/s |
| WAL insert (100K per commit) | 1.7M/s |
| WAL insert (1M per commit) | 1.7M/s |
| WAL reload (10M records) | 3.8s |
License
MIT