turbopuffer v3 scores postings in batches and cuts full-text p90 by up to 80% against v2
turbopuffer says v3 cut hot and cold full-text p90 latency by up to 80% against v2 on 10-million-document namespaces. The figure is from the vendor's own nightly benchmark, and the company does not expect a gain for cold vector queries.
The Engineer · Build desk

Three figures: runtime for unfiltered order-by queries fell 95% on 9/19; p90 latency for hot and cold full-text search queries dropped by up to 80% on 9/19; test namespaces hold 10 million documents.
| Figure | Value | Note | Claim |
|---|---|---|---|
| Runtime reduction, unfiltered order-by queries | 95% | on 09/19, per Xavier Denis's entry | 12 |
| Full-text p90 latency drop, up to | 80% | hot and cold queries, on 9/19 | 1 |
| Docs per test namespace | 10 million docs | 3 |
What happened
- Each point on the benchmark chart is v3 p90 latency divided by v2 p90 latency for the same workload, measured nightly, so a value below 1 means v3 is faster.
- A c4a-highmem-32 client in us-central1-c sends 8 queries per second for 10 minutes at test namespaces in gcp-us-central1.
- The dev log says cold full-text queries also lose a serial object storage round trip, which saves hundreds of milliseconds.
- A second entry, credited to Xavier Denis, reports a 95% drop in runtime for unfiltered order-by queries.
Why it matters
- constraint The 80% is the best drop the engineers saw on 9/19. The nightly chart, not that sentence, shows what v3 delivers on an ordinary night.
- constraint Removing a serial round trip saves the object store's latency, so we'd expect the cold gain to vary with the storage path. The benchmark tests one region.
- decision A team running mostly cold vector search has no v3 latency case to weigh from this page. The evidence on offer favors text search and sorting.
The hot-path gain, according to the dev log entry credited to Matt Cuento, comes from no longer unpacking data. turbopuffer already batched its reads of postings. In the first implementation it then converted each batch into individual rows "for simplicity and correctness" [6]. v3 now keeps the batches through query execution and scores them directly [7].
Cold queries gain a second way. A BM25 query needs three things from object storage: postings for the query terms, attribute data for filtering, and corpus statistics such as document frequencies [8]. v3 loaded the statistics during planning and the rest at execution, one after the other [9]. It now fetches the statistics concurrently with the rest, just before scoring, so the work shares a single round trip [10]. "A large part of optimizing tpuf cold workloads comes from reducing serial round trips to object storage," Cuento wrote [11].
The order-by change is a different idea. Xavier Denis wrote that the slow part of an unfiltered order-by is usually top-k selection, since every row must be considered for inclusion [13]. v3 adds a dynamic filter that starts inactive, rules out rows that can never enter the result set, and updates after each row [14].
Take ORDER BY age ASC LIMIT 2 over [1, 10, 4, 8, 5, 15, 7]. After two rows the candidates are [1, 10], so any new row needs an age below 10 and the sixth row, 15, is skipped. After the third row the set is [1, 4] and every remaining row can be skipped [15]. Denis says the skipping is quite similar to how the MAXSCORE algorithm executes full-text queries [16].
The benchmark limits how far the ratios travel. On the chart, an 80% cut is a ratio of 0.2, a fivefold speedup [18]. Each run sends about 4,800 queries if the client holds 8 queries per second for the full 10 minutes [19]. Hot runs wait for a 100% cache hit ratio and cold runs disable the cache [4]. We'd expect a production cache that holds part of a namespace to land between the two. The text workloads use MS MARCO [5]. The page's own footnote says that "cold query latency is inherently noisy" [17].
What to watch
- Whether the nightly cold full-text ratio holds near 0.2 given the page's own warning about cold noise.
- Whether turbopuffer publishes hot and cold full-text ratios separately instead of one 'up to' figure.
- Whether anyone reproduces the ratios at query rates above 8 per second or on namespaces larger than 10 million documents.
Clarity's read
What the record supports and how the coverage leans. The claims behind it follow.
Reality
- Evidence50
- Adoption
- Insufficient
- Hype gap+12
- Incentives60
- Confidence55
Claim ledger
Ranked by verification strength, evidence, and original report placement.
- [1]
On 9/19, p90 latency for hot and cold full-text search queries on turbopuffer v3 dropped by up to 80%.
- [2]
Each point in the benchmark charts is v3 p90 latency divided by v2 p90 latency for the same workload, measured nightly; below 1, v3 is faster.
- [3]
Test namespaces live in gcp-us-central1 and hold 10 million documents. A c4a-highmem-32 in us-central1-c sends 8 queries per second for 10 minutes.
- [4]
Hot runs wait until the cache reaches a 100% hit ratio. Cold runs send queries with the cache disabled.
- [5]
Full-text and hybrid workloads use MS MARCO, with 1024-dimensional Cohere embed-english-v3 embeddings for the vector query.
- [6]
turbopuffer had previously batched reads of postings, then converted those batches into individual rows for simplicity and correctness in its initial implementation.
- [7]
The change retains the batches of postings through query execution and operates on and scores them directly.
- [8]
To score documents for a BM25 query, turbopuffer must load text postings for the query terms, any attribute data needed for filtering, and BM25 corpus statistics such as document frequencies from object storage.
- [9]
Previously v3 made these requests serially, loading corpus statistics during planning and postings and attributes for filtering at execution time.
- [10]
Loading corpus statistics was pushed down to be fetched concurrently with the remaining postings and attribute data just before scoring, combining them into a single round trip and shaving hundreds of milliseconds off cold full-text query latency.
- [11]
"A large part of optimizing tpuf cold workloads comes from reducing serial round trips to object storage."
- [12]
On 09/19, turbopuffer saw a 95% reduction in the runtime for unfiltered order-by queries.
- [13]
For unfiltered order-by queries, the bottleneck typically falls on top-k selection, since every row must be considered for inclusion.
- [14]
turbopuffer adds a dynamic filter to queries to exclude rows that could never enter the result set; the filter is initially inactive and is updated after each row.
- [15]
For SELECT * ORDER BY age asc LIMIT 2 over the table [1, 10, 4, 8, 5, 15, 7], after the first two rows the candidate set is [1, 10], so a new candidate must have age < 10 and the 6th row (age = 15) is skipped; after the third row the set is [1, 4] and all other rows can be skipped.
- [16]
The dynamic-filter skipping mechanism is quite similar to how turbopuffer's MAXSCORE algorithm executes full-text queries, but applied to order-by queries.
- [17]
"cold query latency is inherently noisy; we do not expect v3 to significantly reduce latency for cold vector queries"
- [18]
An 80% reduction in p90 corresponds to a v3/v2 ratio of 0.2 on the chart, a fivefold speedup.
- [19]
Each benchmark run sends about 4,800 queries if the client holds its rate for the full duration.
Get this ledger inside ChatGPT. Ask about any of our stories and the answer brings its figure, each claim’s verdict and the sources. Free, no account.
Sources
1 independent publisher whose own reporting we read for this story.
- turbopuffer.com/v3
turbopuffer.com
1 article · October 14, 2026
Topics and entities
Follow any of these and your For You feed starts watching them — no settings page required.
Topics
- In-Database Full-Text SearchFollow
- Vector Databases and Search EnginesFollow
- Object-storage query enginesFollow
- Database performance benchmarksFollow