unsubbed.co

SlateDB

SlateDB is a self-hosted database management replacement for Amazon S3, Azure Blob Storage, and more.

An embedded key-value store built on object storage, honestly reviewed. Who actually needs this, and when does it make sense?

TL;DR

  • What it is: An open-source (Apache-2.0) embedded key-value database that writes all data to object storage (S3, GCS, MinIO, and others) instead of local disk [1][2].
  • Who it’s for: Rust, Go, or Python developers building systems that need durable embedded storage without managing a separate database process — stream processing engines, serverless functions, workflow orchestrators, and data lake tooling [2].
  • Cost savings: Eliminates the need for a managed database instance (RDS, DynamoDB, Firestore) in scenarios where you’d otherwise be paying $15–$50+/month just to keep a database running. You pay only for object storage API costs instead [1][3].
  • Key strength: Zero-disk, zero-control-plane architecture. No replication protocol to configure, no local state to manage. Drop it into your process and point it at a bucket [2].
  • Key weakness: 50–100ms write latency by design. If your workload needs sub-millisecond embedded storage (think RocksDB-style local caching), this is the wrong tool. This isn’t a drop-in RocksDB replacement — it’s a different trade-off [2].

What is SlateDB

SlateDB is a Rust library implementing a log-structured merge-tree (LSM-tree) that writes data to object storage rather than local disk. You embed it inside your process the same way you’d embed RocksDB or LevelDB, but instead of opening files on the local filesystem, it talks to an S3 bucket (or any compatible store — GCS, Azure Blob, MinIO, Tigris) [1][2].

The value proposition is simple to state and surprisingly hard to find elsewhere: durability and replication come for free from your object store, not from a replication protocol you have to run and maintain. There’s no leader election, no WAL shipping, no replica nodes. You open the database, you write keys, and those writes eventually land in S3 with 11-nines durability. Your process crashes, you restart it elsewhere, and your data is still there [2].

The project is backed by the Commonhaus Foundation and as of this writing has 2,794 GitHub stars — substantial for a low-level infrastructure library. Real companies are running it in production: TensorLake, Embucket, MerkleMap, S2, and Responsive are listed as users on the homepage [3]. Those are data infrastructure companies, which tells you something about the niche.

The library is written in Rust with official Go and Python bindings. The Rust API is the primary surface and has the most complete feature set [1].


Why people choose it

There’s no meaningful third-party review ecosystem for SlateDB yet — the project is young enough that most coverage is technical blog posts and conference talks from its own contributors, not independent evaluators. What follows is drawn from the primary sources: the GitHub README, the official documentation, and the homepage.

The core use case articulated by the project itself: workloads that are tolerant to 50–100ms write latency and want to avoid the operational overhead of running a separate database process [2]. That’s a narrower slice than it sounds, but it’s a real slice.

Versus RocksDB. This is the closest architectural peer. Both are embedded LSM-tree stores. RocksDB writes to local disk with sub-millisecond latency and handles millions of operations per second. SlateDB writes to object storage with 50–100ms write latency (mitigated by batching) and handles the throughput your object store can sustain. If you need raw embedded performance, RocksDB wins. If you need durability and horizontal read scalability without managing local disk, SlateDB wins [1][2].

Versus running PostgreSQL or DynamoDB. This is where the self-hosted cost angle becomes relevant. If you’re building a serverless function or stream processor that needs persistent state, you currently have two options: (a) spin up a database instance and pay the monthly minimum even when your function sleeps, or (b) use DynamoDB/Firestore/Cosmos at per-operation pricing that gets painful at scale. SlateDB offers (c): embed the database in your process, pay only for S3 API calls and storage, no minimum instance fee [2][3].

The multi-reader design. SlateDB supports multiple reader processes on different nodes all reading the same database from object storage. A writer batches and flushes SSTs to the bucket; readers stream those SSTs and use local read caches to minimize API costs. This pattern maps well to architectures where one writer is producing data and many readers are consuming it — a common shape for analytics pipelines and stream processing systems [2].

Writer fencing. If you’re worried about zombie writer processes corrupting your database — a real concern in distributed systems — SlateDB has built-in writer fencing. It detects old writer processes and prevents them from writing after a new writer has taken over. This is a detail that matters a lot in practice and is often bolted on as an afterthought in other systems [2].


Features

Based on the README and official documentation [1][2]:

Storage and durability:

  • All data written to object storage: S3, GCS, Azure Blob Storage, MinIO, Tigris, and any store implementing the ObjectStore trait [1]
  • SST (Sorted String Table) files flushed periodically from in-memory MemTables — flush interval is configurable [1]
  • put() returns a Future that resolves when data is durably persisted to object storage [1]
  • Optional put_with_options with await_durable: false for lower-latency writes that accept data-loss risk [1]

Read performance:

  • In-memory block cache
  • Optional on-disk read cache for frequently accessed SSTs
  • Bloom filters to skip unnecessary reads
  • Compression [1][2]

Query surface:

  • Range scans over unbound and bound key ranges [1][3]
  • Iterator seek — jump ahead to a specific key mid-scan [1]
  • Put, get, delete [1]

