- Một tối ưu nhỏ đúng chỗ: cache kết quả stemmer cho các term lặp lại giúp pipeline tokenization của turbopuffer tăng ~2x throughput khi stemming bật.
- Chi tiết vì sao nó rẻ mà hiệu quả đến vậy.
TL;DR
turbopuffer vừa ship một stem cache nhỏ trong pipeline tokenization của full-text search. Các term lặp lại sẽ bỏ qua bước stemmer và lấy kết quả từ cache, cho ~2x throughput khi stemming được bật. Không đổi giá, không đổi API — chỉ là một micro-optimization đúng chỗ trên engine FTS v2.
Có gì mới
Stemming là bước biến một từ về gốc từ để search “run” match được document chứa “running” hoặc “runs”. Mỗi lần một term đi qua pipeline, stemmer phải chạy rule-based state machine (thuật toán Snowball/Porter) để ra stem. Với corpus lớn, bước này chiếm phần đáng kể CPU trong giai đoạn tokenization.
Thay đổi mới rất thẳng: thêm một cache nhỏ ở ngay trước stemmer. Khi token được thấy lần đầu, gọi stemmer và lưu kết quả. Lần thứ hai trở đi cho cùng token đó, trả ngay từ cache. Kết quả: ~2x tokenization throughput khi stemming bật.
Vì sao nó quan trọng
Ngôn ngữ tự nhiên có phân phối Zipfian — một lượng nhỏ từ vựng chiếm phần lớn số token. Cả một bài blog dài có thể có hàng nghìn token nhưng chỉ vài trăm từ riêng biệt. Điều đó có nghĩa: ngay cả một cache rất nhỏ cũng có hit-rate cực cao, và stemmer chỉ phải làm việc với số lượng entry bằng unique vocabulary chứ không phải tổng số token.
Stemming lại là pure function: cùng input luôn cho cùng output, không side effect. Nên cache đúng nghĩa trivially safe — không cần invalidation, không cần lo consistency, không cần lock phức tạp.
Chi tiết kỹ thuật
- Scope: chỉ ảnh hưởng stage tokenization khi column bật
stemming: true. Column không stemming không thay đổi gì. - Ngôn ngữ hỗ trợ stemmer: 17 ngôn ngữ theo họ Snowball — Arabic, Danish, Dutch, English (default), Finnish, French, German, Greek, Hungarian, Italian, Norwegian, Portuguese, Romanian, Russian, Spanish, Swedish, Tamil, Turkish.
- Tokenizer mặc định:
word_v3, dùng Unicode v17.0 text segmentation — chạy trước stemmer để tách token. - Hiệu ứng: ~2x throughput cho bước tokenization khi stemming bật. End-to-end write/query latency cải thiện tỉ lệ theo tỉ trọng CPU mà stemming chiếm trong pipeline.
- An toàn: stemmer là deterministic pure-function → cache không cần invalidation logic.
So sánh với các engine khác
| Engine | Cách xử lý stem | Có cache chung? |
|---|---|---|
| Lucene / Elasticsearch | Token filter streaming theo document | Không ở tầng tokenizer |
| Tantivy | Inline per-token | Không |
| PyStemmer (Snowball port) | Có maxCacheSize default 10,000 per-instance | Có, nhưng scope hẹp |
| turbopuffer (sau update) | Cache ở biên tokenizer, chia sẻ trong batch | Có |
Điểm khác biệt: vì turbopuffer xử lý write theo batch lớn và tokenization thuần tuý là CPU-bound, một cache ở đúng ranh giới stemmer amortize được chi phí warm-up qua hàng nghìn document.
Ai hưởng lợi nhất
- Bulk re-ingest / reindex: khi rebuild index cho corpus lớn, tokenization chiếm phần lớn CPU — đây là lúc 2x rõ rệt nhất.
- Log / chat / document search: các column text dài, từ vựng lặp lại nhiều (tên người, keyword domain).
- Khách hàng lớn đang chạy FTS: Cursor, Notion, Linear, Anthropic, Atlassian, Ramp, Grammarly, Superhuman — theo trang chủ turbopuffer.
Giới hạn & pricing
2x chỉ áp dụng cho stage tokenization, không phải toàn bộ pipeline write. Write path vẫn phải merge posting list và flush lên object storage — các bước đó không đổi. Với column không bật stemming, thay đổi này không có tác dụng. Không có thay đổi pricing; optimization nằm trong engine FTS v2 hiện có.
Bối cảnh & tiếp theo
turbopuffer là search engine serverless chạy trên object storage, hỗ trợ cả vector search và BM25 full-text search. Sub-10ms p50 latency, 10x cost advantage so với vector DB truyền thống, chạy ở quy mô 3.5T document, 10M+ writes/sec, 25K+ QPS.
Đợt FTS v2 rollout cuối 2025 đầu 2026 đã mang về up-to-20x faster full-text search. Stem cache là ví dụ tốt cho pattern sau đó: các optimization nhỏ, đo được, ship liên tục — chứ không đợi big-bang release.
Bài học cho hệ thống của bạn: mỗi lần bạn thấy một hàm deterministic chạy trên input có distribution lệch (Zipfian, power-law), một cache cực nhỏ thường đủ đổi lấy 2x throughput gần như miễn phí.
Nguồn: @turbopuffer, turbopuffer FTS docs, roadmap & changelog.