Search & Autocomplete — Failure & Scale Scenarios
What happens when search nodes fail, the cache stampedes, the indexing pipeline backs up, a bad index deploys, updates race out of order, ranking degrades, a query or prefix goes hot, or the index quietly diverges from the source of truth.
Search Node / Shard Failure
A search shard node fails. What happens next depends on replica availability and configuration — it is not automatically "no outage."
Failure: a node hosting a shard (primary or replica) becomes unreachable. User impact: if a healthy replica for that shard exists, queries can be served with reduced capacity and potentially elevated latency as remaining nodes absorb redistributed load; if no replica is available for that shard, queries touching it either fail entirely or return partial results, depending on the fail-vs-partial policy (see Trade-offs → Fail Query vs Return Partial Results).
Detection
Health checks against search nodes (on some regular interval) detect the failure and stop routing to the failed node.
Degradation
Remaining/replica nodes absorb redistributed load — expect some latency increase, not necessarily a full outage, and the exact behavior depends on replica count and consistency configuration for that specific system.
Recovery / re-replication
The failed node, once restarted, needs to sync its shard data from a healthy replica before rejoining the serving pool — for large shards this sync can take a non-trivial amount of time, during which the cluster runs with reduced redundancy.
Cache Failure / Stampede
The result cache fails or expires broadly at once. Traffic that was being absorbed by the cache now hits the search cluster directly — a spike whose size depends on the actual hit rate, not a fixed multiplier.
Failure: the cache layer becomes unavailable, or a large fraction of cached entries expire around the same time. User impact: a sudden increase in load reaching the search cluster — if the workload had (for example) an 80% hit rate, losing the cache is roughly a 5x increase in cluster-facing QPS; the actual multiplier is workload-dependent, not a fixed "10x" or "6-7x" to memorize.
Request coalescing
Collapsing many concurrent identical requests into a single upstream query is the primary defense — this helps regardless of exact hit-rate math, since it prevents the same hot query from being computed redundantly many times over.
TTL jitter
Randomizing TTL slightly per cache entry avoids many entries expiring in the same instant, which is a common self-inflicted cause of stampede-like spikes even without an actual cache outage.
Stale-while-revalidate (where appropriate)
Serving a slightly-expired result while refreshing in the background avoids a hard cliff at TTL expiry.
Capacity headroom / circuit breaking / load shedding
The cluster needs enough spare capacity to absorb a realistic cache-loss spike, and circuit breaking/load shedding to protect itself if the spike still exceeds that headroom — rather than assuming the cache will always be there to absorb load.
Indexing Pipeline Backlog
The indexing pipeline falls behind. The search index serves an increasingly stale view of the corpus — but recovery is conditional, not automatic.
Failure: the pipeline (indexer, broker consumer, CDC connector) falls behind or stops processing. User impact: search results reflect an older snapshot — newly added/updated/deleted source documents don't show up (or don't disappear) as expected.
Graceful degradation
The search index is a read-optimized derivative, not the source of truth — pipeline failure causes staleness, not necessarily search downtime, as long as the index itself is still reachable.
Recovery is conditional, not automatic
Catching up depends on: the source/broker having actually retained the backlog of events (not expired past a retention window); the pipeline having sufficient catch-up throughput to work through the backlog faster than new events arrive; correct ordering/versioning so catch-up doesn't apply stale events over newer ones; and no single poison event blocking the whole backlog from progressing.
Monitoring
Track both lag (how far behind, in time or event count) and the age of the oldest unprocessed event — the second metric catches a stuck-but-still-advancing pipeline that simple lag-count monitoring can miss.
Traffic Spike
Product launches, sales events, and viral moments create sudden QPS spikes — the cache absorbs part of this, but not all of it, and autocomplete has its own multiplying effect.
Failure: search/autocomplete QPS rises sharply beyond steady-state levels. User impact: rising latency, and if capacity is genuinely exceeded, timeouts or errors.
Cache absorbs some, not all, traffic
Already-cached hot queries are absorbed by the cache layer; genuinely novel queries (a brand-new trending term, a new product just launched) bypass the cache entirely on first occurrence and hit the search cluster directly.
Autocomplete multiplies request volume
Each user session doing a single full-text search may have generated many autocomplete requests (one per keystroke, moderated by debounce) — autocomplete QPS during a spike can be a meaningfully larger multiple of "logical searches" than full search QPS is.
Warm-up cost when scaling
Adding search nodes during a spike isn't instant relief — new nodes typically need shard data synced/loaded before they can usefully serve queries, so auto-scaling has a lag between "capacity added" and "capacity actually helping."
Rate limiting / load shedding
Protects cluster stability by shedding or throttling excess load rather than letting every node degrade uniformly under overload.
Partial Shard Failure
Most shards respond normally; one is slow or times out. This is a more common real-world failure mode than a fully-down cluster.
Failure: one shard (or a small subset) responds slowly or not at all within the query's deadline, while the rest respond normally. User impact: depends entirely on the fail-vs-partial policy — either the whole query fails despite most of the corpus being reachable, or a result is returned that's missing whatever that shard held.
Query deadline
The coordinator needs an explicit timeout for how long it will wait on any single shard before deciding to proceed without it — without this, one slow shard can drag the entire query's latency arbitrarily high.
Alternate replica
If the specific node is slow/unreachable but a healthy replica for that shard exists, routing to the replica instead can avoid the problem entirely.
Partial response vs fail, explicitly marked
As covered in Trade-offs → Fail Query vs Return Partial Results, whichever choice is made, a partial response must be clearly marked as such.
Coordinator tail latency
This scenario is precisely why scatter-gather tail latency scales with the number of shards queried — more shards means more chances that at least one is the slow outlier for any given query.
Bad Index Deployment / Corrupt Index
A bad analyzer, mapping, or transformation change goes live and produces broken relevance or missing documents — without any node actually crashing.
Failure: a schema/analyzer/mapping change or a transformation bug is deployed, and the resulting index silently returns wrong, incomplete, or badly-ranked results. User impact: search still "works" (no errors) but returns poor or wrong results — often harder to detect than a hard outage precisely because nothing is throwing errors.
Detection
Requires active relevance/quality monitoring (query success-rate proxies, click-through-rate shifts, automated relevance regression checks) — a bad deploy of this kind doesn't set off traditional uptime/error-rate alerts.
Recovery
This is the direct payoff of the versioned-index-plus-alias pattern (see Architecture Deep Dive → Zero-Downtime Reindexing): validate before cutover, and if a bad version somehow reaches production, switch the alias back to the last known-good versioned index — rolling back a live in-place index is far riskier or may be impossible.
Rebuild from source of truth
If the bad index also wrote incorrect data (not just a bad mapping), a rebuild from the authoritative source database is the reliable fix, not attempting to patch the corrupted index in place.
Out-of-Order Index Updates
A delayed older update for a document arrives and is applied after a newer version already landed — silently reverting the document to stale content.
Failure: network, broker partitioning, or retry behavior delivers update v11 for a document after update v12 for the same document has already been applied. User impact: the document silently reverts to older content/fields until (if ever) another update corrects it — a subtle, hard-to-notice correctness bug rather than a visible outage.
Prevention: source versioning / sequence checks
Every update carries a monotonic version/sequence number from the source; the indexer compares the incoming version against the currently-indexed version and rejects/no-ops any update whose version is not newer (see Architecture Deep Dive → Indexing Pipeline Correctness).
Delete-vs-late-update race
A particularly sharp edge case: a document is deleted (tombstoned), and then a delayed update for a pre-delete version of that document arrives. Without version/sequence awareness, this can incorrectly resurrect a document that should stay deleted — the indexer needs to treat a tombstone as a terminal state that a stale update cannot override.
CDC/Event Loss or Retention Gap
The indexing pipeline falls behind long enough, or long enough that events fall outside the broker/log's retention window — incremental catch-up alone can no longer recover the correct state.
Failure: events needed to catch up have been deleted/rotated out of the source log or broker before the pipeline could consume them (retention exceeded) — or a connector/consumer failure caused events to be missed outright. User impact: the index has a permanent gap relative to the source that ordinary incremental processing cannot close, since the missing events no longer exist to replay.
Source reconciliation
Compare the index against the authoritative source (document counts, checksums, or targeted sampling) to detect and scope the actual divergence — see Source/Index Divergence below for the general-purpose version of this.
Snapshot / full reindex
If the gap is significant or can't be safely bounded, a full reindex from the source snapshot is the reliable recovery path, using the zero-downtime migration pattern rather than reindexing the live index destructively.
Catch-up stream + validation before cutover
After a snapshot rebuild, apply any changes that occurred during the rebuild, then validate document counts/spot-check quality before cutting traffic over to the rebuilt index.
Reindex Failure During Migration
A full reindex — building a new versioned index for a schema/analyzer change or corruption recovery — fails partway through, or falls too far behind ongoing live changes to safely cut over.
Failure: the new index build errors out, stalls, or its catch-up-with-live-changes step can't keep pace with ongoing writes. User impact: none, if the migration pattern was followed correctly — the old index is untouched and continues serving throughout.
Why this is safe by design
This is exactly why the recommended pattern builds into a new versioned index and only atomically switches the alias after validation (see Architecture Deep Dive → Zero-Downtime Reindexing) — a failed build simply means the new index isn't ready yet, not that live search is broken.
Recovery
Restart or resume the new index build (from the last good checkpoint, if the pipeline supports one, or from scratch) without touching the still-serving old index. Investigate and fix the root cause (schema bug, capacity issue, throughput mismatch) before attempting cutover again.
Ranking Service Failure
If ranking beyond first-stage lexical scoring is served by a separate system (a re-ranking model, a personalization service), that dependency can fail independently of the index itself — a strong graceful-degradation example.
Failure: the external re-ranking/personalization service is unavailable or too slow. User impact: ideally, none beyond reduced relevance quality — search itself keeps working.
Fallback to first-stage lexical ranking
If re-ranking can't be reached, fall back to serving results ordered by the first-stage (BM25-style) score alone, rather than failing the whole query.
Skip personalization/business re-ranking
Any business-rule or personalization layer that depends on the same failed service is skipped along with it, in favor of continuing to serve some reasonable result.
Hot Query / Hot Prefix
A single trending term or prefix generates disproportionate autocomplete/search QPS — a form of hot-key problem specific to search.
Failure: one term/prefix (a breaking-news term, a viral product) drives a large share of total query volume concentrated on one cache key / index term / autocomplete prefix. User impact: if unmitigated, this specific hot key can create a localized bottleneck (a single cache key stampeding, a single posting list under heavy concurrent read load) even while overall cluster capacity looks fine in aggregate.
Hot-key cache handling
Request coalescing (again) plus, for genuinely extreme cases, replicating the hot cache entry across multiple cache nodes rather than relying on a single node/key to absorb all the load.
Replication
For a hot posting list or hot shard specifically, ensuring adequate replica capacity for that shard specifically, not just average per-shard replica count.
Rate limiting
Protects against a single hot term (or a client hammering it) from degrading service for unrelated queries.
Precomputed autocomplete suggestions
For a hot prefix, a precomputed/cached suggestion list is far cheaper to serve repeatedly than recomputing ranking live for every request.
Expensive Query / Query-of-Death
A single pathological query — an overly broad wildcard, an aggressive fuzzy match, an unbounded facet request — consumes disproportionate CPU/memory and can degrade the cluster for everyone else.
Failure: a query shape (very broad wildcard/prefix, high edit-distance fuzzy match across a short prefix, a facet request over a very high-cardinality field, or a combination) is far more expensive to execute than a typical query. User impact: elevated latency or resource exhaustion affecting not just that query but others sharing the same node/shard capacity.
Query complexity limits
Bound the maximum number of clauses, term expansions, or wildcard breadth a single query is allowed to generate.
Timeout
Every query needs an enforced deadline so one expensive query can't monopolize a shard indefinitely.
Minimum prefix length / bounded edit distance
As covered in Typo Tolerance and Fuzzy Search, bounding these directly prevents the worst-case explosion in expanded term count.
Circuit breaking
Reject or degrade query classes that repeatedly trip resource thresholds, protecting overall cluster health over serving every possible query shape.
Bounded facet cardinality
Cap how many distinct facet values are aggregated/returned, rather than allowing an unbounded high-cardinality field to make a single facet request arbitrarily expensive.
Hot Shard / Uneven Distribution
Routing/domain sharding (or plain data skew) causes one shard to receive disproportionate query load or storage — a direct consequence of the sharding trade-off discussed in Trade-offs & Decisions.
Failure: one shard (commonly under routed/domain sharding, if one tenant/category is simply much larger or more heavily queried than others) grows disproportionately in size or query load relative to its peers. User impact: elevated latency specifically for queries touching that shard, and disproportionate resource pressure (memory, disk, CPU) on the node(s) hosting it.
Detection
Per-shard size and query-load monitoring, not just cluster-wide aggregates — a hot shard can be invisible in average/aggregate metrics while being a real bottleneck for the queries that happen to hit it.
Rebalance / split / routing changes
Redistributing data (splitting an oversized shard, adjusting the routing scheme for future writes) to even out the skew — this is genuinely more involved than simple document copying, since it can require replanning the routing key or reprocessing affected documents.
Replica capacity for the hot shard specifically
Adding extra replica capacity targeted at the specific hot shard, rather than uniformly increasing replica count cluster-wide, can be a faster mitigation than a full rebalance.
Autocomplete Index Stale
Full search already reflects a new or updated document, but autocomplete suggestions haven't caught up — because autocomplete commonly has its own, separate freshness pipeline.
Failure: the autocomplete candidate/suggestion source (a precomputed suggestion index, a separately-updated trie/edge-n-gram structure) updates on a different cadence than the main search index. User impact: a newly added product or trending term is findable via full search but doesn't yet appear as an autocomplete suggestion, which can look inconsistent to users.
Separate freshness SLOs are expected, not a bug
If autocomplete uses a dedicated structure or a precomputed popularity-ranked suggestion list, it's reasonable (and common) for it to have its own update cadence distinct from the main index's — this should be an explicit, monitored SLO rather than an accidental side effect nobody set out to build.
Rebuild/update behavior
Understand whether the autocomplete structure updates incrementally (new terms/documents trickle in continuously) or via periodic full rebuild (a batch job regenerates suggestions on a schedule) — this determines both the expected staleness window and how to reason about a stuck update process.
Source/Index Divergence
Over time, the search index can silently drift from the source of truth — missing documents that should exist, or retaining documents that should have been removed — without any single dramatic failure causing it.
Failure: an accumulation of missed events, edge-case bugs, or partial failures over time leaves the index quietly inconsistent with the source, without an obvious triggering incident. User impact: intermittent, hard-to-reproduce reports of "this should be in search results and isn't" or "this shouldn't show up anymore" — the kind of bug that's easy to dismiss individually but indicates a systemic reconciliation gap.
Reconciliation via counts/checksums/sampling
Periodically compare aggregate document counts, per-partition checksums, or targeted random sampling between source and index to detect divergence before it's reported by confused users.
Periodic repair
A scheduled reconciliation job that identifies and corrects specific divergent documents, rather than relying solely on the live event pipeline to eventually self-correct.
Rebuild from source of truth
For divergence too large or too systemic to patch incrementally, a full reindex from the authoritative source remains the reliable reset — the same pattern used for corruption recovery and event-loss recovery above.
Freshness/consistency metrics as an ongoing signal
Treating index-source divergence as a continuously monitored metric (not just something investigated reactively after a user complaint) catches drift early, before it compounds.
Triage map
| Scenario | Blast radius | First action |
|---|---|---|
| Search node / shard failure | Capacity or one shard's data | Serve from a healthy replica; if none exists, fail or return marked partial results |
| Cache failure / stampede | Cluster load rises by 1 / (1 − hit rate) | Request coalescing, cache replication and headroom |
| Indexing backlog | Index staleness | Check log retention; catch up, or reconcile/reindex if retention is exceeded |
| Traffic spike | Cluster load, amplified by autocomplete | Cache absorbs part; added nodes need shard data loaded first, so plan headroom from realistic spikes |
| Partial shard failure | Tail latency, completeness | Per-shard timeout; return clearly marked partial results |
| Bad index deployment | Relevance or missing documents | Detect via relevance monitoring, then switch the alias back to the last known-good versioned index; rebuild from source if bad data was written |
| Out-of-order index updates | Individual documents reverted | Compare monotonic versions and treat a tombstone as terminal so stale updates cannot override it |
| CDC / event loss | Index correctness | Source reconciliation or full reindex |
| Reindex migration failure | Migration | Keep serving the old index; do not cut over until validated and caught up |
| Ranking service failure | Relevance only | Degrade to first-stage lexical ranking |
| Hot query / prefix | Autocomplete and search load | Coalesce requests, replicate the hot cache entry, precompute hot-prefix suggestions, add replicas for that shard |
| Expensive query | Whole cluster | Bound clauses, wildcard breadth, fuzzy expansion and facet cardinality; enforce deadlines; reject repeat offenders |
| Hot shard | One shard's node | Monitor per shard; add targeted replicas, or split/re-route the oversized shard |
| Autocomplete staleness | Suggestions lag full search | Monitor the separate suggestion pipeline's freshness |
| Source/index divergence | Silent drift | Periodic reconciliation against the source of truth |