Skip to content
Agentmart
Submit a tool

turbopuffer

Guide for building search on turbopuffer, the object-storage-native vector and full-text search engine.

Skill by maragudk

IndexedMIT★ 30
Write a review

Chalk Labs

Need help deploying turbopuffer?

Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.

Book a call

Install

Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.

npx agentmarket install skill/maragudk-turbopuffer

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Guide for building search on turbopuffer, the object-storage-native vector and full-text search engine. Use this skill whenever the user is writing or modifying code that talks to turbopuffer -- anything importing `github.com/turbopuffer/turbopuffer-go`, calling `*.turbopuffer.com` endpoints, or mentioning tpuf or turbopuffer namespaces -- and when designing features it could serve, such as semantic/vector search, BM25 full-text search, hybrid search with RRF, or RAG retrieval with filters. Also use it when deciding whether turbopuffer fits a use case, designing namespaces or schemas for it, or debugging its consistency, caching, backpressure, or HTTP 429 behavior.

Use cases: ml, writing

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 26, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/turbopuffer

What's inside

Skill name
turbopuffer
Description
Guide for building search on turbopuffer, the object-storage-native vector and full-text search engine. Use this skill whenever the user is writing or modifying code that talks to turbopuffer -- anything importing `github.com/turbopuffer/turbopuffer-go`, calling `*.turbopuffer.com` endpoints, or mentioning tpuf or turbopuffer namespaces -- and when designing features it could serve, such as semantic/vector search, BM25 full-text search, hybrid search with RRF, or RAG retrieval with filters. Also use it when deciding whether turbopuffer fits a use case, designing namespaces or schemas for it, or debugging its consistency, caching, backpressure, or HTTP 429 behavior.
License
MIT
Instructions
283 lines in SKILL.md · view on GitHub

Files (1)

  • SKILL.md

SKILL.md (first lines)

# 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) or heavy first-stage ranking logic (it does first-stage retrieval; rerank in your own code). Bring your own vectors, or let it embed text for you (see Native embeddings).

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 for `uuid`, `datetime`, vectors beyond `vector`, 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).

## Client setup (Go)

```go
// go get github.com/turbopuffer/turbopuffer-go/v2
import (
	"github.com/turbopuffer/turbopuffer-go/v2"
	"github.com/turbopuffer/turbopuffer-go/v2/option"
)

tpuf := turbopuffer.NewClient(
	option.WithAPIKey(os.Getenv("TURBOPUFFER_API_KEY")), // default; can be omitted
	option.WithRegion("gcp-europe-west1"),               // or TURBOPUFFER_REGION env var
)
ns := tpuf.Namespace("my-namespace")
```

Reuse one client for connection pooling. Region is part of the base URL (`https://<region>.turbopuffer.com`); pick the one closest to your backend. Regions span AWS (e.g. `aws-eu-central-1`, `aws-us-east-1`) and GCP (e.g. `gcp-europe-west1`, `gcp-us-central1`); full list at https://turbopuffer.com/docs/regions.

The client retries connection errors, 408, 409, 429, and 5xx with exponential backoff (4 retries by default; tune with `option.WithMaxRetries`). Errors unwrap to `*turbopuffer.Error` via `errors.As`. Optional scalar params use helpers: `turbopuffer.Bool(true)`, `turbopuffer.Int(10)`, `turbopuffer.String("x")` — prefer these over `param.NewOpt`, which needs an extra import the docs snippets forget.

Namespace names must match `[A-Za-z0-9-_.]{1,128}`. Attribute names can't start with `$`.

## Writing documents

One endpoint does everything: upserts, patches, deletes, and namespace copies, atomically per request.

```go
res, err := ns.Write(ctx, turbopuffer.NamespaceWriteParams{
	UpsertRows: []turbopuffer.RowParam{
		{"id": 1, "vector": embedding, "text": "walrus narwhal", "public": true},
		{"id": 2, "vector": embedding2, "text": "pufferfish clownfish", "public": false},
	},
	DistanceMetric: turbopuffer.DistanceMetricCosineDistance,
	Schema: map[string]turbopuffer.AttributeSchemaParam{
		"text":     {AttributeSchemaConfig: &turbopuffer.AttributeSchemaConfigParam{Type: "string", FullTextSearch: &turbopuffer.FullTextSearchConfigParam{}}},
		"user_ids": turbopuffer.AttributeSchemaParamAttributeSchemaConfig("[]uuid"), // type only
	},
})
// res.RowsAffected, res.RowsUpserted, ...
```

Write params (all optional, combined freely):

