Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
turbolite — SQLite VFS with sub-100ms cold JOIN queries from S3 + page-level compression and encryption | Kitploit
Tools/GitHubGitHub/russellromney/turbolite
Encryption/Decryption ToolsCryptographyCloud SecurityUtilities & FrameworksDatabase Security
GitHubrussellromney/turbolite

turbolite

SQLite VFS with sub-100ms cold JOIN queries from S3 + page-level compression and encryption

View Repository
48012113 months agoReviewed by Kitploit

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

turbolite

turbolite is a SQLite VFS in Rust that serves point lookups and joins directly from S3 with sub-250ms cold latency.

This repo is a Cargo workspace with two crates:

  • turbolite — Pure Rust library. SQLite VFS with page-level compression, encryption, and S3 tiering.
  • turbolite-ffi — C FFI / loadable extension + language bindings (Python, Node.js, Go).

It also offers page-level compression (zstd) and encryption (AES-256) for efficiency and security at rest, which can be used separately from S3.

Experimental. turbolite is under active development and contains bugs. Be careful.

Object storage is getting fast. S3 Express One Zone delivers single-digit millisecond GETs and Tigris is also extremely fast. The gap between local disk and cloud storage is shrinking, and turbolite exploits that.

The design and name are inspired by turbopuffer's approach of ruthlessly architecting around cloud storage constraints. The project's initial goal was to beat Neon's 500ms+ cold starts. Goal achieved.

If you have one database per server, use a volume. turbolite explores how to have hundreds or thousands of databases (one per tenant, one per workspace, one per device), don't want a volume for each one, and you're okay with a single write source.

turbolite ships as a Rust library, a SQLite loadable extension (.so/.dylib), and language packages for Python and Node.js, plus Github deps for Go. Any S3-compatible storage works (AWS S3, Tigris, R2, MinIO, etc.). It's a standard SQLite VFS operating at the page level, so most SQLite features should work: FTS, R-tree, JSON, WAL mode, etc.

turbolite is part of the broader hadb ecosystem. Standalone turbolite is a storage VFS with one safe writer; if you want HA leader election plus continuous WAL replication, use it through haqlite-turbolite, which layers HaQLite and walrust on top. That HA path is very experimental still.

If you want to contribute to turbolite or find bugs, please create a pull request or open an issue.

Performance

QueryTypeCold (S3 Express)Cold (Tigris)
Post + userpoint lookup + join86ms172ms
Profilemulti-table join (5 JOINs)251ms479ms
Who-likedindex search + join206ms302ms
Mutual friendsmulti-search join19ms49ms
Indexed filtercovered index scan79ms88ms
Full scan + filterfull table scan476ms532ms

1M posts / 100K users (~1.5GB stored) with nothing cached, every byte from S3. EC2 c5.2xlarge + S3 Express One Zone (same AZ, ~4ms GET latency). Fly performance-8x + Tigris (~25ms GET latency). Both: 8 dedicated vCPU, 16GB RAM, 7 prefetch worker threads. See Benchmarking and Storage backend matters.

Benchmarks are organized by cache level (what's already on local disk when the query runs):

Cache levelWhat's cachedWhat's fetched from S3When this happens
nonenothingeverythingFresh start, empty cache
interiorinterior B-tree pagesindex + data pagesFirst query after connection open
indexinterior + index pagesdata pages onlyNormal turbolite operation
dataeverythingnothingEquivalent to local SQLite

interior is the most realistic cold benchmark: interior pages load eagerly on connection open, so by the time you run your first query, they're cached. Index pages aggressively prefetch on first access in the background and may not be ready yet.

Warm cache (VFS overhead vs plain SQLite)

100K rows, Fly.io performance-2x (dedicated vCPU, NVMe, IAD):

OperationSQLiteturboliteOverhead
Point lookup145K/s73K/s2.0x
Range scan8.8K/s8.3K/sparity
Full table scan56/s60/sparity
INSERT19K/s23K/sparity
UPDATE by PK40K/s27K/s1.5x
Batch INSERT (in txn)685K/s740K/sparity

Point lookups have the highest per-page overhead (~2x). Everything else approaches or beats parity. Lock-free cache architecture means concurrent reads never block writes.

Checkpoint cost

AfterLocalS3 (same-region RustFS)
1K inserts19ms38ms
10K batch17ms114ms
1K updates9ms36ms

Writes are always local-speed. The S3 cost is at checkpoint only. Numbers with RustFS in same Fly region (~2ms RTT). S3 Express One Zone would be comparable.

Quick Start

Python

pip install turbolite
import turbolite

conn = turbolite.connect("my.db", mode="s3",
    bucket="my-bucket",
    endpoint="https://t3.storage.dev")

conn.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)")
conn.execute("INSERT INTO users VALUES (1, 'alice', '[email protected]')")
conn.commit()

alice = conn.cursor().execute("SELECT * FROM users").fetchone()
print(alice[1])
>>> "alice"

See Installation for Node, Go, Rust, local-only mode, and using the .so loadable extension directly

Design

turbolite is designed for S3's constraints over filesystem constraints. Every decision flows from this model:

S3 ConstraintImplication
Round trips are slowMinimize request count. Batch writes, prefetch reads aggressively.
Bandwidth is a bottleneckMaximize bandwidth utilization.
PUTs and GETs charge per-operationA 64KB GET costs the same as a 16MB GET. Optimize request count, not byte efficiency.
Objects are immutableNever update in place. Write new versions, swap a pointer. No partial-write corruption.
Storage is cheapDon't optimize for space. Over-provision, keep old versions, let GC clean up later.

Architecture

turbolite adds introspection and indirection layers between SQLite and S3 that efficiently groups, compresses, tracks, and fetches pages.

SQLite uses a B-tree index and requests for one page at a time. It knows page N is at byte offset N * page_size. And those pages are distributed randomly throughout the pagemap for efficient random access. But on S3, fetching one page per request would mean thousands of potentially random GETs per query.

But pages are not created equally. SQLite has different types of pages. turbolite separates page groups by type: interior B-tree, index leaf, and data leaf pages.

Interior pages are touched on every query to route lookups to leaf pages. turbolite detects them, stores them in compressed bundles in S3, and loads them eagerly on VFS open. After that, every B-tree traversal is a cache hit.

Index leaf pages get the same treatment: separate bundles, lazy background prefetch, pinned against eviction. Cold queries only need to fetch data pages.

turbolite takes advantage of B-tree introspection to understand which tree (a table or index) a page is part of, and intelligently stores those pages together in S3 as page groups: many pages chunked into a single S3 object. Big enough to saturate bandwidth on prefetch, small enough for point queries. Default: 256 pages per group, ~16MB at 64KB pages.

Storing the same table/index together means that we make the fewest possible GETs for cold queries.

Download Tool