2026 · Novus Stream Solutions (hub)About 13 min readNovus Stream Solutions
Static search vs hosted search: which does a small site actually need?
Every content site eventually needs a search box, and the reflex is to sign up for a hosted service. For most small sites that is the heavier choice: a prebuilt index shipped with the page is cheaper, faster, and fresher than it gets credit for. Here is the honest math, with our own search as the worked example.
Contents
- 1.Overview
- 2.The index-size math, with actual numbers
- 3.Freshness: a deploy, not a sync pipeline
- 4.Relevance quality: where hosted search earns its fee
- 5.Cost at small scale, and the shape of the risk
- 6.Latency and failure modes
- 7.How our own search works, as a worked example
- 8.Migrating later, in either direction
- 9.A decision rule you can apply in five minutes
Overview
The day our site crossed three hundred articles, browsing stopped being a viable way to find anything, and I did what most people do: opened a tab to compare hosted search services. Every one of them was excellent, and every one of them was shaped for a problem we did not have — millions of records, thousands of queries a second, merchandising rules, A/B-tested ranking. What we had was a few hundred posts, tutorials, and docs pages that needed a fast search box. We ended up shipping a prebuilt index that travels with the site itself, and a year of running it has convinced me the choice deserves a more honest comparison than it usually gets.
The two architectures could hardly be more different. Static search — sometimes called client-side or prebuilt search — generates an index of your content at build time and delivers it to the browser, where a small amount of JavaScript answers queries locally with zero network round trips. Hosted search keeps the index on someone else’s servers: you push records to their API, their infrastructure handles queries, and you embed their widget or call their endpoint from your site. One is a file; the other is a service. That distinction drives everything downstream — size limits, freshness, relevance, cost, and failure modes — so I will walk through each in turn with real numbers.
The index-size math, with actual numbers
The case against client-side search is always the same sentence: “the index gets too big.” Whether that is true depends entirely on what you put in it, so let us do the arithmetic instead of repeating the folklore. A metadata index — title, URL, description, and a keyword field per document — costs roughly 300 to 500 bytes per document once serialized. At 350 documents, that is under 200 KB uncompressed, and text like this compresses hard: gzip or brotli takes it to 40–60 KB on the wire, which is less than a single mid-sized hero image. Even at 2,000 documents you are near 250–350 KB compressed, still smaller than the JavaScript bundle many sites ship without blinking.
Full-text indexing changes the equation, and this is where people get burned. Indexing every word of every article means the index scales with your total corpus, not your document count: 350 articles averaging 2,500 words is 875,000 words, and a naive inverted index over that lands in the multi-megabyte range before compression. Tools like Pagefind attack this by chunking the index and lazy-loading only the fragments a query touches, which keeps first-load cost tiny at the price of a little query latency. The practical rule I use: metadata search scales to thousands of pages without tricks, full-text search needs chunking beyond a few hundred, and if neither fits your corpus you have genuinely outgrown static search — which is a real threshold, just a much higher one than the folklore claims.
- Metadata-only index: ~300–500 bytes per document; 350 docs ≈ 40–60 KB compressed on the wire.
- Full-text index: scales with total words, not page count; multi-megabyte territory past a few hundred long articles.
- Chunked full-text (Pagefind-style): tiny initial load, fragments fetched per query.
- Hosted index: effectively unlimited size, but every query is a network round trip.
Freshness: a deploy, not a sync pipeline
Hosted search vendors talk about real-time indexing as a headline feature, and for a marketplace where sellers add listings every minute, it is one. For a content site, the question to ask is: how does new content actually appear on your site? For us — and for most small sites — the answer is a deploy. A post does not exist for readers until the site rebuilds, and since the search index is generated during that same build, the index and the content are updated in the same atomic step. It is impossible for our search to be staler than the site, because they are the same artifact.
The hosted model splits that atom. Your content pipeline and your search index become two systems that must be kept in sync: a webhook or CI step pushes new records after each publish, deletions have to propagate or dead results linger, and edits to titles or URLs must overwrite the right record IDs. None of this is hard, but all of it is surface area, and sync bugs in search are the embarrassing kind — a visitor searches for the post you promoted this morning and gets nothing, or clicks a result that 404s because the redirect never reached the index. If your content changes through deploys, build-time indexing is not a freshness compromise. It is the stronger freshness guarantee.
There is one freshness case worth planning for in advance: the emergency edit. When a published page contains something that must disappear immediately — a broken embed, a factual error a reader flagged, a post you need to unpublish — the static model’s answer is a rebuild, which on our stack means the fix is live everywhere, index included, in about two minutes. Know your build time before you need it, because that number is your worst-case correction latency for every page you have ever published — and hosted search does not escape the problem either, since a takedown has to propagate through the sync pipeline too, leaving two systems to confirm instead of one. If builds take twenty minutes, that is a genuine cost of the static approach no comparison table mentions, and shrinking it — caching, incremental builds, a lighter image pipeline — buys operational calm that has nothing to do with search and everything to do with sleeping soundly after you hit publish.
Relevance quality: where hosted search earns its fee
Here is the part of the comparison where I will argue against my own setup, because pretending client-side search matches a mature hosted engine on relevance would be dishonest. Typo tolerance is the clearest gap: a hosted service returns your pricing page when someone types “pricng,” while a naive term-match index returns nothing. Add stemming (“exporting” matching “export”), synonym handling (“picture” finding “image”), multi-language analyzers, and ranking models tuned on billions of queries, and the quality ceiling of a hosted engine is simply higher. Those capabilities exist in client-side libraries too, but each one you enable grows the index and the code you ship.
The honest counterweight is that relevance difficulty scales with corpus size and query ambiguity, and a small site has little of either. When 350 documents have distinct, descriptive titles, a query has maybe three plausible targets, and a scoring rule as crude as “title match beats description match” gets the right answer almost every time. The sophisticated machinery matters when 40,000 products all contain the word “blue” — not when the question is which of nine visualizer tutorials mentions beat sync. My working rule: if your visitors’ queries routinely fail on a simple index, that is a real signal to upgrade; buying world-class ranking before you have a ranking problem is paying for headroom you cannot feel.
Cost at small scale, and the shape of the risk
On price, the static approach is not merely cheaper — it removes the line item. A prebuilt index costs whatever your build already costs plus a few hundred milliseconds of generation time, and serving it is bandwidth you were already paying for, which on a small site rounds to zero. There is no per-query meter, no per-record quota, no plan tier to watch. A traffic spike that triples your search volume changes nothing, because the queries execute on your visitors’ devices.
Hosted pricing at small scale looks friendly at first glance — free tiers commonly cover around 10,000 queries a month — and the risk is not the sticker price but the shape of it. Metered pricing means your costs are a function of someone else’s behavior: a post goes modestly viral, curious readers hammer the search box, and the invoice notices even though your revenue does not. Vendors also reprice: quotas shrink, free tiers gain limits, per-record fees appear, and a dependency you adopted at zero dollars quietly becomes a bill you have to budget for. None of that makes hosted search a bad purchase — it makes it a purchase, with all the ongoing attention purchases demand, versus a build artifact that will never email you about a plan change.
- Static: zero marginal cost per query, per record, and per visitor; cost lives in your existing build.
- Hosted free tiers: generous today, but metered — spikes and repricing are both real exposures.
- Hidden hosted cost: the sync pipeline is code you write, run, and debug forever.
- Hidden static cost: relevance features you want become bytes every visitor downloads.
Latency and failure modes
Query latency splits the two architectures in an interesting way. A client-side index answers in single-digit milliseconds because there is no network in the loop — results can update on every keystroke without debouncing gymnastics, which is why local search feels eerily instant. A hosted query is a round trip: often 50–150 ms from good geography, worse on mobile networks, and vendors mitigate it with edge replication precisely because the physics are against them. For an autocomplete experience, local wins outright; the hosted latency is fine for a search results page and noticeable in a type-ahead.
Failure modes matter more than averages, and they differ in kind. Static search has essentially one: the index you shipped is the index you have, so a bug in generation ships to everyone until the next deploy. Hosted search inherits the failure surface of any third-party service — API outages, expired keys, rate limiting, an ad blocker or corporate firewall eating the widget’s requests. When our site is up, our search is up, by construction. I have watched sites where the content loaded fine while the search box spun forever because a search vendor was having a bad afternoon, and visitors do not file that under “vendor problem.” They file it under “this site is broken.”
How our own search works, as a worked example
Concrete beats abstract, so here is the actual design running on this site. Our content lives in typed TypeScript modules rather than a CMS — the approach covered in Content as code: running a 250-post blog without a CMS — which means every post, tutorial, and docs page is already a structured object at build time. A single function walks those modules and emits one search entry per document: title, URL, a short description, a kind tag (Tutorial, Blog, Documentation, or Page), and a precomputed lowercase keyword string. No crawler, no extraction step, no records API — the index is a byproduct of the content’s existing shape.
The client side is deliberately small. Queries are split into terms, and every term must match somewhere in an entry’s keyword string or the entry is discarded — an AND that keeps multi-word queries precise. Surviving entries are scored with flat, legible weights: a title hit counts ten, a context hit four, a description hit two, and results cap at fifty. There is no stemming, no typo tolerance, no learned ranking, and across a catalog of a few hundred documents with descriptive titles, the right result lands in the top three essentially every time. The entire feature is one generator, one scoring function, and one React view — no vendor, no API key, no invoice — and it fits comfortably inside the performance budget discussed in Page speed and Core Web Vitals for a small site. The same index also powers the search that sits beside our Documentation section, because one artifact serves every surface.
What I would change at a different scale is easy to name. If the catalog reached several thousand documents, the shipped index would need chunking or a move to metadata-only entries with lazy-loaded full text. If query logs showed visitors failing on typos and synonyms, that would be the trigger to either adopt a heavier client library or finally pay for hosted relevance. Neither trigger has fired, and this is the discipline the whole comparison comes down to: upgrade on evidence, not on architecture anxiety.
Migrating later, in either direction
One fear deserves a direct answer: if you start static, are you trapped when the site outgrows it? The migration from a prebuilt index to a hosted service turns out to be the gentle direction. The build step that generates your index already produces exactly what a records API wants to ingest — structured objects with titles, URLs, and descriptions — so the switch is a push script and a widget swap, an afternoon of work rather than a re-architecture. Nothing about starting static forecloses the hosted option; the structured content that made the index cheap to generate makes the eventual export equally cheap. The worst case is that you deferred a subscription until the day you demonstrably needed one, which is not a failure mode. It is the plan working.
The reverse migration is the one that stings, and I have watched it happen twice to teams caught by a repricing. Unwinding a hosted dependency means rebuilding query handling you never wrote, re-implementing whatever relevance behavior your visitors quietly came to rely on, and discovering how many corners of the site — autocomplete here, a related-articles widget there — had grown roots into the vendor’s API. The asymmetry generalizes well beyond search: it is almost always cheaper to graduate from the simple architecture to the service than to retreat from the service to the simple architecture, because services are engineered to be easy to enter. Nobody engineers them to be easy to leave.
So sequence the decision with that asymmetry in mind. If you genuinely cannot tell which side of the size thresholds your site will land on, start with the prebuilt index anyway — the cost of being wrong runs in the cheap direction. Instrument the search box from day one: log queries that return zero results, even if only to a counter you glance at monthly, and let that log be the upgrade trigger. When the zero-result rate climbs or the index outgrows its byte budget, you will migrate with evidence in hand and a vendor shortlist shaped by your visitors’ actual query patterns, instead of guessing at features from a pricing page. That is what a properly hedged architecture bet looks like: reversible, instrumented, and priced in advance.
A decision rule you can apply in five minutes
Strip away the vendor marketing and the folklore, and the choice reduces to three questions. First: how many documents, and how do they change? Under a couple thousand documents updated via deploys, static search is the default; tens of thousands of records changing continuously, hosted. Second: what do failed queries cost you? On a content site, a missed search means a visitor browses instead — annoying, cheap. On a store, a missed search is a missed sale, and paying for typo tolerance and merchandising has direct revenue math behind it. Third: who types the content? Curated titles written by you are easy to match; user-generated text in a dozen languages is the hard problem hosted engines were built for.
It is the same instinct that drives the static-first argument in Static-first: when a small site doesn't need a single-page app: adopt the service-shaped solution when you have the service-shaped problem, and not before. Search vendors are not selling snake oil — they are selling industrial equipment, and industrial equipment is wasted on a workshop. Ship the index with the site, watch what real visitors actually search for, and let observed failures — not imagined scale — tell you when to reach for the heavier tool. Most small sites will find that day never comes.
Frequently asked questions
Quick answers to common questions about this topic.
What is the difference between static search and hosted search?
Static (client-side) search builds an index of your content at build time and ships it to the browser, where JavaScript answers queries locally with no network requests. Hosted search keeps the index on a vendor’s servers: you push records to their API and every query travels to their infrastructure. The first is a file that deploys with your site; the second is an ongoing service with its own sync pipeline, latency, quotas, and bill. The right choice depends on document count, how content changes, and how costly failed queries are.
How big does a client-side search index get?
A metadata index — title, URL, description, keywords — runs roughly 300–500 bytes per document, so a few hundred pages compress to about 40–60 KB on the wire, smaller than one hero image. Full-text indexing scales with total words instead of page count and reaches multi-megabyte sizes past a few hundred long articles, which is where chunked, lazy-loaded approaches like Pagefind become the right tool. For most small sites, the index is far smaller than the folklore suggests.
Is a prebuilt search index always stale compared to hosted search?
No — often the opposite. If your content only changes when the site deploys, an index generated during that same build updates in the same atomic step as the content, so search can never lag behind the site. Hosted search introduces a second system that must be synced: new records pushed, deletions propagated, edits overwritten. Real-time indexing genuinely matters for marketplaces and user-generated content, but for deploy-driven content sites, build-time indexing is the stronger freshness guarantee.
When is a hosted search service worth paying for?
When you have the problem it was built for: tens of thousands of records or more, content that changes continuously outside deploys, user-generated or multi-language text, or queries where a miss costs revenue — a store’s search box being the classic case. Hosted engines deliver typo tolerance, synonyms, stemming, and tuned ranking that simple client-side matching does not. The signal to upgrade is observed query failures on your real traffic, not anticipated scale.
Does client-side search hurt page performance?
Only if you let the index outgrow its budget. A compressed metadata index for a few hundred documents costs tens of kilobytes and can be loaded lazily — only when a visitor focuses the search input — so it adds nothing to initial page weight. Queries then run in single-digit milliseconds with no network round trip, which is why local search feels instant and can update on every keystroke. The thing to watch is full-text indexing, which grows with your total word count.