Written in Rust · Apache 2.0

etcd, backed by your database

Rhino is a drop-in etcd v3 gRPC server that stores everything in a relational database or Redis. Same API your tools already speak. Simpler operations. No more Raft.

Get Started View Source
# Add rhino to your project $ cargo add rhino   # Or run the server standalone $ rhino --dsn sqlite:///var/lib/rhino/state.db
100%
Rust — memory safe, zero GC
gRPC
Full etcd v3 API compatibility
0
Consensus protocols required
4
Pluggable backends (SQL + Redis)
Features

Everything etcd does.
Without the complexity.

Rhino implements the etcd v3 gRPC API surface, so existing clients, tools, and Kubernetes distributions work out of the box. Under the hood, it's just SQL.

KV Transactions

Atomic compare-and-swap with revision-based optimistic concurrency. Create, update, and delete with the guarantees you expect.

Watch Streams

Real-time gRPC streaming of key changes with prefix matching. Supports historical replay from any revision.

Revision History

Every mutation is appended with a monotonic revision. Query historical state at any point in time with full fidelity.

Range Queries

List keys by prefix with pagination and count support. Backed by indexed SQL queries for consistent performance.

Auto-Compaction

Background compaction removes old revisions on a configurable schedule. Keep your database lean without manual intervention.

Async-First

Built on Tokio and Tonic. Fully async from gRPC handler to database query. Non-blocking I/O throughout the entire stack.

Architecture

A translation layer, not a database

Rhino sits between your etcd clients and a SQL database. It translates gRPC calls into SQL queries, handling revisions, watches, and compaction transparently. Read the full architecture doc →

Your application
etcd Client
gRPC v3
API shim
Rhino
SQL / Redis
Storage
SQLite / Postgres / MySQL / Redis
Backends

Your database. Your rules.

Rhino's pluggable backend trait means you pick the database that fits your operational reality. Run embedded with SQLite, scale up with Postgres, use MySQL, or go in-memory with Redis.

SQLite
ready
PostgreSQL
ready
MySQL
ready
Redis
ready
Quickstart

Up and running in minutes

Embed Rhino as a library, or run it as a standalone server. Either way, your etcd clients connect as if nothing changed. Full getting started guide →

lib.rs — embed as a crate
use rhino::{RhinoServer, SqliteBackend};

let backend = SqliteBackend::new(
    "sqlite:///var/lib/rhino/state.db"
).await?;

let server = RhinoServer::new(backend);
server.serve("0.0.0.0:2379").await?;
shell — use with etcdctl
# Put a key
$ etcdctl put /registry/pods/default/nginx \
    '{"kind":"Pod"}'
OK

# Read it back
$ etcdctl get /registry/pods/default/nginx
/registry/pods/default/nginx
{"kind":"Pod"}

# Watch for changes
$ etcdctl watch /registry/pods/ --prefix

Ready to simplify your stack?

Replace etcd with a database you already know how to operate, back up, and scale.

Star on GitHub View Quickstart