- `UpsertRows` / `UpsertColumns` — insert or **fully overwrite** documents (row vs columnar format).
- `PatchRows` / `PatchColumns` — partial update of listed attributes only. Patches to missing IDs are silently ignored. **Vector attributes cannot be patched.**
- `Deletes` — delete by ID (`[]any{1, 3}`).
- `DeleteByFilter` / `PatchByFilter` — filter-driven bulk ops (max 5M / 50k rows per request; `rows_remaining` in the response tells you to reissue). Read Committed semantics.
- `UpsertCondition` / `PatchCondition` / `DeleteCondition` — conditional writes (below).
- `DistanceMetric` — `cosine_distance` or `euclidean_squared`. Required on writes to a namespace with vectors.
- `Schema`, `Sharding`, `Encryption`, `CopyFromNamespace`, `BranchFromNamespace`, `DisableBackpressure`.

Batch aggressively: up to 512 MB per request, batching earns up to a 50% write discount, and per-namespace throughput is ~10k writes/s only when batched. Duplicate IDs in one request are an error (HTTP 400).

### Schema and types

Types: `string`, `int`, `uint`, `float`, `bool`, `uuid`, `datetime` (ISO 8601 strings), array forms (`[]string`, `[]uuid`, ...), vectors `[N]f32` / `[N]f16` / `[N]i8`, multi-vector `[][N]f32` (late interaction), sparse `{}f16`. Only `string`/`int`/`bool` (and arrays of them) are inferred — declare the rest explicitly, or they land as the wrong type permanently. An attribute literally named `vector` is inferred as a vector.

Per-attribute schema options: `Ann` (required `true` for extra vector columns), `Filterable` (default true; **set false on large attributes you never filter — 50% storage discount and faster indexing**), `FullTextSearch` (bool or config object), `Regex`, `Glob`, `Fuzzy` (each enables the matching filter operators; each defaults `filterable` to false when enabled), `SparseKnn`, `Embed`.

`Schema` is a `map[string]turbopuffer.AttributeSchemaParam`; wrap options in `{AttributeSchemaConfig: &turbopuffer.AttributeSchemaConfigParam{...}}` or use `turbopuffer.AttributeSchemaParamAttributeSchemaConfig("uuid")` for a bare type.

Schema changes in place: `filterable`, `full_text_search`, `regex`, `glob`, `fuzzy`, adding/removing `embed` — via a document-free write with only `Schema` set, or `ns.UpdateSchema`. Type changes and attribute deletion require export + re-upsert into a new namespace. A namespace has max 8 vector columns (embedded attributes count), **fixed at creation**; all documents must include all vector attributes.

### Conditional writes

Conditions are filters evaluated atomically against the current document (Serializable semantics); `NewExprRefNew` references the incoming value. Documents that don't exist are written unconditionally.

```go
res, err := ns.Write(ctx, turbopuffer.NamespaceWriteParams{
	UpsertRows: []turbopuffer.RowParam{{"id": 1, "vector": v, "updated_at": "2026-07-31T12:00:00Z"}},
	UpsertCondition: turbopuffer.NewFilterOr([]turbopuffer.Filter{
		turbopuffer.NewFilterLt("updated_at", turbopuffer.NewExprRefNew("updated_at")),
		turbopuffer.NewFilterEq("updated_at", nil),
	}),
	DistanceMetric: turbopuffer.DistanceMetricCosineDistance,
})
```

Conditional and filter-based writes are billed as a write plus one or two queries.

## Querying

```go
res, err := ns.Query(ctx, turbopuffer.NamespaceQueryParams{
	RankBy:            turbopuffer.NewRankByAnn("vector", queryEmbedding),
	Limit:             turbopuffer.LimitParam{Total: 10},
	Filters:           turbopuffer.NewFilterEq("public", true),
	IncludeAttributes: turbopuffer.IncludeAttributesParam{StringArray: []string{"text"}},
})
for _, row := range res.Rows {
	// Row is a map[string]any: row["id"], row["$dist"] (the rank score),
	// and the requested attributes like row["text"]
}
```

### rank_by variants

- `NewRankByAnn("vector", []float32{...})` — approximate nearest neighbor.
- `NewRankByKnn(...)` — exact search; requires filters, costs 2 concurrency slots.
- `NewRankByTextBM25("text", "query")` — full-text relevance.

From maragudk/fabrik, MIT.

More from maragudk/fabrik

Signals

Stars
30
Forks
2
Open issues
0
Last commit (this folder)
Jul 31, 2026 (3 months ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from maragudk

Done for you

Rather not set it up yourself?

Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.

See how we build AI agents →Read the case studies

Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.

launches shipped
50+
launches shipped
media placements
500+
media placements
founders on every account
2
founders on every account

Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block

Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.

Get turbopuffer running in your business

Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.

Goes to the Chalk Labs founders, not the newsletter. Privacy

Need help deploying turbopuffer?

CallGet help
Cite this page

turbopuffer skill. Agent Mart. https://agentmart.dev/skills/maragudk-turbopuffer (last updated 2026-10-24)