Advanced features:

  • ACID transactions [3]
  • Merge operator (for custom read-modify-write semantics without read-before-write) [3]
  • TTL (time-to-live) for automatic key expiration [3]
  • Checkpoints and snapshots [3]
  • Snapshot isolation — readers see a consistent view while writes are happening [2]
  • Pluggable compaction — you can provide a custom compaction strategy [2]
  • Separate compaction process — compaction can run out of process, reducing latency spikes in the writer [3]
  • Change data capture (documented in design section) [2]

Language support:

  • Rust (primary): cargo add slatedb [1]
  • Go: go get slatedb.io/slatedb-go [3]
  • Python: pip install slatedb [3]

Pricing: self-hosted math

SlateDB is a library, not a service. There’s no pricing page because there’s no product to buy. The cost question is: what do you pay to run a system that uses SlateDB versus the alternatives?

Object storage costs (what SlateDB uses): SlateDB batches writes to reduce PUT API calls — the most expensive object storage operation. Instead of making one PUT per put() call, it accumulates writes in a MemTable and flushes periodically. For most workloads, the object storage cost is dominated by storage size (cents per GB-month) plus a modest number of API calls. Exact numbers depend on your object store provider and workload.

What you’re replacing:

  • A minimal RDS instance (PostgreSQL on db.t3.micro): roughly $15–25/month even at idle
  • DynamoDB on-demand: billed per read/write unit — can be cheap at low volume but climbs fast with throughput
  • Redis for durable state: ElastiCache starts around $15–25/month for the smallest instance
  • Firebase/Firestore: free tier is generous, but production costs vary significantly by read/write volume

For a serverless or stream processing workload: If your function runs occasionally and you need durable state between invocations, a $15/month minimum database fee is pure waste for 90% of the billing period. SlateDB on S3 replaces that with pennies of API calls. For a workload that writes 1 million keys per day and reads them back, the S3 API cost is negligible — well under a dollar per month at standard S3 pricing.

The caveat: This math only works if your write latency tolerance is 50ms+. If you need sub-millisecond embedded storage, no amount of S3 cost savings justifies the architectural mismatch [2].


Deployment reality check

SlateDB is a library, not a server you deploy. “Deployment” means: add it as a dependency, give it an object store client, open a database path, and call put/get from your application code [1].

What you actually need:

  • A Rust, Go, or Python project (Rust has the most complete feature set)
  • Access to an object store — S3, GCS, MinIO, or any ObjectStore-compatible implementation
  • An async runtime (Tokio in Rust)
  • No server process to manage, no port to expose, no configuration file to maintain

The README’s quickstart is genuinely minimal. In Rust:

let object_store: Arc<dyn ObjectStore> = Arc::new(InMemory::new());
let kv_store = Db::open("/tmp/test_kv_store", object_store).await?;
kv_store.put(b"key", b"value").await?;

Swap InMemory::new() for your S3 configuration and you’re writing durably to object storage [1].

What can go wrong:

The 50–100ms write latency is not a bug — it’s the consequence of every put() waiting for an object storage flush. If you’re building something that calls put() in a user-facing request path and awaits durability, that 100ms will show up in your p99 latency. The await_durable: false option gives you sub-millisecond acknowledgment at the cost of potential data loss on crash [1][2].

The single-writer constraint is hard. SlateDB is designed for exactly one active writer per database. Writer fencing helps prevent dual-writer corruption, but you need to architect around it — typically using partitioning so each shard has one owner [2].

Object storage API costs can surprise you if you get the flush interval wrong. Too-frequent flushes = too many PUTs = unexpected S3 bills. Too-infrequent flushes = large write latency spikes when the MemTable finally flushes. Tuning this for your workload is not optional — it requires benchmarking [1][2].

The project’s documentation covers design deeply (LSM-tree structure, compaction, garbage collection, change data capture) but is lighter on operational guides for production tuning. For a library at this maturity level, that’s expected, but plan for some trial-and-error [2].


Pros and cons

Pros

  • Apache-2.0 license. No commercial restrictions, no copyleft, no “fair-code” gotchas. Embed it in a commercial product, build a managed service on top of it, ship it to customers — all fine [1].
  • Zero-disk, zero-control-plane. No replication protocol, no local state, no process to babysit. Object storage handles durability. For serverless and ephemeral compute environments, this is a meaningful operational reduction [2].
  • Multiple readers. Many reader processes across many nodes can all read the same database. For analytics and fan-out patterns, this is architecturally clean [2].
  • Writer fencing. Zombie writer protection built in, not bolted on [2].
  • Pluggable compaction. For teams with specific performance characteristics, being able to swap compaction strategy is a real feature [2].
  • Real language bindings. Rust, Go, and Python — covers most of the use cases where you’d reach for an embedded store [3].
  • Snapshot isolation and ACID transactions. Consistent reads and transactional writes in an object-storage-backed embedded store is a non-trivial engineering achievement [3].
  • Real production users. TensorLake, Embucket, MerkleMap, S2, Responsive — data infrastructure companies betting their products on it [3].

