Skip to content
grepvine.aiJoin preview

Tradeoffs

Every design picks what to be bad at. This page says what Grepvine chose.

Regex mode uses RE2 syntax, which has no backreferences and no lookaround. In exchange, matching always takes linear time, so no pattern can make a query run away. PCRE syntax isn’t supported.

Grepvine narrows a query to candidate documents using the literal text in its pattern. A pattern with no literal run of at least three bytes, such as \d+, [A-Z]{2,} or ab, can’t be narrowed, so it checks every searchable document. It still returns every match, page by page, but it takes longer on a large index.

To speed such a query up, add a literal (ERROR \d+ rather than \d+), or a metadata filter. A filter narrows the candidates before Grepvine checks any text.

A query is fastest when its index is in a server’s NVMe cache. The first query after an index has left the cache reads from object storage instead, and takes 15 to 35 times longer. These are measurements of selective queries over the full Wikipedia corpus (19.57 GB):

Index One query at a time, p50 / p95 20 at a time, p50 / p95
Cached on NVMe 5 / 25 ms 22 / 51 ms
In object storage only 171 / 543 ms 480 / 812 ms

A query that misses the cache fetches only what it needs, and the server then caches more of the index in the background, so the queries that follow run warm. An index nobody queries for a while leaves the cache as other indexes take its place. That is the price of an idle index taking up no machines.

Grepvine acknowledges a write only after it is in object storage, so each write takes longer than a write to memory. Grepvine groups concurrent writes, whole batches included, into shared writes to object storage, so throughput comes from sending many documents at once. Send documents in batches: put_many, putMany and gv upload do this for you. Grepvine targets 50 MiB/s of ingestion with acknowledgment p99 below one second.

Sustained heavy writing can outpace background optimization. When it does, Grepvine first slows writes down. If the backlog keeps growing, it answers 429 with Retry-After. The SDKs and gv wait and retry on their own. Queries stay correct throughout.

Limit Value
Document 1 GiB. Searchable when valid UTF-8 and at most 100 MiB.
Single upload Must finish within the 35-second request deadline.
Batch 2,048 documents and 16 MiB of text.
Key 1,024 bytes.
Metadata 64 fields and 64 KiB encoded per document.
Pattern 8 KiB.
Filter 8 KiB.
Context lines 20 before and 20 after each result.
Result text 64 KiB per result, and 4,096 matches.
Page size 1 to 200 results, 50 by default.
Page token Valid for 15 minutes.
Index description 16,384 characters.
Index tags 64 per index. A tag key is 1 to 128 characters; a value is up to 1,024.