turbopuffer
turbopuffer
Overview
turbopuffer is a search engine (vector, full-text, hybrid, filters) built natively on object storage. Object storage is the only source of truth; NVMe SSD and memory are caches in front of it. That architecture makes it very cheap at rest, fast when warm (vector p50 ~14ms on 10M docs), and slower when cold (p50 ~500-900ms) or writing (p50 ~165ms for a 512KB batch, since every write is an object-storage PUT).
Reach for it when you have: RAG/semantic search, hybrid search (BM25 + vectors), naturally partitioned data (per-tenant namespaces), or large scale at low cost. It is deliberately not a fit for: a free tier (commercial only), heavy first-stage ranking logic (it does first-stage retrieval; rerank in your own code), or built-in embedding as a primary workflow (bring your own vectors; native embedding exists but is in private beta).
There is no local emulator and no open-source version. Tests and development hit the real service (see Testing below).
Mental model
- A namespace is an isolated container of documents with its own indexes — a prefix on object storage. Namespaces are created implicitly on first write, scale to hundreds of millions per org, and are near-free when idle. Design rule: one namespace per set of documents queried together (e.g. per tenant), not one big namespace with filters. Smaller namespaces are faster and cheaper.
- A document has an
id(u64, UUID, or string ≤64 bytes), optional vectors, and attributes. Attribute types are consistent per namespace and tracked in a per-namespace schema (auto-inferred by default; declare explicitly foruuid,datetime, vectors beyondvector, FTS, and to disable indexing). - Writes append to a write-ahead log on object storage: durable when the call returns, immediately visible to strongly consistent queries. Concurrent writes to a namespace group-commit; each namespace commits at most ~1 WAL entry/second, so batch instead of looping single writes. Indexing happens asynchronously on separate nodes; unindexed data is searched exhaustively in the meantime.
- Queries default to strong consistency, which costs a ~10ms floor (an object-storage metadata check). Eventual consistency skips that and scans at most 128 MiB of unindexed data; it can be stale up to ~1h after very large writes.
- Vector indexing uses SPFresh (centroid-based ANN, tuned for 90-100% recall@10, measured continuously on 1% of live traffic). Full-text search is a native BM25 inverted index. Filters use inverted indexes that cooperate with the ANN index, so filtered vector search keeps recall.
- First query to a cold namespace reads object storage directly (3-4 roundtrips); subsequent queries hit NVMe/memory cache on the same node. You can pre-warm (see below).