Cons

  • 50–100ms write latency. This is the central trade-off and it eliminates SlateDB from every use case that requires low-latency embedded writes. No workaround except await_durable: false, which trades durability for speed [2].
  • Single writer only. Horizontal write scaling requires you to partition at the application layer. If you don’t design for this upfront, you’ll hit it later [2].
  • Young project — 2,794 stars. The library is not yet at the maturity level of RocksDB (28K+ stars, used in production at Facebook/Meta scale). For mission-critical storage, evaluate carefully.
  • Object storage API costs require tuning. Flush interval is configurable, but “get it wrong” has a direct billing consequence. There’s no free-tier safety net here.
  • No third-party review ecosystem. You’re largely working from official documentation and reading the source code. Independent operational war stories are scarce.
  • Rust-first. The Go and Python bindings exist, but the Rust library is where features land first. If you’re not in Rust, you may be running behind [3].
  • No REST API. This is an embedded library. There is no server, no HTTP interface, no external client. You’re writing application code, not configuring a service [1].

Who should use this / who shouldn’t

Use SlateDB if:

  • You’re building a stream processing engine, workflow orchestrator, durable execution system, or data lake component in Rust, Go, or Python, and you need an embedded store that survives process restarts without a separate database process.
  • You’re deploying to serverless or ephemeral compute environments where “spin up a database instance” is an anti-pattern.
  • You’re already paying for object storage (everyone using S3/GCS is) and want to avoid a separate managed database bill.
  • Your write latency tolerance is 50ms+. If that’s a comfortable constraint, SlateDB maps cleanly to your requirements.

Skip it if:

  • You need sub-millisecond embedded storage. Use RocksDB, LevelDB, or LMDB.
  • You need multiple concurrent writers without a partitioning layer. Look at TiKV, FoundationDB, or a distributed key-value store.
  • You need SQL. SlateDB is a key-value store. There is no query language, no schema, no joins.
  • You’re a non-technical founder looking to replace a SaaS tool with a self-hosted alternative. This is a developer library, not a deployable service. It has no UI, no admin panel, and no concept of “self-hosting” in the conventional sense — it’s a dependency in your codebase.
  • You need a mature production track record with extensive operational documentation. The project is real and used in production, but it’s not at RocksDB maturity.

Alternatives worth considering

  • RocksDB — the standard embedded LSM-tree store. Sub-millisecond latency, enormous production track record (used at Meta, LinkedIn, Cockroach, TiKV). Writes to local disk. If you need raw performance and disk is acceptable, this is the default choice.
  • LevelDB — RocksDB’s predecessor, simpler, but largely replaced by RocksDB for new projects.
  • LMDB — memory-mapped embedded store. Extremely fast reads, ACID transactions. No LSM-tree, different write characteristics. Good for read-heavy workloads.
  • Sled — another Rust-native embedded store. More ergonomic API than binding to RocksDB from Rust, but less battle-tested.
  • TiKV — distributed key-value store built on RocksDB. Handles multi-writer at scale, but adds significant operational complexity.
  • FoundationDB — distributed, ACID, multi-writer. Apple’s internal infrastructure database. Excellent for complex transactional workloads, more complex to operate.
  • DuckDB — if you need analytics SQL over embedded data rather than a key-value interface. Completely different use case but often considered alongside embedded stores.
  • MinIO — if you want to self-host the object storage layer that SlateDB would write to.

For developers choosing between SlateDB and RocksDB: the question is whether you’re optimizing for local performance (RocksDB) or operational simplicity and object-storage durability (SlateDB). They’re complementary tools for different constraints.


Bottom line

SlateDB is a well-engineered solution to a specific problem: embedded durable storage for workloads that run on ephemeral or serverless compute, where local disk state is a liability and running a separate database process is operational overhead you don’t want to pay. The Apache-2.0 license, multi-reader design, and zero-disk architecture are genuine strengths. The 50–100ms write latency is a genuine constraint that disqualifies it from many use cases. At 2,794 stars with real production users in the data infrastructure space, it’s past the “toy project” threshold but hasn’t reached the operational maturity of RocksDB or FoundationDB.

If your use case fits — stream processing, durable serverless functions, workflow state, data lake tooling — it’s worth a serious evaluation. If you’re a non-technical founder looking to replace an expensive SaaS database subscription with something self-hosted, this isn’t that: it’s a library for developers, not a service you spin up. For the right developer building the right system, the cost math is real: object storage API calls instead of a managed database minimum monthly fee adds up faster than people expect over a year of production operation.


Sources

Primary sources (no independent third-party reviews available for this tool at time of writing):

  1. SlateDB GitHub Repository — README, code examples, API documentation. https://github.com/slatedb/slatedb (2,794 stars, Apache-2.0 license)
  2. SlateDB Official Documentation — Introduction, features, use cases, design. https://slatedb.io/docs/get-started/introduction/
  3. SlateDB Homepage — Feature list, language support, production users. https://slatedb.io

Features

Integrations & APIs

  • REST API

Data & Storage

  • S3 / Object Storage