Skip to content

PlanetScale's TIN Makes Postgres Full-Text Search 25x Faster

Karify98 & Amy ๐ŸŒธยท
Cover Image for PlanetScale's TIN Makes Postgres Full-Text Search 25x Faster

A benchmark published on September 16th shows a performance gap in Postgres full-text search that's hard to believe: 25x throughput, 26x lower latency. Not marketing copy โ€” there's a table, an 85GB corpus, and a named competitor.

What happened

PlanetScale, the managed Postgres/MySQL cloud provider, just shipped TIN (Text INdex), a full-text search extension for Postgres. It's already GA across every PlanetScale and Neki database. The syntax reads like any other index:

CREATE INDEX an_index_name ON table_name USING tin(text_column_name);
SELECT * FROM table_name
  WHERE text_column_name ==> 'some words';

Postgres already ships a built-in GIN index for full-text search, and the ecosystem already has extensions like ParadeDB and pg_textsearch. PlanetScale claims TIN beats all three โ€” and backs it up with numbers instead of adjectives.

The benchmark: not a marginal gap

PlanetScale tested on an AWS i7i.8xlarge instance, capped at 8 vCPUs and 32GB RAM per container, using an 85GB corpus of 150 million Stack Exchange questions and answers. They compared TIN v1.0.2 against ParadeDB v0.25.2, pg_textsearch v1.4.0, and the built-in Postgres GIN index (Postgres 18.6).

Index build times alone show a clear split:

Engine Build time Index size RAM required
TIN 8m10s 50.7 GB 32 GB
ParadeDB 19m20s 52.1 GB 64 GB
pg_textsearch 26m49s 41.5 GB 128 GB
Postgres GIN 2h09m04s 28.0 GB 64 GB

Query performance โ€” the part that actually matters in production โ€” widens the gap further. On a mixed workload of conjunction, disjunction, and phrase queries returning the top 10 results by BM25 score, TIN hit 199 QPS with 256ms p99 latency. ParadeDB managed 7.9 QPS with a 6,765ms p99. That's 25x more queries per second, and even the slowest queries are 26x faster. Postgres GIN couldn't finish this benchmark at all โ€” it ran out of memory on the disjunction searches.

On conjunction and phrase queries alone, TIN is 10x faster than ParadeDB and 541x faster than GIN. Even with a concurrent client hammering 1,000 UPDATE queries per second, TIN completed 270,279 updates in a 10-minute run, versus 185,584 for ParadeDB and just 735 for pg_textsearch โ€” pg_textsearch's constant read traffic starved writes of the locks they needed.

Why it's fast โ€” skipping a translation step nobody talks about

This is the more interesting part. Most text indexes, including ParadeDB and pg_textsearch, assign sequential document IDs within each segment to keep postings lists compressible. But Postgres internally doesn't use sequential IDs โ€” it uses ctid, a 48-bit number that points directly to a row's physical location on disk.

The result: whenever a search matches 10 million rows, ParadeDB and pg_textsearch have to translate those 10 million sequential IDs back into real ctids through a separate mapping structure. TIN skips that entirely โ€” it uses ctid as the document identifier from the start. No mapping, no lookup, no middle layer.

The tradeoff is a harder compression problem. ctids are discontiguous 48-bit numbers, not sequential, so classic tricks like delta-encoding don't apply. PlanetScale's answer is a two-level bitmap that exploits a Postgres quirk: no page can hold more than 291 tuples, so a page-level bitmap stays dense enough to compress well. For high-frequency terms, they get down to roughly 1 bit per posting.

So what does this mean for developers?

If your team has been building search โ€” e-commerce, log search, internal docs โ€” on top of Postgres and quietly considering "let's just bolt on Elasticsearch or Meilisearch," these numbers are worth a second look. A 10-25x QPS gap is big enough to change the calculus on whether you need a separate search system at all. Staying inside Postgres means one less service to operate, one less sync pipeline, one less failure point.

Two caveats worth keeping in mind, though. First, this is a benchmark PlanetScale published about its own product, not an independent third party โ€” even though they shared the corpus, the exact queries, and a forked benchmarker, you should still reproduce it against your own workload before switching anything. Second, TIN is currently GA on PlanetScale's own infrastructure; it's unclear at the time of writing whether a standalone version exists for self-hosted Postgres, so teams not already on PlanetScale should verify availability before expecting to use it right away.

For anyone already running on PlanetScale, this is a solid reason to try CREATE INDEX ... USING tin(...) on a real table and measure it against your own workload instead of trusting the marketing numbers.

What to know

  • TIN (Text INdex) is PlanetScale's new full-text search extension, GA for every PlanetScale/Neki database, shipped September 16, 2026
  • Benchmarked on an 85GB Stack Exchange corpus: 10-25x faster QPS than ParadeDB, up to 541x faster than built-in Postgres GIN on some query types
  • The trick: using Postgres' native ctid as the document ID directly, skipping the sequential-ID mapping layer other engines need
  • Keeps solid throughput even with 1,000 concurrent UPDATE/sec โ€” traditionally a weak spot for text indexes
  • The benchmark is self-published by PlanetScale; availability outside PlanetScale's own infrastructure is unclear at the time of writing

Content assisted by AI (Amy ๐ŸŒธ). Reviewed by the author.

Related Posts