Skip to content

feat: add SQLite storage backend (extenddb-storage-sqlite)#109

Open
ivanbarlog wants to merge 1 commit into
ExtendDB:mainfrom
ivanbarlog:feat/sqlite-storage-backend
Open

feat: add SQLite storage backend (extenddb-storage-sqlite)#109
ivanbarlog wants to merge 1 commit into
ExtendDB:mainfrom
ivanbarlog:feat/sqlite-storage-backend

Conversation

@ivanbarlog
Copy link
Copy Markdown

Summary

  • Introduces a new extenddb-storage-sqlite crate implementing the full DynamoDB-compatible storage layer backed by SQLite via sqlx
  • Implements all required traits: TableEngine, DataEngine, MetadataEngine, StreamEngine, BackupEngine, WorkerStore, plus all catalog/management/auth stores
  • Self-registers via the inventory crate alongside the existing PostgreSQL backend — no changes needed in the engine or server crates

Key design decisions vs the PostgreSQL backend

Concern SQLite approach
Placeholders ? positional (not $N)
Concurrency Single WAL-mode pool; writer serialization replaces FOR UPDATE
GSI/LSI updates Synchronous on every write (no async propagation queue)
Stream sequencing seq_counters table with atomic UPDATE+SELECT (no PostgreSQL sequences)
Parallel scan rowid % total_segments (vs hashtext(pk) % total_segments)
Pagination (pk > ? OR (pk = ? AND sk > ?)) OR-expansion (SQLite lacks tuple comparison)
String begins-with upper bound char(1114111) (not chr() which is PostgreSQL)
Pool Single self.pool for all catalog + data ops

Test plan

  • cargo build -p extenddb-storage-sqlite — clean build, zero errors
  • cargo clippy --all-targets -- -D warnings — zero warnings/errors
  • cargo test --workspace — 379 tests pass across all crates
  • Wire up backend = "sqlite" in extenddb.toml and run devtools/run-tests --extenddb --pytest against a live SQLite instance

🤖 Generated with Claude Code

Implements a complete DynamoDB-compatible storage backend backed by
SQLite, suitable for local development and CI environments without
requiring a PostgreSQL instance.

Key design decisions vs the PostgreSQL backend:
- Single pool (`self.pool`) for all catalog and data operations
- `?` positional placeholders throughout (not `$N`)
- No `FOR UPDATE` — SQLite's writer serialization handles concurrency
- Synchronous GSI/LSI updates (no async propagation queue)
- `seq_counters` table replaces PostgreSQL sequences for stream ordering
- `rowid % total_segments` for parallel scan (vs `hashtext(pk) %`)
- OR-expansion `(pk > ? OR (pk = ? AND sk > ?))` for pagination
  (SQLite lacks tuple comparison)
- `char(1114111)` as string upper-bound in begins-with queries (not `chr()`)

Implemented traits: TableEngine, DataEngine, MetadataEngine,
StreamEngine, BackupEngine, WorkerStore, CatalogStore, and all
management/auth stores (AdminStore, AuthorizationStore, CredentialStore,
ManagementStore).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@LeeroyHannigan
Copy link
Copy Markdown
Collaborator

Thanks for putting this together, the design table is well thought out and the approach to SQLite's limitations (WAL serialization, OR-expansion for pagination, positional placeholders) shows you've done your homework.

That said, we're not in a position to take on new storage backends right now. We're still working through DynamoDB behavioral parity on the existing Postgres backend, and we don't yet have a clear story for how multiple backends should be organized, tested, and maintained long-term (shared conformance harness, CI matrix, feature parity guarantees between backends, etc.).

Once we've nailed that down, we'll have a better foundation for community-contributed backends like this. I'd suggest keeping your fork alive and we can revisit when the time is right.

@LeeroyHannigan LeeroyHannigan added the deferred Valid contribution, but blocked on prerequisite work or architectural decisions label May 22, 2026
@ivanbarlog
Copy link
Copy Markdown
Author

Goal was clear:

/goal implement extension for sqlite for extenddb

@jcshepherd jcshepherd self-assigned this May 22, 2026
@jcshepherd
Copy link
Copy Markdown
Collaborator

This is awesome and I'll find some time to look through it. It's especially valuable because it's an existence proof of the practicality of adding additional backends: thanks very much for that alone!

Like Lee said, we need to get our ducks in a little better order for properly qualifying and releasing backends, but I hope you'll bear with us while we do that so that this contribution can be part of the project.

One head's up: we are leaning in the direction of keeping the reference PostgreSQL backend implementation in the main extenddb repo, and vending additional backends as library crates from their own repos, partly to prevent the main project from acquiring a bunch of dependencies on different db drivers, and partly as a forcing function to ensure proper decoupling between the request handling and routing aspects of ExtendDB from the db-specific implementation details.

I will write a proper RFC to outline this and get consensus on it, but wanted you to be aware of how we're thinking about it.

Thanks!

@Iamrodos
Copy link
Copy Markdown

I'm really keen on SQLite making the cut here. I have been waiting for someone to start it.

The local dev and CI story is one of ExtendDB's strongest use cases, and for that I'd reach for an in-process backend over a running Postgres every time.

Whilst it makes sense having Postgres staying as the in-core reference, two things jump out at me:

  1. If SQLite lives in its own repo, that's a fork to keep alive and extra friction for what's actually a primary use case. Feels a bit odd to push a core use case out to the bring-your-own tier.

  2. So @jcshepherd I'd love the RFC to pin down a promotion path. What gets a backend into core, especially when it's serving a primary use case like this one.

Thanks for doing this in the open.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

deferred Valid contribution, but blocked on prerequisite work or architectural decisions

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants