N-gram Tokenizers in Elasticsearch: Breaking Words Into Every Possible Fragment
A complete, zero-prior-knowledge walkthrough of what an n-gram tokenizer is, why partial and autocomplete search needs it, how it works internally, and how real companies use it to catch typos, substrings, and search-as-you-type queries.
Imagine trying to find a specific frame in a movie, except you don’t remember any full scene — you only remember a brief, half-second flash of color partway through. A word-by-word index of “scenes” would be useless to you; what you actually need is something that has cut the entire film into tiny, overlapping fragments, so that any fleeting moment, however short, can still be located. Elasticsearch faces a very similar problem whenever a search needs to match part of a word rather than the whole word — a partial product code, a fragment of a misspelled name, or the first few characters someone has typed so far into an autocomplete box. The tool built to solve exactly this problem is called an n-gram tokenizer, and this guide explains, from first principles, what it is, why it exists, and how it actually works.
Before we look at n-grams specifically, we need to understand what a tokenizer does in general, and why the standard word-splitting approach falls short for partial matching.
What is a tokenizer?
A tokenizer is the component within Elasticsearch’s text-analysis pipeline responsible for breaking a stream of raw text into individual, indexable units called tokens. The most familiar and commonly used tokenizer splits text on whitespace and punctuation, producing one token per whole word — so “wireless mouse” becomes the two tokens “wireless” and “mouse.” This whole-word approach works beautifully for typical full-text search, but it has a clear blind spot: it can only ever match complete words, never fragments or substrings within a word.
So what is an n-gram?
An n-gram is a short, contiguous sequence of characters (or sometimes words, though character n-grams are far more common in this context) taken from a larger piece of text, where “n” simply refers to the length of that sequence. An n-gram tokenizer, instead of producing one token per whole word, slides a small window of a fixed character length across the text, producing a token for every possible position of that window, resulting in many small, overlapping fragments rather than a handful of whole-word tokens.
Picture cutting a strip of camera film into every possible 3-frame-long clip, sliding forward one frame at a time, rather than only keeping distinct whole scenes. From a 10-frame strip, you would end up with many overlapping 3-frame clips: frames 1-3, then 2-4, then 3-5, and so on. An n-gram tokenizer does exactly this to a word’s characters: from the word “search,” with a fragment length of 3, it produces overlapping fragments like “sea,” “ear,” “arc,” “rch,” and more, rather than a single token for the whole word “search.”
Two related but distinct flavors
Elasticsearch offers two closely related tools worth distinguishing clearly from the start. A plain n-gram tokenizer generates fragments starting from every position within a word, useful for matching a substring located anywhere inside a larger word. An edge n-gram tokenizer generates fragments only from the beginning of a word, growing outward one character at a time — producing, for the word “search,” fragments like “se,” “sea,” “sear,” “searc,” and “search.” Edge n-grams are specifically what powers the familiar experience of search suggestions appearing as a user types character by character.
A regular n-gram tokenizer is built for “does this word contain this substring anywhere?” A prefix-focused edge n-gram tokenizer is built specifically for “has the user typed the beginning of this word so far?” — two related but genuinely different matching needs, solved by two closely related but distinct tools.
Any position
Produces fragments starting anywhere within the word, good for finding a substring located anywhere inside a larger term.
Beginning only
Produces fragments that always start from the first character, growing outward, ideal for search-as-you-type autocomplete.
Let’s look at where an n-gram tokenizer fits inside the broader text-analysis pipeline, and the settings that shape its behavior.
The analysis pipeline it belongs to
Recall that an analyzer is generally made up of a character filter stage, a tokenizer stage, and a token filter stage. An n-gram tokenizer is simply a specific choice made at the tokenizer stage, slotted into this same overall pipeline just as the standard whole-word tokenizer would be. This means an n-gram-based field can still be combined with the same lowercase normalization, stop-word handling, or other token filters used elsewhere, if desired, applied on top of the raw n-gram fragments it produces.
Minimum and maximum gram length
An n-gram tokenizer’s behavior is primarily controlled by two settings: a minimum fragment length and a maximum fragment length. Rather than producing fragments of only one fixed size, it typically produces fragments across a configured range — for example, a minimum of 2 and a maximum of 3 characters would produce both 2-character and 3-character fragments for every applicable position in the text. Choosing this range carefully is one of the most important decisions when configuring n-gram-based search, since it directly controls the trade-off between matching flexibility and index size.
Where n-grams are typically applied: multi-fields
N-gram-based analysis is rarely applied to a field’s only representation. It is far more common to add an n-gram-analyzed sub-field alongside a normally-analyzed field (using the multi-field concept covered elsewhere in this reference library), so that ordinary full-text search continues to use standard whole-word matching, while a dedicated sub-field is available specifically for partial-match or autocomplete-style queries when needed.
flowchart TB
A["Raw Text Input
'search'"] --> B["N-gram Tokenizer
min: 2, max: 3"]
B --> C["se"]
B --> D["sea"]
B --> E["ea"]
B --> F["ear"]
B --> G["ar"]
B --> H["arc"]
B --> I["...and more overlapping fragments"]
C --> J["Inverted Index
of Overlapping Fragments"]
D --> J
E --> J
F --> J
G --> J
H --> J
I --> J
J --> K["Substring Query Matches Fragment
Directly, No Wildcard Scan Needed"]
“Why would you use an n-gram tokenizer instead of a wildcard query for substring matching?” — A strong answer explains that a wildcard query typically has to scan across the term index at query time, which can be slow, whereas n-gram tokenization does the fragmenting work once, up front, at indexing time, so a substring search becomes a fast, direct lookup against pre-built fragment tokens instead of an expensive scan.
Let’s trace, step by step, exactly what happens the moment a document containing n-gram-analyzed text is indexed, and later searched.
Raw text enters the analysis pipeline
The field’s value passes through any configured character filters first, exactly as it would for any other field, before reaching the tokenizer stage.
The sliding window generates overlapping fragments
The n-gram tokenizer walks across the text, producing a fragment at every valid position for every configured length between the minimum and maximum gram size.
Any configured token filters are applied to each fragment
If lowercasing or other token filters are configured, they are applied uniformly to every generated fragment, just as they would be to whole-word tokens elsewhere.
Every fragment becomes its own entry in the inverted index
Each overlapping fragment is stored as an individually searchable token, meaning a single word can produce many more index entries than it would under standard whole-word tokenization.
A search query is analyzed appropriately at query time
Typically, the search-time query uses a different, non-n-gram analyzer on the query text itself (matching against the pre-built n-gram tokens), preventing the query from over-expanding into excessive extra fragments of its own.
Matching documents are found via direct fragment lookup
Because the fragments were already generated and indexed ahead of time, a substring search becomes a direct, efficient lookup against existing index entries, rather than an expensive real-time scan across the full term dictionary.
It is common practice to use a different analyzer for indexing (the n-gram analyzer, generating many fragments) than for searching (a simpler analyzer that does not itself further fragment the query text). Without this “index-time vs search-time” separation, a search query would also get exploded into many fragments, often producing far too many loosely matching results.
N-gram tokenization shapes both how data grows on disk over its lifetime and how a search experience feels character by character.
Index growth over time
Because n-gram tokenization multiplies a single word into many overlapping fragment tokens, an n-gram-analyzed field naturally grows the size of an index more than an equivalent standard-analyzed field would, and this effect compounds as more documents are indexed over the index’s lifetime. This growth is a direct, predictable consequence of the fragment-length range chosen; wider ranges producing proportionally more fragments per word.
The search-as-you-type lifecycle
In a typical autocomplete experience built on edge n-grams, a user’s keystrokes drive an evolving sequence of queries: after one character, results reflect an extremely broad match; after several more characters, the effective match narrows considerably, purely because the query text itself is growing longer and more specific with each keystroke, while the underlying edge-n-gram-indexed fragments remain unchanged. This lifecycle — broad to narrow, driven entirely by growing query length — is what gives autocomplete its familiar, responsive, narrowing-as-you-type feel.
Reindexing implications
Just like other analyzer choices, changing an n-gram tokenizer’s minimum or maximum length settings on an already-populated field requires a reindex, since the previously generated fragments were built using the old configuration and cannot be retroactively regenerated in place.
Min & Max Gram
n-gram & edge n-gram
With Wider Ranges
N-gram tokenization solves a genuine problem well, but it is one of the more resource-intensive text-analysis choices available, and that trade-off deserves careful thought.
Advantages
- Enables fast substring and partial-word matching without expensive query-time wildcard scanning.
- Edge n-grams power responsive, character-by-character autocomplete and search-as-you-type experiences.
- Helps surface results despite minor misspellings or partial input, improving forgiving, user-friendly search.
- The fragmenting work happens once at indexing time, keeping query-time performance predictable and fast.
- Configurable gram-length range allows tuning the balance between match flexibility and index overhead.
Disadvantages & Trade-offs
- Significantly increases index size compared to standard whole-word tokenization, sometimes substantially.
- Increases indexing-time computational cost, since many more tokens must be generated and written per document.
- Poorly chosen gram-length ranges can produce excessive, overly loose matching, hurting result precision.
- Not well suited for every field; applying it broadly across many large text fields “just in case” wastes resources without corresponding benefit.
N-gram tokenization is not primarily a security feature, but it has a few notable implications worth understanding.
Increased partial-match discoverability
Because n-gram tokenization deliberately makes substrings of a value independently searchable, a sensitive field indexed this way becomes discoverable through partial fragments as well as whole values, which can meaningfully widen the practical surface through which sensitive information might be inferred or located, compared to a standard whole-word analyzed field. This is a reason to apply n-gram analysis specifically to fields where partial matching is a genuine, deliberate requirement, rather than broadly across all text fields by default.
Resource consumption as an availability concern
Because indexing n-gram-analyzed content is comparatively expensive, a system that allows uncontrolled or excessively large text input into an n-gram-analyzed field can experience disproportionate indexing load compared to the same input on a standard field, which is worth factoring into capacity planning and input-size validation for any user-facing system accepting free-form text into such a field.
Apply n-gram or edge n-gram analysis selectively, only to the specific fields that genuinely need partial or autocomplete matching, and consider reasonable input-length limits on those fields to keep both index growth and indexing cost within predictable, manageable bounds.
Because n-gram tokenization’s costs are largely structural (disk size, indexing throughput), watching a few specific signals goes a long way toward catching problems early.
What to watch
- Index size per field: comparing the storage footprint of n-gram-analyzed fields against comparable standard-analyzed fields reveals the true, ongoing cost of the chosen gram-length range in production.
- Indexing throughput and latency: tracking whether documents containing n-gram-analyzed fields take noticeably longer to index than similar documents without them helps quantify the real-world indexing overhead.
- Autocomplete query latency by keystroke position: for search-as-you-type experiences, monitoring latency at each stage of a growing query (one character, two characters, and so on) helps confirm the feature remains responsive throughout.
- Field usage relative to cost: periodically confirming that an n-gram-analyzed field is genuinely being queried in ways that rely on its partial-matching capability, rather than sitting unused while still incurring its full indexing and storage cost.
Practical Habit
Before broadly applying n-gram analysis to a new field, prototype it on a representative sample of real data first and measure the actual resulting index size increase, rather than assuming the overhead will be acceptable.
Certain n-gram usage patterns are considered established best practice, and certain shortcuts consistently cause avoidable pain.
Established patterns
Edge n-gram autocomplete sub-field
A dedicated edge-n-gram-analyzed sub-field alongside the main analyzed field, used specifically to power a search-as-you-type suggestion box.
Narrow gram range for structured codes
Applying n-gram analysis with a tight min/max range to short, structured identifiers like SKUs or part numbers, where substrings genuinely matter.
Index-time vs search-time analyzer split
Using an n-gram analyzer only at index time while keeping the search-time analyzer simpler, to prevent the query itself from over-expanding into too many fragments.
Anti-patterns to avoid
Applying N-grams Broadly “Just In Case”
Adding an n-gram sub-field to every text field in a mapping, regardless of whether any real query pattern actually needs substring or autocomplete matching for that specific field.
Why It Hurts
Every added n-gram sub-field permanently increases index size and indexing cost, whether or not it is ever actually queried, making this an expensive habit with no guaranteed corresponding benefit.
Using the Same Analyzer for Both Indexing and Searching
Applying the n-gram tokenizer identically at both index time and search time without separating the two.
Why It Hurts
The query text itself also gets exploded into many overlapping fragments, often producing an overly broad, low-precision match against far more documents than genuinely intended.
A short, practical checklist distilled from how experienced Elasticsearch practitioners use n-gram tokenizers well.
| Best Practice | Why It Matters |
|---|---|
| Choose the narrowest gram-length range that satisfies the real use case. | Directly limits unnecessary index growth and indexing overhead. |
| Use edge n-grams specifically for prefix-style autocomplete, not general substring search. | Matches the tool to the actual intent, avoiding unnecessarily broad fragment generation. |
| Separate index-time and search-time analyzers. | Prevents the search query itself from being over-fragmented, keeping match precision reasonable. |
| Reserve n-gram analysis for fields with a genuine partial-match or autocomplete need. | Avoids paying ongoing storage and indexing cost for capability that is never actually used. |
| Measure real index size impact on representative data before rolling out broadly. | Surfaces the true resource cost early, before it becomes a production-scale surprise. |
Setting an unnecessarily wide maximum gram length “to be safe,” which generates a large number of long fragments that rarely, if ever, get used in genuine partial-match queries, while still incurring their full ongoing storage and indexing cost.
N-gram tokenization quietly powers many of the responsive, forgiving search experiences people interact with every day.
Search-As-You-Type Suggestions (Google-scale and e-commerce search boxes)
The familiar experience of seeing relevant suggestions appear the moment a user types even a few characters into a search box is commonly powered by edge n-gram-indexed fields, letting each partial keystroke sequence match directly against pre-built prefix fragments rather than requiring the user to finish typing a full word first.
Product Code and SKU Lookup (Amazon-scale inventory systems)
Retail and logistics platforms often need to find a product by a partial code fragment, such as when a barcode scanner returns a truncated or partially obscured value. N-gram-indexed identifier fields allow these partial fragments to be matched directly against inventory records without falling back on slow, broad wildcard scanning.
Fuzzy Name Matching (large customer support and CRM platforms)
Customer support tools that need to find a customer record from a partially remembered or slightly misspelled name commonly rely on n-gram-analyzed name fields, since overlapping character fragments remain shared between a correctly spelled name and a close misspelling, even when a standard whole-word match would fail entirely.
Key Takeaways
- An n-gram tokenizer breaks text into many small, overlapping character fragments instead of whole words, enabling substring and partial matching.
- Edge n-grams are a prefix-focused variant, generating fragments only from the start of a word, and are the standard mechanism behind search-as-you-type autocomplete.
- Fragment generation happens once at index time, which is what makes query-time substring matching fast compared to real-time wildcard scanning.
- The minimum and maximum gram-length settings directly control the trade-off between matching flexibility and index size, and should be chosen deliberately.
- Index-time and search-time analyzers are usually kept separate, so that the search query itself is not also over-fragmented.
- N-gram analysis meaningfully increases index size and indexing cost, and should be applied selectively to fields with a genuine partial-match need, not broadly by default.
- Sensitive fields indexed with n-grams become discoverable through partial fragments as well as whole values, which is worth considering when deciding where to apply this technique.