Search is where users spend the most time on any data-intensive platform. E-commerce sites live and die by product search quality; aggregator platforms depend on filter accuracy; SaaS products measure success partly by how fast users find what they need. Getting Elasticsearch search infrastructure right is not a tuning exercise — it determines whether your platform works.
This guide covers the full production stack: inverted index internals, cluster architecture patterns, mapping design, relevance tuning, autocomplete strategies, faceted search with aggregations, and operational monitoring. By the end, you will have a clear model of what Elasticsearch search infrastructure looks like at each scale and which components to build first.
Elasticsearch Search Infrastructure: Core Architecture
Elasticsearch is a distributed search and analytics engine built on Apache Lucene. The architecture decisions you make at setup — shard counts, replica strategies, mapping design — determine your ceiling for scale and query performance.
How the Inverted Index Works
Traditional databases scan rows sequentially. For full-text search across millions of documents, sequential scanning fails. The inverted index stores the list of documents containing each term, enabling instant lookup.
Consider three documents: "fast shipping guaranteed", "free shipping available", "fast guaranteed delivery". The inverted index maps: "fast" → [doc1, doc3], "shipping" → [doc1, doc2], "guaranteed" → [doc1, doc3]. A query for "fast shipping" intersects these lists and scores doc1 highest.
This structure, combined with Lucene's segment-based architecture, provides high performance for both writes and reads. Each new document creates a small segment; segments are periodically merged in the background (compaction).
Cluster Node Roles
A production Elasticsearch cluster separates work across specialized node types:
Master nodes manage cluster state — creating and deleting indices, tracking shard allocation. Run a minimum of three dedicated master nodes to prevent split-brain. Master nodes should not serve search traffic.
Data nodes store shards and execute search queries. Size data nodes for the working set that fits in memory (OS page cache matters more than JVM heap for query performance). Hot-warm-cold tiering uses different hardware classes for different data ages.
Coordinating nodes (sometimes called client nodes) receive search requests, scatter them to relevant data nodes, gather results, and return the merged response. Separating coordination from data work prevents large queries from interfering with indexing.
Ingest nodes run transformation pipelines before indexing. Grok patterns, date parsing, geo-IP enrichment, and field extraction all run on ingest nodes, keeping transformation close to the data path.
Shard and Replica Strategy
Every Elasticsearch index is divided into primary shards. The shard count is set at index creation and cannot be changed without a full reindex — this is the most consequential architectural decision you will make.
Rules of thumb from production systems:
- Target 20–50 GB per shard. A shard much smaller than 20 GB creates overhead; larger than 50 GB slows recovery after node failures.
- For a 1 TB dataset, start with 20–30 shards across data nodes.
- Total shards per cluster (primaries + replicas) should stay under 1,000 per node. Clusters with tens of thousands of shards hit master node bottlenecks.
Replica shards provide redundancy and read parallelism. Increase replicas for read-heavy workloads — queries distribute across all copies. During initial bulk indexing, set replicas to 0 and restore after indexing completes. Write throughput roughly doubles with zero replicas.
Index Design and Mapping Strategies
Mapping in Elasticsearch is the schema definition: it specifies how each field is stored and indexed. Poor mapping decisions are hard to reverse.
Field Types
Text fields are analyzed — broken into tokens, lowercased, stemmed — and stored in the inverted index for full-text search. Do not use text fields for filtering, sorting, or aggregations.
Keyword fields are stored as-is — no analysis — and support exact match, filtering, sorting, and aggregations. Use keyword for product SKUs, category names, status codes, and tags.
Multi-field mapping indexes a single field as both text and keyword:
"product_name": {
"type": "text",
"fields": {
"keyword": { "type": "keyword" }
}
}
This lets you full-text search product_name while also filtering and sorting on product_name.keyword.
Numeric types (integer, float, double) and date use range-optimized data structures. Store numeric metadata explicitly typed — auto-mapping from JSON can infer float when you need integer, breaking range aggregations.
Nested type handles arrays of objects where inner object matching must be independent. If a product has multiple reviews with author and rating, nested ensures a search for "5-star reviews by Alice" does not match a review where Alice left 3 stars and Bob left 5 stars.
Dynamic Mapping in Production
Elasticsearch creates fields automatically when new data arrives (dynamic mapping). In production, this leads to mapping explosions — an application pushing logs with arbitrary field names can create tens of thousands of mapped fields, crashing the master node.
Set dynamic: strict on indices receiving unknown input. Define all expected fields explicitly. Use a catch-all keyword field for arbitrary metadata if you need it.
Index Templates and Component Templates
Index templates apply mapping and settings to all indices matching a naming pattern. Component templates define reusable mapping fragments — date fields, geo fields, standard metadata — that multiple index templates share. This structure prevents mapping drift across related indices.
PUT _component_template/timestamps
{
"template": {
"mappings": {
"properties": {
"created_at": { "type": "date" },
"updated_at": { "type": "date" }
}
}
}
}
Relevance Tuning: Surfacing the Right Results
Search result ranking determines user satisfaction. Elasticsearch defaults to BM25 — a proven algorithm that balances term frequency, inverse document frequency, and document length normalization.
BM25 Mechanics
BM25 scores a document higher when the query term appears frequently in that document (TF), the term is rare across all documents (IDF), and the document is short. A product title match scores higher than the same term buried in a long description.
BM25 has two tuning parameters: k1 (term frequency saturation — how much extra weight additional occurrences add) and b (length normalization strength). Defaults of k1=1.2 and b=0.75 work well for most content. Short product titles may benefit from lower b values.
Field Boosting
Not all fields carry equal weight. A match in the product title matters more than a match in the product description. In multi-match queries, apply field boosts:
"multi_match": {
"query": "running shoes",
"fields": ["title^3", "category^2", "description"]
}
Validate boost values with real query data. Boosting title 3x may under-serve long-tail queries where the exact match is only in the description.
Function Score Queries
Pure text relevance is insufficient for e-commerce and aggregator search. Business logic must participate in ranking:
- Popularity: multiply relevance score by sales volume or view count
- Recency: decay function reduces scores for older documents exponentially
- Inventory: filter out-of-stock products or reduce their scores
- Geo-distance: boost nearby listings on proximity-sensitive queries
Function score queries combine these signals with the text match score. The multiply mode preserves text relevance while business factors act as multipliers — a product that matches well and is popular ranks higher than a product that matches perfectly but has never sold.
In Smart Maple's aggregator platform projects, we typically implement a two-stage ranking: Elasticsearch retrieves the top-K candidates by text relevance, then a lightweight re-ranker applies business logic in application code before returning results to the user. This keeps the Elasticsearch query simple and lets business rules evolve without re-indexing.
Autocomplete and Suggestion Mechanisms
Showing suggestions as users type is one of the highest-impact search UX features. Elasticsearch supports multiple approaches with different tradeoffs.
Completion Suggester
The completion suggester uses a Finite State Transducer (FST) data structure held in memory. It returns results in milliseconds and supports prefix matching. It is best suited for bounded value sets — product names, category names, brand names — where inputs are known in advance.
"product_name_suggest": {
"type": "completion",
"analyzer": "standard"
}
FST is memory-intensive. For 10 million product names averaging 40 characters, expect 400–600 MB of heap for the completion field alone.
Edge N-gram Tokenizer
Edge n-grams tokenize from the start of each word: "elasticsearch" becomes "el", "ela", "elas", "elast", and so on. This supports prefix matching on text fields with full relevance scoring.
Use different analyzers for indexing and search:
"analysis": {
"analyzer": {
"autocomplete_index": {
"tokenizer": "edge_ngram_tokenizer",
"filter": ["lowercase"]
},
"autocomplete_search": {
"tokenizer": "standard",
"filter": ["lowercase"]
}
}
}
The index analyzer generates n-grams; the search analyzer uses standard tokenization. Without this distinction, searching for "elastic" would match documents containing "el" — every word.
search_as_you_type Field Type
Elasticsearch 7.x introduced search_as_you_type, which handles both prefix and infix matching automatically. It creates sub-fields with edge n-gram and shingle analysis internally, requiring no manual analyzer configuration. For new implementations, this is the lowest-complexity autocomplete solution.
Faceted Search and Aggregations
Modern search interfaces show filtering panels — categories, price ranges, ratings, attributes — alongside results. Elasticsearch aggregations power this faceted search.
Terms Aggregation
Returns distinct values and document counts for a field. Use keyword fields for terms aggregations:
"aggs": {
"categories": {
"terms": { "field": "category.keyword", "size": 20 }
}
}
Size controls how many distinct values to return. For high-cardinality fields, increase size at the cost of memory and CPU.
Range Aggregation
Groups documents into numeric ranges — price brackets, date windows, distance bands:
"aggs": {
"price_ranges": {
"range": {
"field": "price",
"ranges": [
{ "to": 50 },
{ "from": 50, "to": 200 },
{ "from": 200 }
]
}
}
}
Post-Filter for Accurate Facet Counts
When a user selects "Electronics" as a category filter, the results list should show only electronics — but the category facet should still show counts for all categories (so the user can switch). post_filter applies after aggregations are calculated:
{
"query": { "match_all": {} },
"aggs": { "categories": { "terms": { "field": "category.keyword" } } },
"post_filter": { "term": { "category.keyword": "Electronics" } }
}
Without post_filter, the category aggregation would only count electronics documents, hiding the ability to navigate to other categories.
Performance Optimization
Search performance degrades predictably with scale. Catch the patterns early.
Query Performance
Prefer filter context over query context wherever possible. Filters do not calculate relevance scores and are cached by the node query cache. A bool query with filters runs faster than the equivalent query:
"bool": {
"must": [{ "match": { "title": "shoes" } }],
"filter": [
{ "term": { "in_stock": true } },
{ "range": { "price": { "gte": 20, "lte": 200 } } }
]
}
The match clause scores; the filter clauses are cached.
Avoid script queries in hot paths. Scripts execute JVM bytecode per document and bypass caching. Replace script-based sorting with pre-computed numeric fields where possible.
Indexing Performance
For bulk indexing operations, use the bulk API — individual index calls carry per-request overhead. Temporarily disable refresh (refresh_interval: -1) and set replicas to 0 during large loads; restore both after completion.
Refresh creates a new segment and makes documents searchable. At 1-second refresh, indexing throughput is limited by segment creation overhead. For pipelines that can tolerate 30-second freshness, increase the interval.
Cache Strategy
Elasticsearch maintains three cache layers:
- Node query cache: caches filter results per segment. Invalidated when the segment is refreshed.
- Shard request cache: caches aggregation and top-hits results for requests with
size: 0. Useful for dashboards. - Fielddata cache: used for aggregations and sorting on text fields. Avoid fielddata on text; use keyword fields instead.
Monitor cache sizes and eviction rates. An undersized query cache causes repeated filter recomputation; an oversized fielddata cache drives JVM heap pressure.
Scaling Strategies
Horizontal Scaling
Add data nodes to distribute shard storage and query load. Elasticsearch automatically rebalances shards across nodes (rebalancing). For predictable scaling, use Index Lifecycle Management (ILM) to move indices through hot → warm → cold → frozen phases automatically as data ages.
Hot nodes use fast NVMe SSDs for recent, frequently-queried data. Warm nodes use cheaper SSDs or HDDs for data queried occasionally. Cold nodes use object storage (S3-compatible) for archival data. The query latency difference between hot and cold can be 10-100x — tier carefully.
Time-Series Indexing
For logs, metrics, and event data, use time-based index rollover. Index aliases point to the active write index; readers query all indices through a single alias. When the active index reaches a size or document count threshold, ILM creates a new index and updates the alias automatically.
This strategy keeps individual index sizes bounded and enables dropping old data by deleting old indices — vastly simpler than deleting documents.
Cross-Cluster Search
For geographically distributed systems or multi-tenant architectures with separate clusters, Cross-Cluster Search (CCS) lets a single query span multiple clusters. The coordinating cluster scatters the query to remote clusters and merges results. Latency adds up across clusters — keep cross-cluster queries rare and indexed appropriately.
Operational Monitoring
Cluster health degrades before it fails. Instrument these signals:
Cluster health status: Green (all primary and replica shards assigned), Yellow (some replicas unassigned), Red (some primary shards unassigned — data potentially unavailable). Red requires immediate response.
JVM heap usage: Keep below 75% of allocated heap. Above 75%, garbage collection starts causing latency spikes. Above 85%, the risk of out-of-memory kills rises sharply. Heap should not exceed 30 GB on a single node due to compressed pointer limitations.
Search latency percentiles: Track p50, p95, and p99 separately. p99 captures tail latency that affects 1 in 100 queries. Alert when p99 exceeds your SLA threshold.
Indexing rate and reject rate: Thread pool rejections indicate the cluster cannot keep up with write load. Scale horizontally or reduce write pressure.
Shard count: Above 1,000 total shards per node, master node overhead becomes measurable. Above 10,000 per cluster, expect cluster state management latency.
Use Kibana's Stack Monitoring, or export metrics via Elasticsearch Exporter to Prometheus and visualize in Grafana. Alert on heap usage, unassigned shards, search latency, and disk utilization crossing 80%.
Alternative Search Engines
Elasticsearch is not the right choice for every scenario.
OpenSearch: AWS-maintained fork of Elasticsearch 7.10. Fully open source, API-compatible with most Elasticsearch clients. Natural choice for teams running on AWS infrastructure or requiring a non-proprietary license.
Meilisearch and Typesense: Modern search engines optimized for developer simplicity and fast relevance out of the box. Typo-tolerance and ranking are strong defaults with minimal configuration. Ideal for small-to-medium datasets, MVPs, and internal tools where operational simplicity matters more than extreme scale.
Algolia: Fully managed SaaS search. No infrastructure to operate. Per-request pricing makes it expensive at scale but cost-effective for early-stage products. Rich UI components accelerate frontend integration.
Conclusion
Effective Elasticsearch search infrastructure requires treating mapping design, analyzer selection, relevance tuning, and operational monitoring as a unified system rather than independent tasks. Start with explicit mappings — never rely on dynamic mapping in production. Instrument from day one: zero-result rate, average query latency, p99 latency, and click-through rank distribution all surface problems before users complain.
Scale progressively. A single-node development cluster is sufficient for testing mapping and analyzer choices. Add replicas and data nodes as load grows. Use ILM to automate data lifecycle. Validate relevance changes with A/B tests before rolling them to all traffic. Search quality is not set-and-forget — it improves continuously as you measure what users actually click.
Related Articles
MLOps Guide: Taking Machine Learning Models to Production [2026]
87% of machine learning models built by data science teams never reach production. The models work — they pass cross-validation, they score well on holdout sets, they demonstrate genuine predictive value. The problem is not the modeling. The problem is everything that happens between a notebook experiment and a reliable, monitored, production system. MLOps is the discipline that closes that gap. This guide covers the full MLOps stack: maturity levels, tooling choices (MLflow, DVC, Kubeflow
Read More: MLOps Guide: Taking Machine Learning Models to Production [2026]LLM Fine-Tuning Guide: Custom Model Training with LoRA and QLoRA [2026]
General-purpose LLMs are impressive. They can write code, summarize documents, answer questions, and translate between languages with reasonable accuracy. But "reasonable" is not good enough when your application requires consistent output format, domain-specific terminology, a particular tone, or behavior that the base model was never trained to exhibit. That gap is where fine-tuning matters. Fine-tuning updates a model's weights on your specific data, changing how the model behaves — not
Read More: LLM Fine-Tuning Guide: Custom Model Training with LoRA and QLoRA [2026]Computer Vision Applications: Object Detection, OCR, and Industrial AI [2026]
Computer vision has moved well past the research phase. The models are trained, the frameworks are mature, the hardware is accessible, and the use cases are generating measurable returns. What was a specialized capability requiring deep expertise in 2018 is now deployable infrastructure — if you know which component to reach for and where the real complexity lives. This guide covers computer vision applications across industrial, medical, logistics, and document processing domains. It expl
Read More: Computer Vision Applications: Object Detection, OCR, and Industrial AI [2026]
