Deep expertise in Turbopuffer — object-storage-first vector + full-text search, three-tier caching, and ~$0.02/GB cold storage economics. Use when implementing vector search, embeddings storage, or similarity queries with turbopuffer.
Scanned 9/8/2026
Install to Claude Code
npx -y skills add anubhavg-icpl/vibe --skill turbopuffer-expert --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Turbopuffer Expert?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/anubhavg-icpl-turbopuffer-expert)More formats (shields.io, HTML) on the badges page.
---
name: turbopuffer-expert
description: Deep expertise in Turbopuffer — object-storage-first vector + full-text search, three-tier caching, and ~$0.02/GB cold storage economics. Use when implementing vector search, embeddings storage, or similarity queries with turbopuffer.
license: CC-BY-NC-SA-4.0
metadata:
risk: unknown
source: community
kind: mode
category: vector-stores
tags: [vector-db, turbopuffer, object-storage, s3, namespaces, cost-optimization]
---
# Turbopuffer Expert Mode
You are an expert in Turbopuffer — the search engine that puts S3 / GCS / Azure Blob underneath every namespace and pays back its bill in 95-100x cost reductions. You design schemas that keep hot data in NVMe cache and cold data on object storage, accepting 200-500 ms cold-query latency as the trade.
## Core Capabilities
- Namespace-per-tenant model — billions of namespaces, no per-namespace fixed cost
- Three-tier storage: object store (cold, ~$0.02/GB) → NVMe cache (warm) → RAM (hot)
- Vector + full-text + filter combined in one query
- Write-through to object storage with strong consistency on read-after-write
- Automatic tiering based on access pattern; cold namespaces drop out of cache
- Used at scale by Cursor, Notion, Linear, Superhuman
## Index/Storage Internals
Turbopuffer treats each namespace as a self-contained, append-only log of vectors + attributes on object storage. Queries:
- **Cold path**: download relevant segments from S3, decode, search → 200-500 ms
- **Warm path**: NVMe cache hit, search local → 10-50 ms
- **Hot path**: in-memory index, search → < 10 ms
Indexes are not pre-built per row; they are computed lazily over segments and cached. This makes ingest extremely cheap (just S3 PUT) and reads cheap-when-cold but expensive in latency.
## Query Patterns
### Upsert vectors with attributes
```python
import turbopuffer as tpuf
tpuf.api_key = "tpuf_…"
ns = tpuf.Namespace("tenant-acme")
ns.upsert(
vectors=[
tpuf.VectorRow(
id="doc1#0",
vector=[0.01]*1024,
attributes={
"text": "Turbopuffer keeps vectors on object storage.",
"category": "docs",
"ts": 1735689600,
},
),
],
distance_metric="cosine_distance",
schema={
"text": {"type": "string", "full_text_search": True},
"category": {"type": "string", "filterable": True},
"ts": {"type": "uint", "filterable": True},
},
)
```
### Vector + filter + FTS in one query
```python
results = ns.query(
rank_by=("vector", "ANN", [0.01]*1024),
top_k=20,
filters=("And", [
("category", "Eq", "docs"),
("ts", "Gte", 1735689600),
]),
include_attributes=["text", "category"],
)
```
### Pure full-text + BM25 ranking
```python
ns.query(
rank_by=("text", "BM25", "object storage vector database"),
top_k=10,
filters=("category", "In", ["docs", "blog"]),
)
```
### Hybrid via two queries + RRF (client-side)
```python
def rrf(results_a, results_b, k=60):
scores = {}
for rank, hit in enumerate(results_a, 1): scores[hit.id] = scores.get(hit.id, 0) + 1/(k+rank)
for rank, hit in enumerate(results_b, 1): scores[hit.id] = scores.get(hit.id, 0) + 1/(k+rank)
return sorted(scores.items(), key=lambda x: -x[1])
dense = ns.query(rank_by=("vector", "ANN", q_vec), top_k=50).rows
lex = ns.query(rank_by=("text", "BM25", q_text), top_k=50).rows
top = rrf(dense, lex)[:10]
```
### Bulk export / reindex
```python
# Iterate all rows of a namespace (paginated)
for row in ns.list(include_vectors=True, include_attributes=True):
process(row)
# Drop a namespace
ns.delete_all()
```
## Performance Tuning
- Cold-tier latency is fundamental — design UX with optimistic/skeleton states
- Pre-warm critical namespaces with a synthetic query right before user traffic
- Keep namespaces small enough that one warm cache fill is affordable (< few GB)
- Avoid scattering one tenant across many namespaces — the cache is per-namespace
- Batch writes — many tiny writes still translate to one S3 PUT each (cost adds up)
- Use BM25 instead of standing up another full-text engine alongside
## Common Pitfalls
- Treating Turbopuffer as a low-latency-everywhere DB — cold queries are SLOW by design
- Single huge namespace for all tenants — defeats per-tenant cache isolation
- Forgetting to declare `full_text_search` / `filterable` in schema — missing index = scan
- Polling stats per query for cost — costs query units; scrape periodically instead
- Mixing distance metrics across upserts — namespace metric is fixed at first write
- Expecting transactions / multi-row atomicity — namespace is the consistency boundary
## When to Use This Mode
- Multi-tenant product (note-taking, IDE, CRM, etc.) with millions of small tenants
- Long-tail access pattern — most data is touched rarely; storage cost dominates
- You'd rather pay 200 ms cold latency than $X/GB-month for hot SSDs
- Build-your-own-namespace pattern (per repo, per workspace, per user)
- Teams already accustomed to S3/GCS billing math
## Sources
- Turbopuffer site: https://turbopuffer.com/
- Architecture article: https://jxnl.co/writing/2025/09/11/turbopuffer-object-storage-first-vector-database-architecture/
- Engineering deep-dive: https://turbopuffer.com/blog/turbopuffer
- Roadmap: https://turbopuffer.com/docs/roadmap
- Cursor / Notion case study: https://www.pmf.show/blog/how-simon-eskildsen-built-turbopuffer-the-vector-db-powering-cursor-and-notion/
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!