What Is Fielddata in Elasticsearch?

What Is Fielddata in Elasticsearch?

A friendly but thorough guide to the in-memory structure that lets Elasticsearch sort, aggregate and script on text, why it is switched off by default, how it can quietly exhaust your heap, and what to use instead.

Imagine a huge library with a wonderful index at the back of every book. Look up the word “volcano” and the index instantly tells you every page where it appears. That is perfect when you want to find pages. Now imagine someone asks a different question: “For page 214, list every word printed on it, in alphabetical order.” Your back-of-the-book index is suddenly the wrong tool, because it was built to go from words to pages, not from pages to words. To answer the new question quickly, you would have to flip the index upside down and keep the flipped copy on your desk.

Elasticsearch faces this exact situation every day, and the flipped copy on the desk is called fielddata. It is powerful, it is sometimes the only way to answer a certain kind of question, and it is also one of the most common reasons an Elasticsearch node runs out of memory. In this tutorial we start from zero: how Elasticsearch stores text, why sorting and aggregating need a different view of the data, what fielddata really is, how it is built, what it costs, how to watch it, and, most importantly, how to avoid needing it in the first place.

1The Big Picture: How Elasticsearch Stores and Finds Data

To understand fielddata you first need to understand the structure it is built from: the inverted index.

Documents, fields and indices

Elasticsearch stores information as documents, which are pieces of data such as a product, a blog post or a log line. Each document is made of fields, for example a title, a price and a date. A collection of similar documents is stored in an index, roughly comparable to a table in a traditional database. Elasticsearch splits each index into shards and spreads them over the nodes of a cluster, so that the work and the data are shared.

Inside each shard, the data is written into small immutable files called segments. A segment, once written, is never modified. New documents create new segments, and background merging combines small segments into larger ones. This detail will matter a great deal later, because fielddata is built one segment at a time.

The inverted index: a map from words to documents

When you store a text field such as “Quick brown fox,” Elasticsearch runs it through an analyzer, a small pipeline that breaks the text into tokens (the individual words), converts them to lowercase, and optionally removes noise words or reduces words to their roots. The result for our example might be the tokens quick, brown and fox. Elasticsearch then records, for each token, which documents contain it. This structure is the inverted index, and it is the reason full-text search is so fast.

Simple Analogy

Think of the index at the back of a school textbook. It lists words in alphabetical order and next to each word shows the page numbers where it appears. It is “inverted” because the book itself goes from pages to words, while the index goes from words to pages. If you want to know which pages mention “volcano,” the index answers in a moment.

graph LR
  subgraph Docs["Documents"]
    D1["Doc 1: quick brown fox"]
    D2["Doc 2: brown bear"]
    D3["Doc 3: quick red fox"]
  end
  subgraph Inv["Inverted index: term to documents"]
    T1["brown: Doc 1, Doc 2"]
    T2["fox: Doc 1, Doc 3"]
    T3["quick: Doc 1, Doc 3"]
    T4["bear: Doc 2"]
    T5["red: Doc 3"]
  end
  D1 --> T1
  D2 --> T1
  D1 --> T2
  D3 --> T2
  D1 --> T3
  D3 --> T3
  D2 --> T4
  D3 --> T5
        
FIG 1 — The inverted index answers “which documents contain this word?” very quickly

The question the inverted index cannot answer well

The inverted index is brilliant for searching, but it is awkward for a whole different family of questions. Sorting results by a field, counting how many documents fall into each category, computing an average, or running a script that reads a field’s value for each matching document all need the opposite direction: given a document, what value does it have in this field? Going from a document to its terms with the inverted index would mean scanning the whole term dictionary for every single document, which is far too slow.

Search engines therefore keep a second, separate view of the data organised by document. Elasticsearch has two ways to provide that view. One is stored on disk and built when documents are indexed; it is called doc values. The other is built in memory on demand by flipping the inverted index upside down; that is fielddata.

Term 1

Analyzer

The pipeline that turns raw text into tokens, usually by splitting, lowercasing and filtering.

Term 2

Inverted index

A lookup from each token to the documents that contain it. Ideal for search.

Term 3

Segment

A small, immutable chunk of a shard. Shards are made of many segments that merge over time.

Term 4

Doc values

An on-disk, document-by-document view of field values, built at index time.

Term 5

Fielddata

An in-memory, document-by-document view built at query time by uninverting the inverted index.

Term 6

Heap

The memory area of the Java Virtual Machine where Elasticsearch keeps objects such as fielddata.

2So, What Exactly Is Fielddata?

Fielddata is a temporary, in-memory structure that maps each document to the terms it contains for a particular field.

A precise definition

Fielddata is a data structure that Elasticsearch builds in the heap memory of a node by reading the inverted index of a field and turning it around, so that for each document in a segment it can quickly answer “which terms does this document have in this field?” The process of flipping the structure is called uninverting. The finished result is stored in a cache on the node and reused for later requests that need the same field.

Three words in that definition deserve attention. It is in memory, which means it competes with everything else in the heap for space. It is built at query time, which means the first request that needs it pays a noticeable cost. And it is built from the inverted index, which means that for an analyzed text field it contains the individual tokens, not the original sentence.

Simple Analogy

Suppose the back-of-the-book index lists words with their pages, but a teacher now wants a table showing each page with all the words on it. A helpful student goes through the entire index, word by word, and writes each word onto the row of every page where it appears. The finished table is very quick to consult, but it took time to create, and it needs a whole extra desk to spread out. That table is fielddata, and the desk is your heap.

What operations need it?

Fielddata is used whenever Elasticsearch has to look at a field from the document’s point of view. The main cases are sorting results by a field, running aggregations such as terms counts or cardinality estimates, and reading field values inside scripts. For most field types this job is done by doc values instead, and fielddata is never involved. It matters mostly for one field type, the analyzed text field, which cannot use doc values at all.

Sorting

To order search results by a field, Elasticsearch must know each matching document’s value for that field. Doc values or fielddata provide that value quickly.

Aggregations

Counting documents per category, finding top terms, or computing statistics all need to walk over documents and read their values, which again requires the document-to-value view.

Scripting

When a script reads a field’s value for each document, for example to compute a score or a derived value, it reads from doc values or fielddata rather than from the original source text.

graph TD
  Q["Request: sort, aggregate or script on a field"] --> C{"What type is the field?"}
  C -->|"keyword, number, date, boolean, ip"| DV["Read doc values from disk, cached by the operating system"]
  C -->|"text"| F{"Is fielddata enabled?"}
  F -->|"No, the default"| ERR["Request fails with a clear error message"]
  F -->|"Yes"| FD["Uninvert the inverted index into heap memory"]
        
FIG 2 — Which structure answers a sort or aggregation request
i
Remember This

Fielddata is not something you normally turn on or use every day. It is a fallback for one specific situation, sorting or aggregating on analyzed text. Most healthy clusters never need it at all.

3Why Text Fields Have Fielddata Turned Off

The default setting is a safety feature learned through many painful production incidents.

The default and the error message

On a text field, fielddata is disabled by default. If you try to sort, aggregate or script on such a field, Elasticsearch refuses and returns an error explaining that text fields are not optimised for operations that need per-document values. The message suggests using a keyword field instead, and mentions that you could enable fielddata on the field, but with a warning that this can use significant memory. That warning is not decoration; it reflects real experience.

This default was introduced with Elasticsearch 5.0, when the old single “string” field type was split into two distinct types, text for full-text search and keyword for exact values. Before that, string fields were analyzed by default and their fielddata could be loaded quietly on the first sort or aggregation. Many clusters ran out of memory without anyone understanding why. Splitting the types and switching fielddata off for text made the cost explicit and turned a hidden trap into a deliberate choice.

Simple Analogy

Think of a school cafeteria where the “eat as much as you like” button on the dessert machine used to be pressed by default. Everyone quickly got a stomach ache. The school removed the default and put up a sign: “You may press the button, but be warned.” Fielddata on text is now the same: allowed, but only if you press the button on purpose.

Why text fields are especially expensive

A keyword field stores one whole value per document, such as “Delhi” or “Blue.” A text field, by contrast, produces many tokens per document, and across millions of documents produces a very large dictionary of distinct terms. Uninverting it means creating structures that hold every term and connect each document to all of its terms. The more documents, the longer the text and the more varied the vocabulary, the bigger the structure becomes.

Moreover, this memory cost is paid on top of what the index already needs. The inverted index still sits on disk and in the file system cache. The fielddata copy is an extra, in-heap duplicate of the same information in a different shape. And because the heap is shared with everything else the node is doing, a single careless aggregation can push a node toward trouble.

!
Common Mistake

Many people see the error message, find a forum answer that says “just enable fielddata,” and switch it on without measuring. It makes the error vanish, but it can also move the problem from a clear error message to a slow, mysterious memory crisis some weeks later.

Off
default fielddata state on text fields
5.0
version that split text from keyword
Heap
where fielddata lives, in memory

4Fielddata Versus Doc Values

These two structures do the same job in very different ways, and the difference explains almost every practical decision.

Doc values: built early, stored on disk

Doc values are a column-oriented structure written to disk at index time, alongside the inverted index. For each field, the values are stored together, one after another, in document order. Reading the value for a document is therefore a quick, predictable lookup. Because the structure lives in files, the operating system’s file system cache keeps the hot parts in memory automatically, and the Java heap is not burdened with them. Doc values are enabled by default for almost every field type: keyword, numbers, dates, booleans, IP addresses, and more. The main exception is the analyzed text field.

Fielddata: built late, stored in memory

Fielddata takes the opposite approach. Nothing is prepared at index time. When a request first needs the structure, Elasticsearch reads the inverted index, builds the document-to-terms view, and keeps it in heap memory. The upside is flexibility, since it works on analyzed text without any extra index-time preparation. The downside is cost: a delay on first use, memory pressure, and extra pressure on garbage collection.

Simple Analogy

Doc values are like a class register that the teacher writes neatly, row by row, as each student arrives. It is stored in a filing cabinet and can be consulted at any time. Fielddata is like asking the teacher to reconstruct the register from scratch at the moment you need it, by listening to a recording of everyone announcing their names. It works, but it is slow to start and takes up the whole desk.

AspectDoc valuesFielddata
When it is builtAt index time, as documents are writtenAt query time, on first use of the field
Where it livesOn disk, cached by the operating systemIn the Java heap
Default stateOn for most field typesOff for text fields
Works on analyzed textNoYes, when enabled
First-request latencyLowHigh, because of uninverting
Memory pressure on heapLowHigh
Disk costExtra disk space per fieldNone extra, uses the existing inverted index
Best forExact values, numbers, dates, categoriesRare cases needing token-level aggregation on text
graph LR
  subgraph Index["At index time"]
    W["Document is written"] --> INV["Inverted index on disk"]
    W --> DVS["Doc values on disk (keyword, numbers, dates)"]
  end
  subgraph Query["At query time"]
    DVS --> OSC["Operating system file cache"]
    INV -->|"only if fielddata is enabled"| UNINV["Uninvert into heap"]
    UNINV --> HEAP["Fielddata cache in JVM heap"]
  end
        
FIG 3 — Doc values are prepared early on disk; fielddata is built late in memory
i
Rule of Thumb

If a field is used for sorting or aggregations, make it a type that has doc values, such as keyword. Reach for fielddata only when you truly must aggregate on the analyzed tokens of a text field, and even then, think twice.

5Text, Keyword and the Multi-Field Solution

The cleanest way to avoid fielddata is to store the same value in two shapes, one for searching and one for sorting.

Two field types for two jobs

A text field is analyzed, broken into tokens, and designed for full-text search: you can find a document by searching for a single word in a long paragraph. A keyword field is stored as one exact value, not analyzed, and is designed for filtering, sorting and aggregating. If a product name is “Red Running Shoes,” a text field lets people find it by typing “running,” while a keyword field treats the whole phrase as one unit that can be counted or alphabetised.

Type 1

Text field

Analyzed into tokens. Great for search relevance. No doc values, so sorting and aggregations need fielddata.

Type 2

Keyword field

Stored as one exact value. Has doc values by default, so sorting and aggregations are efficient.

Type 3

Multi-field

One source value indexed in several ways, such as a text version for search and a keyword version for sorting.

Type 4

Normalizer

A light-weight analyzer for keyword fields that can lowercase or clean a value while keeping it as one token.

Multi-fields: the everyday answer

A multi-field lets you index one value in more than one way. The typical pattern is a main field of type text, plus a sub-field of type keyword. You search on the main field and you sort or aggregate on the sub-field. When you let Elasticsearch create mappings dynamically for string values, it does this for you by default: a text field with a keyword sub-field, where the keyword version ignores values longer than a set number of characters, 256 by default. That is why many users see fields called something like name and name.keyword.

The sub-field costs some disk space, because the doc values are written to disk, but it costs almost nothing on the heap. That trade is nearly always worth it. You pay a little at index time and a little in storage, and you avoid the runtime memory hazards of fielddata.

Simple Analogy

A library keeps every book both on the shelf by topic, so you can browse ideas, and in a neat catalogue sorted by title, so you can look up an exact name. Keeping both costs a little extra effort when a book arrives, but saves enormous effort every time someone asks a question. The keyword sub-field is the sorted catalogue.

What about case-insensitive sorting?

A plain keyword field is case-sensitive, so “apple” and “Apple” sort in different places and count as different values. If you want them treated as one, you can attach a normalizer that lowercases the value before it is stored. The value remains a single token, so it still has doc values and needs no fielddata. This is far more predictable than sorting on analyzed tokens, which would split “New York” into two separate words.

!
Watch Out

Keyword values above the configured length limit are simply not indexed in that sub-field. If your field can hold long paragraphs, do not expect to aggregate on them. Long free text is meant for searching, not for grouping.

6How Fielddata Is Loaded and Kept

Understanding the lifecycle explains why the first request is slow and why memory can creep upward.

Lazy loading

By default, fielddata is loaded lazily. Nothing happens when a text field with fielddata enabled is first indexed. The first time a sort, aggregation or script needs it, each shard reads the relevant terms from the inverted index of each segment and builds the structure. That work uses processor time and disk reads, and the memory needed is reserved in the heap. The request that triggers it can be far slower than later ones.

1

A request arrives

A user runs an aggregation on a text field that has fielddata enabled. The shard checks the fielddata cache for that field in each segment.

2

The circuit breaker is consulted

Before loading, Elasticsearch estimates how much memory the structure will need and checks it against a safety limit. If it would exceed the limit, the request fails cleanly instead of risking the node.

3

The inverted index is uninverted

For every segment, terms are read one by one and the documents containing them are recorded, building a document-to-terms structure.

4

The result is cached

The finished structure is stored in the fielddata cache in the heap, tied to the segment it came from.

5

Later requests are fast

Subsequent requests find the structure in memory and read from it immediately, until the segment disappears or the cache is cleared or trimmed.

Segments make it a moving target

Because segments are immutable and new ones appear continuously as you index, fielddata is tracked per segment. When new documents arrive and a refresh creates a new segment, the next request must load fielddata for that new segment, while the older segments’ entries are still valid. When segments are merged, the old segments are retired and their fielddata is released, and the merged segment needs a fresh load the next time it is used. On a cluster with heavy indexing, this creates a steady background rhythm of loading and freeing.

sequenceDiagram
  participant U as User
  participant S as Shard
  participant B as Circuit breaker
  participant H as Fielddata cache in heap
  U->>S: Aggregate on text field
  S->>H: Is fielddata loaded for each segment?
  H-->>S: No
  S->>B: Estimate memory needed
  B-->>S: Within limit
  S->>S: Uninvert inverted index
  S->>H: Store structure
  S-->>U: Aggregation result (slow first time)
  U->>S: Same aggregation again
  S->>H: Loaded already
  S-->>U: Aggregation result (fast)
        
FIG 4 — First request pays the loading cost; later requests reuse the cache

Eager versus lazy

Loading on demand means users can feel the cost. Some setups prefer to pay the cost in advance, so that no user request has to wait. Elasticsearch offers a setting to build structures eagerly, when new segments become visible after a refresh, rather than waiting for the first query. Eager loading moves the cost from user requests to the refresh step. It gives smoother query latency but slows down refreshes and uses memory whether or not anyone runs the query. It suits fields that are certain to be used frequently, and it is a poor choice for fields that are rarely queried.

i
Trade-off

Lazy loading is friendly to memory but unfriendly to the first user. Eager loading is friendly to users but unfriendly to indexing speed and memory. Neither is free; choose based on how predictable your queries are.

7Inside the Machine: How Uninverting Really Works

A closer look at the loading step shows exactly why the cost grows with your data.

Step one: the term dictionary

Every segment stores, for each indexed field, a sorted list of all the distinct terms found in that field, called the term dictionary. Next to each term, the segment stores a postings list, which is simply the list of document numbers in that segment that contain the term. The term dictionary and postings lists together are the inverted index. When fielddata is built, Elasticsearch walks through this dictionary from the first term to the last, one term at a time.

Step two: filling in the document rows

For each term, the loader reads its postings list and, for every document in the list, records that this document has this term. By the end of the walk, each document has a small list of the terms it contains, the exact opposite view of the one stored on disk. Terms are kept as compact numbers pointing into a shared dictionary of the actual text, so the same word is not stored again and again for every document that has it.

Simple Analogy

Picture a teacher holding the back-of-the-book index and a blank grid with one row for each page. The teacher reads the index from A to Z. For the word “apple,” which appears on pages 3, 9 and 40, the teacher writes “apple” into the rows for pages 3, 9 and 40. After the last word, every row lists the words on that page. Longer indexes and more pages mean more writing and a bigger grid.

What decides how big the result is?

Factor 1

Number of documents

Every document in the segment needs a row, even if the row is short. More documents mean a bigger structure.

Factor 2

Number of distinct terms

Every unique word must be stored once in the shared dictionary. Rich vocabularies with many rare words cost the most.

Factor 3

Terms per document

A long paragraph contributes many tokens to its row, while a short title contributes only a few.

Factor 4

Number of segments

Each segment builds its own structure, so many small segments add overhead compared with a few large ones.

Factor 5

Analyzer choice

Analyzers that create extra tokens, such as word-fragment analyzers for autocomplete, multiply the term count dramatically.

Factor 6

Frequency filter

Filtering out very rare and very common terms can shrink the structure to a fraction of its natural size.

flowchart LR
  A["Term dictionary of a segment"] --> B["Read next term"]
  B --> C["Read postings list for that term"]
  C --> D["For each document in the list, add the term to its row"]
  D --> E{"More terms?"}
  E -->|"Yes"| B
  E -->|"No"| F["Document-to-terms structure complete and cached"]
        
FIG 5 — The uninverting loop: every term is visited, every posting is copied

Why this work cannot be skipped

Some people ask whether Elasticsearch could load only the parts needed for a particular query. In practice, an aggregation or sort usually touches a large share of the matching documents, and those documents are spread across the whole segment. Loading only a slice would mean repeating the expensive term walk many times. Doing it once for the whole segment and caching the result is the sensible engineering choice, which is why the cost is front-loaded and heavy.

!
Autocomplete Trap

Fields analyzed into word fragments, such as edge-based tokens used for type-ahead suggestions, produce a huge number of tiny tokens per word. Enabling fielddata on such a field can be many times more expensive than on a normal text field, and its buckets are meaningless fragments. Never enable it there.

8Global Ordinals: The Hidden Cousin of Fielddata

Even if you never enable fielddata on a text field, a related in-memory structure may appear when you aggregate on keyword fields.

What is an ordinal?

Comparing long strings again and again is slow. To speed up counting, Elasticsearch gives every distinct term in a segment a small whole number, an ordinal, based on its alphabetical position. The aggregation then works with these small numbers, which are cheap to compare and count, and converts them back to text only at the end when building the result.

Simple Analogy

Imagine a class of thirty students who are always called by their roll numbers instead of their full names when the teacher counts hands. Counting is quicker with “roll number 7” than with a long name. Only when announcing the winner does the teacher look up the name that goes with the number.

Why “global”?

Ordinals in one segment do not match ordinals in another, because each segment has its own list of terms. To combine results across the segments of a shard, Elasticsearch builds a global ordinals structure that gives every distinct term one number valid across all segments of the shard. Building it needs to read through the terms of all segments, so it can be expensive for fields with a large number of distinct values, and it must be rebuilt when the set of segments changes.

Global ordinals are stored in the heap and count toward the same memory accounting and circuit breaker as fielddata. That is why an aggregation on a high-cardinality keyword field, one with millions of different values, can show up in your fielddata memory statistics even though you never enabled fielddata on it.

Concept 1

Segment ordinal

A small number for each term within one segment, based on sorted order.

Concept 2

Global ordinal

A shard-wide numbering of terms that lets aggregations combine segments quickly.

Concept 3

Eager global ordinals

A setting that builds the structure at refresh time instead of at the first aggregation.

Concept 4

Cardinality

The number of distinct values in a field. High cardinality means bigger ordinals structures.

!
High-Cardinality Trap

Fields with unique or nearly unique values, such as identifiers, session tokens or full URLs, make expensive aggregation targets. If you truly need to count them, consider approximate counting or a different modelling approach rather than grouping by each individual value.

9Enabling Fielddata on Text: When and How to Think About It

Sometimes you really do need to aggregate on analyzed tokens. Here is what that means and what to watch for.

What you actually get

When fielddata is enabled on a text field, sorting and aggregating work on the analyzed tokens, not on the original sentence. If a document’s field contains “New York City,” an aggregation on that field will produce separate buckets for new, york and city, all lowercase, and probably not what most people expect when they think of counting cities. Analysis steps such as stemming, if configured, would also change the words that appear in the results.

There are legitimate uses. If you want to find the most common words in a body of text, for example the most frequent words in customer reviews, aggregating over analyzed tokens is exactly the point. But for names, categories, statuses and identifiers, tokens are the wrong unit, and a keyword field is the correct tool.

A good reason

A research team wants to explore the most common tokens across a small, bounded set of free-text survey answers, on a dedicated index where memory has been sized for it.

A poor reason

A developer saw the error message when sorting by product name, enabled fielddata on a text field with millions of documents, and moved on. Sorting by tokens gives odd results and the memory cost grows with the index.

A better answer to the poor reason

Add a keyword sub-field, ideally with a lowercase normalizer, and sort on that. It is faster, uses doc values, and sorts on the whole product name as people expect.

Controlling the size with a frequency filter

Elasticsearch lets you limit which terms are loaded into fielddata using a frequency filter. You can tell it to load only terms that appear in a certain range of documents, either as absolute counts or as fractions of the segment, and to skip small segments altogether. Very rare terms, such as typos and one-off tokens, and extremely common terms, such as filler words, are often useless for analysis yet take up a lot of memory. Filtering them out can shrink fielddata dramatically. The trade-off is that the filtered terms will not appear in your results.

Simple Analogy

When making a table of every word in the school library, you might decide to skip words that appear only once in the whole library, which are mostly typos, and also skip “the” and “and,” which appear everywhere. The table becomes much smaller and still tells you what you wanted to know.

Changing the setting on an existing field

The fielddata option on a text field is one of the few mapping properties that can be changed on an existing field, because it does not affect how data is indexed, only what happens at query time. That makes it easy to turn on, and also easy to turn on carelessly. Turning it back off does not immediately free memory already used; the cached structures stay until they are evicted or cleared.

i
Better Alternatives First

Before enabling fielddata, ask three questions. Can a keyword sub-field do this job? Can a specialised aggregation for text, such as one designed to find unusual terms in text, do it without fielddata? Can the value be computed at query time from the stored source using a runtime field? Only if all three answers are no should fielddata be considered.

10The Memory Problem: Heap, Garbage Collection and Instability

Fielddata is dangerous not because it is slow, but because it takes memory that every other part of the node also needs.

Why heap memory is precious

Elasticsearch runs on the Java Virtual Machine, which manages memory in a fixed-size area called the heap. Everything the node keeps as live objects, including caches, request buffers, the cluster state and fielddata, lives there. A well-run node keeps its heap a comfortable distance from full, because the JVM periodically runs garbage collection to reclaim unused memory. When the heap is nearly full, garbage collection runs more often and for longer, and the node can appear frozen while it is busy cleaning up.

Good practice is to set the heap to no more than about half of the machine’s memory, and below the size at which the JVM loses its compact-pointer optimisation, generally around thirty gigabytes. The rest of the memory is intentionally left to the operating system, which uses it as a file system cache. This is exactly the memory that makes doc values fast. So the two structures compete in opposite ways: doc values lean on the operating system’s cache, while fielddata eats the very heap that has been carefully limited.

Simple Analogy

Imagine a classroom desk with limited space. Your books, notebook, pencil case and lunch all have to fit on it. Fielddata is like unrolling a giant poster across the desk: everything else has to squeeze into the corner. When the desk is full, you spend all your time shuffling things around instead of working.

The chain reaction

1

Fielddata grows

Several large fields are loaded across many segments, and the fielddata cache fills a large slice of the heap.

2

Free heap shrinks

Other work, such as searches, indexing buffers and aggregation results, has less room and forces more frequent garbage collection.

3

Pauses get longer

Garbage-collection pauses stretch from milliseconds to seconds. Requests to the node slow to a crawl.

4

Health checks fail

If a pause is long enough, other nodes conclude the node is gone. It may be removed from the cluster, forcing shards to move and adding more load to the remaining nodes.

5

Cascade

The extra work on the survivors causes them to load more fielddata or run out of memory too, and the problem spreads across the cluster.

Why memory pressure hurts the whole cluster

This chain reaction shows why a single misjudged aggregation is not only that user’s problem. A node that is struggling with memory can be evicted from the cluster, and if it is also serving as the elected master, the cluster must run a new election. That is why teams often separate the master role from busy data nodes. Fielddata-heavy workloads belong on data nodes with generous heap headroom, never on the nodes that coordinate the cluster.

50%
of RAM as the upper guide for heap size
~30 GB
approximate heap ceiling to keep compact pointers
OS
cache handles doc values outside the heap

11Guard Rails: The Fielddata Circuit Breaker and Cache Size

Elasticsearch includes automatic protections that stop runaway memory use before a node falls over.

What is a circuit breaker?

In an electrical system, a circuit breaker trips when too much current flows, cutting the power to prevent a fire. In Elasticsearch, a circuit breaker estimates how much memory an operation will need, and if that would push usage above a limit, it rejects the operation with an error instead of allowing an out-of-memory failure. The rejected request fails, but the node stays healthy and continues serving everyone else.

Simple Analogy

A lift has a weight limit. When too many people step in, an alarm sounds and the doors refuse to close. It is annoying for the person who has to wait, but far better than the cable snapping.

The relevant breakers

The fielddata circuit breaker estimates the memory needed to load fielddata and rejects the request if loading would exceed its limit, which by default is a large fraction of the heap, around forty percent. It also applies a small overhead multiplier to estimates to stay on the safe side. Above it sits the parent circuit breaker, which watches total memory use across all the breakers and, in modern versions, can look at real heap usage; its default limit is much higher, around ninety-five percent of the heap. There are further breakers for request memory and in-flight data, but the fielddata breaker is the one that trips when fielddata loading is too greedy.

When a breaker trips, the error message says the data was too large, and it reports the estimated size and the limit. Seeing this message is a clear sign that a request is asking for more memory than the node can safely provide. The right response is to change the query or the mapping, not simply to raise the limit.

Guard railWhat it doesDefault behaviour
Fielddata circuit breakerRejects a fielddata load that would exceed the limitLimit around 40 percent of heap
Parent circuit breakerCaps total memory across all breakersLimit around 95 percent of heap in modern versions
Fielddata cache sizeOptionally evicts old entries when the cache reaches a set sizeUnbounded unless configured
Frequency filterLoads only terms in a chosen frequency rangeOff unless configured on the field

The cache size setting

By default the fielddata cache has no size limit; entries stay until their segment goes away or someone clears the cache. You can set a maximum size, in which case the least recently used entries are evicted when the cache is full. This may sound like a cure, but it hides a subtle trap. If the limit is smaller than the fielddata that queries actually need, entries are evicted and then reloaded again and again, an expensive cycle sometimes called thrashing. It is also important that any cache size be lower than the circuit breaker limit, or the breaker will trip before eviction can help.

ANTI-PATTERN-01 Avoid
Problem

Raising the fielddata circuit breaker limit to make a “data too large” error go away.

Why It’s Harmful

The breaker exists to protect the node. Raising it removes the protection while the underlying demand stays the same, pushing the node closer to heap exhaustion and long garbage-collection pauses.

Correct Approach

Reduce the demand: aggregate on a keyword field, add a frequency filter, narrow the query, or add nodes and heap sized for the workload.

12Estimating and Planning Fielddata Memory

Guessing is dangerous. A little measuring and a little multiplication go a long way.

There is no magic formula

The memory needed by fielddata depends on the vocabulary, the number of documents, the analyzer, the number of segments and the frequency filter. Because these factors interact, no simple formula gives a precise answer. The reliable method is empirical: load fielddata for the field in a realistic test environment with realistic data and read the memory figure from the statistics. Then scale that figure thoughtfully to production volumes.

1

Build a representative sample

Copy a realistic slice of production data, such as a few million documents with real vocabulary, into a test index that uses the same mapping and analyzers.

2

Trigger the load deliberately

Run the sort or aggregation you plan to support and read the fielddata memory from the cat or node statistics for that field.

3

Scale with care

Estimate how memory grows with data. Memory usually grows with the number of documents and, less predictably, with vocabulary. Add a generous margin, since real data is often messier than samples.

4

Multiply by copies

Every shard copy, primary or replica, that serves the request builds its own structure on its own node. Replicas therefore multiply total cluster memory use, though each node holds only its own share.

5

Compare with headroom

Check the per-node figure against the breaker limit and against the free heap left after everything else the node does. Leave room for peaks, not just averages.

Where the memory lands

Fielddata is held on the nodes that hold the shards, not on the node that received the request. If a field’s data is concentrated in a few large shards, the nodes holding them carry more of the load. If shards are spread evenly, the load is spread too. Uneven shard sizes are a common cause of one node hitting its breaker while its neighbours are calm.

Planning questionWhy it mattersWhat to check
How many documents will the field cover?Each document needs a row in every segmentIndex size projections over the retention period
How rich is the vocabulary?Distinct terms drive dictionary sizeTerms count on a sample of real data
How many shard copies serve the queries?Each copy loads independentlyShard and replica counts per node
How much heap is free at peak?Fielddata competes with everything elseHeap percentage during busiest hours
How often do segments change?New segments trigger new loadsIndexing rate, refresh interval, merge activity
Can a frequency filter be applied?May shrink memory dramaticallyWhether rare or common terms are useful
Simple Analogy

Before hiring a coach for a school trip, you count the students, count the teachers, and add the luggage. If you only guess “about thirty,” you may find on the day that fifty people turn up. Measuring a sample first is the difference between a smooth trip and a bus that cannot close its doors.

i
Practical Advice

If your estimate says fielddata would consume more than a modest slice of the fielddata breaker limit on a node, treat that as a sign to redesign, not to buy bigger machines. A keyword sub-field almost always costs less than the hardware needed to hold the equivalent fielddata.

13Fielddata, Other Caches and Query Performance

Elasticsearch has several caches, and mixing them up is a very common source of confusion.

A tour of the caches

People often use the word “cache” for any memory-based speed-up, but Elasticsearch has distinct caches with different purposes, different owners and different lifetimes. Understanding which is which helps you avoid clearing the wrong one or blaming the wrong one for a slow query.

CacheWhat it storesWhere it livesTypical use
Fielddata cacheDocument-to-terms structures and global ordinalsJVM heapSorting, aggregations and scripts on fields
Node query cacheResults of frequently used filtersJVM heap, limited to a share of the heapSpeeding up repeated filter clauses
Shard request cacheWhole results of certain searches, mostly aggregations without hitsJVM heapDashboards repeating the same request
File system cacheRaw index files, including doc valuesOperating system memory outside the heapMaking disk reads fast for everything
graph TD
  subgraph HeapArea["JVM heap: limited and precious"]
    FD["Fielddata cache"]
    QC["Node query cache"]
    RC["Shard request cache"]
    OT["Request buffers, cluster state, indexing buffers"]
  end
  subgraph OSArea["Operating system memory: outside the heap"]
    FS["File system cache: inverted index files and doc values"]
  end
        
FIG 6 — Fielddata competes for the heap; doc values live in the operating system cache

Why the difference matters for tuning

Clearing the fielddata cache does not clear the request cache, and clearing the request cache does not free fielddata. If a dashboard is slow, the cause may be a cold fielddata load, a cold file system cache after a restart, or simply a heavy query. Diagnosing correctly saves hours. A cold restart, for example, empties every cache at once, so the first queries after startup are slow for several reasons together, not only because of fielddata.

The refresh interval and eager loading

Elasticsearch makes new documents searchable by refreshing, which by default happens about once a second on active indices. Each refresh may create a new segment, and new segments need fresh structures if a query uses them. If you have chosen eager loading for global ordinals, each refresh triggers that build work. On an index receiving constant writes, that can become a heavy tax. A common compromise is to lengthen the refresh interval for indices that do not need near-real-time visibility, which reduces the number of new segments and the associated rebuild work.

Merging and read-only indices

Because fielddata and ordinals are built per segment, having fewer, larger segments reduces overhead. For indices that are no longer written to, such as yesterday’s logs, merging down to fewer segments can make later aggregations cheaper and more predictable. Combined with moving such indices to nodes with suitable resources, this is a standard pattern for time-based data.

i
Time-Based Data Tip

Hot indices that receive writes need fast refreshes and flexible memory. Older, read-only indices can be consolidated and given lighter, cheaper resources. Fielddata and ordinals for old, stable segments stay valid for as long as those segments exist, so stable data is friendlier to caches than churning data.

Symptom: slow only after a restart

Likely a mix of cold caches. The file system cache, and any fielddata or ordinals, must be rebuilt. Consider eager loading only for the most important keyword fields, and warm critical dashboards gently after restarts.

Symptom: slow at the top of every hour

Perhaps a scheduled dashboard refreshes at the same instant, causing simultaneous loads. Stagger schedules, or pre-aggregate the results it needs.

Symptom: fast for days, then suddenly slow

Possibly a merge or a batch of new segments invalidated structures on a large index, or a new query pattern started using an unloaded field.

14Monitoring Fielddata in a Live Cluster

You cannot manage what you cannot see, and Elasticsearch offers several simple views into fielddata usage.

Where to look

The cat API for fielddata shows, for each node, how much memory each field’s fielddata is using. The node statistics API reports fielddata memory in bytes and the number of evictions, both per node and optionally per field. The index statistics API gives the same picture per index. The breaker statistics section of node stats reports each breaker’s limit, its estimated current usage, and how many times it has tripped. Together these tell you which fields are large, which nodes are affected, and whether protections are being triggered.

View 1

Cat fielddata

A compact table of memory used by each field on each node. The quickest first look.

View 2

Node stats for indices

Fielddata memory size and evictions per node, with optional per-field detail.

View 3

Index stats

Fielddata usage grouped by index, useful for finding which index is responsible.

View 4

Breaker stats

Limits, current estimates and trip counts for each circuit breaker on each node.

View 5

Heap and GC metrics

Heap percentage in use and garbage-collection pause times, the ultimate symptoms.

View 6

Slow logs and query logs

Reveal which slow queries triggered heavy loading, so you can trace cause to a specific application.

What healthy looks like

On a well-designed cluster that uses keyword fields and doc values for sorting and aggregations, fielddata memory is small or close to zero for text fields, and modest for global ordinals. Evictions are rare or absent. Breaker trip counts stay at zero. Heap usage follows a steady sawtooth pattern, rising as memory is used and falling as garbage collection reclaims it, without creeping upward over days.

flowchart TD
  A["Alert: heap high or breaker tripped"] --> B["Check fielddata memory by field"]
  B --> C{"Is one field dominant?"}
  C -->|"Yes"| D["Find queries using that field"]
  C -->|"No"| E["Check other heap users: request buffers, shard count"]
  D --> F{"Is it text with fielddata enabled?"}
  F -->|"Yes"| G["Move to keyword sub-field or add frequency filter"]
  F -->|"No, keyword"| H["Check cardinality and global ordinals"]
        
FIG 7 — A simple triage path when fielddata is suspected
i
Alert on Causes

Set alerts on heap percentage, long garbage-collection pauses, breaker trips and fielddata evictions. A trip count that rises from zero is the earliest and clearest signal that something new is asking for too much memory.

15Fixing Fielddata Problems: A Practical Playbook

When memory trouble strikes, work from the gentlest fix to the most drastic one.

1

Identify the offender

Use the fielddata views to find which field and which index take the most memory, and which queries touch them.

2

Redirect the query to a keyword field

If the field has a keyword sub-field, change the application to sort or aggregate on it. This usually removes the need for fielddata entirely.

3

Add a keyword sub-field if none exists

Update the mapping to add the sub-field, then rebuild the data so existing documents populate it. This typically means reindexing into a new index, or running an update-by-query on the same index.

4

Turn fielddata off and clear the cache

Once no query depends on it, disable fielddata on the text field and clear the fielddata cache for the affected indices so memory is released at once rather than waiting for eviction.

5

Tune if fielddata is truly required

Apply a frequency filter, restrict the query to smaller time ranges or fewer indices, and give the relevant data nodes enough heap and headroom.

6

Prevent recurrence

Update index templates so new indices are created with the correct multi-field mapping, and add checks to catch fielddata being enabled by accident.

The cache-clearing step in context

Clearing the fielddata cache is a quick, targeted tool: you can clear it for one index, several indices, or specific fields. It is a good emergency measure and a good cleanup step after a mapping change. But clearing only frees memory now. If queries continue to ask for the same fielddata, the cache will simply refill. Treat cache clearing as a bandage, and treat the mapping or query change as the cure.

Why reindexing is sometimes unavoidable

Adding a new sub-field to an existing mapping affects only documents indexed after the change. Older documents will not have values in the new sub-field until they are re-processed. Reindexing to a new index with the improved mapping, then switching an alias over to it, is the cleanest approach because the switch can be almost instant for users, and the old index remains available for rollback until you are confident.

ANTI-PATTERN-02 Avoid
Problem

Enabling fielddata on a text field across all indices, through a broad template, so that any application can sort or aggregate on it.

Why It’s Harmful

It turns a hidden memory cost into a system-wide risk. Any user with access to run a query can trigger large loads, and the cost grows with every new index.

Correct Approach

Model the data properly with keyword sub-fields, keep fielddata off by default, and enable it narrowly, on specific fields and indices, only after review.

16A Worked Example: From Error Message to Healthy Cluster

Let us follow a realistic story from the first error to the final fix.

The scenario

A team runs a support-ticket search application. Each ticket has a title, a long description, a customer company name, a status and a creation date. The application shows a table of tickets that users can sort by company name, and a chart of the ten most common companies. The team maps every string as a text field, because it seemed the natural choice, and relies on dynamic mapping for the rest.

Act one: the error

A developer adds the “sort by company name” feature. The first test fails with the message saying that text fields are not optimised for sorting and that fielddata could be enabled. A colleague suggests enabling fielddata on the company field, because it “just works.” The developer applies the change to the live mapping, and the feature suddenly works. Everyone is happy, and the change is shipped.

Act two: the slow burn

Over the following weeks, ticket volume grows. The company field contains names such as “Acme Trading Private Limited,” which the analyzer splits into several lowercase tokens. The chart of top companies now shows entries such as “private,” “limited” and “trading” as the biggest “companies,” which confuses the business team. At the same time, heap usage on the data nodes creeps higher, and the monitoring dashboard shows garbage-collection pauses stretching to several seconds during busy hours.

sequenceDiagram
  participant Dev as Developer
  participant ES as Elasticsearch
  participant Ops as Operations
  Dev->>ES: Sort by company (text field)
  ES-->>Dev: Error: fielddata disabled on text
  Dev->>ES: Enable fielddata on company
  ES-->>Dev: Sort works
  Note over ES: Weeks pass, data grows, heap fills
  Ops->>ES: Alerts: long GC pauses
  ES-->>Ops: Breaker trips on some aggregations
  Ops->>ES: Investigate fielddata memory by field
  ES-->>Ops: Company field is the largest consumer
        
FIG 8 — A typical story: a quick fix that turns into a memory problem

Act three: the diagnosis

The operations engineer opens the cat fielddata view and sees that the company field dominates the fielddata memory on every data node. Node statistics show growing memory and the breaker statistics show trips. The engineer cross-checks the slow log and confirms that the sort and the top-companies chart are the queries causing the loads. The weird buckets in the chart make the modelling error obvious: the field is being aggregated as tokens rather than as whole company names.

Act four: the fix

1

Design the new mapping

Company becomes a keyword field with a lowercase normalizer for sorting and grouping, plus, if free-text search on company is required, a text sub-field for searching.

2

Create a new index and reindex

A new index is created with the corrected mapping and all tickets are copied into it, while the old index continues to serve live traffic.

3

Update the application queries

The sort and the chart now target the keyword field. The team tests both on the new index and compares results with expectations, especially the top-company chart.

4

Switch the alias

The application reads through an alias. The alias is moved from the old index to the new one in a single step, so users notice nothing except a faster, more accurate chart.

5

Clean up and confirm

After a safe waiting period, the old index is deleted, which frees its fielddata. The team confirms that fielddata memory has dropped to near zero and that pauses have disappeared.

Weeks
before the hidden cost became visible
1 field
was responsible for most of the memory
0
fielddata needed after remodelling
i
The Moral

The original error message was trying to help. It pointed at the right fix, a keyword field, and warned about the wrong one. Reading it carefully at the beginning would have saved weeks of trouble.

17A Safe Migration Checklist: From Fielddata to Keyword Fields

Changing how a field is modelled touches data, queries and people, so a checklist keeps it calm.

Before you start

Check 1

List every consumer

Find every application, dashboard, saved search and script that sorts, aggregates or scripts on the field.

Check 2

Decide the new shape

Choose keyword, text, or both, and decide about normalizers and length limits for each field involved.

Check 3

Estimate space and time

Reindexing needs enough disk for a second copy and enough time to finish without hurting live traffic.

Check 4

Confirm backups

Take a recent snapshot so that a rollback is always possible if something unexpected appears.

The migration path

1

Update the template

Change the index template first, so that any new index, such as the next rollover, is created with the correct mapping automatically.

2

Create the target index

Create a fresh index with the corrected mapping. It is empty and unused by applications until the switch.

3

Copy the data

Use the reindex feature to copy documents in batches, throttling if necessary so that live search is not slowed.

4

Verify counts and samples

Compare document counts between old and new indices, and compare results of key queries on both, including sorted lists and grouped counts.

5

Catch up on late writes

If the source index is still receiving writes, run a final incremental copy or pause writes briefly, so the new index is fully current.

6

Switch the alias

Move the alias to the new index in one atomic operation, so applications see a clean cut-over.

7

Observe and retire

Watch heap, breaker and latency metrics for a period. When confident, remove fielddata settings and delete the old index.

flowchart LR
  APP["Application uses alias"] --> ALIAS["Alias: tickets"]
  ALIAS -->|"before switch"| OLD["Old index: text with fielddata"]
  ALIAS -.->|"after atomic switch"| NEW["New index: keyword sub-fields"]
  OLD -->|"reindex copies data"| NEW
        
FIG 9 — An alias makes the cut-over invisible to applications
ANTI-PATTERN-03 Avoid
Problem

Applications that hard-code concrete index names, forcing every mapping change to become an application release.

Why It’s Harmful

A migration that could be a quiet alias switch turns into a coordinated deployment, and teams are tempted to keep a bad mapping simply to avoid the effort.

Correct Approach

Always read and write through aliases, so that the physical index behind the name can change freely.

18Troubleshooting Cheat Sheet: Symptoms, Causes and Cures

When something looks wrong, match the symptom to the most likely cause, then apply the gentlest fix.

SymptomLikely causeFirst fix to try
Error about text fields not being optimised for sorting or aggregationsSorting or aggregating on an analyzed text field without fielddataUse a keyword sub-field instead
Error saying data is too large, mentioning the fielddata breakerA fielddata or ordinals load would exceed the limitChange the query or field, not the limit
Buckets are single lowercase wordsAggregating tokens from a text fieldAggregate on the keyword version
Heap climbs steadily over daysFielddata or ordinals accumulating with data growthCheck fielddata memory by field and remodel
Long garbage-collection pausesHeap nearly full, often from cachesReduce fielddata, clear caches, check shard counts
Nodes dropping out of the cluster under loadPauses long enough to fail health checksReduce memory demand, separate roles
High fielddata evictionsCache size limit smaller than working setRemove need for fielddata, or resize deliberately
Aggregation on a keyword field is slow the first time onlyGlobal ordinals built at first useConsider eager global ordinals for that field
Sorting seems to ignore capital letters oddlyCase-sensitive keyword orderingAdd a lowercase normalizer
Aggregation returns nothing for long valuesValues exceed the keyword length limitAggregate on a shorter derived field

A calm mental checklist

When faced with a memory alarm, resist the urge to change settings at random. First identify what is using memory, using the fielddata views. Second, identify which queries cause it, using logs. Third, decide whether the queries or the mapping should change. Fourth, apply the change in a test environment and measure. Only then apply it to production. Most incidents resolve at step three, when someone realises a field is modelled for the wrong job.

!
Avoid Panic Settings

Raising heap to the maximum, disabling breakers, or restarting nodes repeatedly can make things worse or merely hide the problem. A restart clears memory but not the cause, and the same queries will simply refill it.

ANTI-PATTERN-04 Avoid
Problem

Scheduling a periodic job that clears all caches to keep memory “under control.”

Why It’s Harmful

Every clear forces the next queries to rebuild everything, causing recurring latency spikes. It treats a symptom, and it also throws away caches that were working well.

Correct Approach

Find and fix the field or query responsible for excess memory. Clear caches only as a targeted, one-off step after a mapping change.

19Design Patterns That Avoid Fielddata

The best fielddata strategy is a data model that never needs it.

Search with text, analyse with keyword

Give every descriptive string a text field for searching and a keyword sub-field for sorting and grouping. Decide which fields truly need each capability, and skip the unneeded one to save disk.

Normalised keyword fields

Attach a lowercase normalizer to keyword fields where case should not matter, such as tags and user-entered categories. Grouping and sorting then behave the way people expect.

Dedicated fields for exact identifiers

Store codes, statuses and identifiers as keyword only, not as text at all. There is no benefit to analysing a product code, and keyword fields carry doc values automatically.

Numeric and date fields for numbers and dates

Never store numbers or dates as text. Proper numeric and date types use doc values, support range queries and are compact.

Specialised aggregations for text exploration

When you want to find interesting or unusual words in a body of text, use an aggregation designed for that purpose, which analyses text without requiring fielddata on the field.

Runtime fields for occasional needs

When you need a derived value only now and then, a runtime field computes it at query time from stored source, avoiding index-time cost. It is slower per query than an indexed field, but it does not permanently consume heap or disk.

Eager global ordinals for hot keyword fields

For a keyword field that is aggregated on constantly in a read-heavy index, building global ordinals at refresh time removes the delay for the first user request. Use it selectively.

flowchart TD
  S["Need to sort or aggregate on a string"] --> Q1{"Is the value a whole label such as a name, tag or status?"}
  Q1 -->|"Yes"| K["Use a keyword field or keyword sub-field with doc values"]
  Q1 -->|"No, it is long free text"| Q2{"Need the most frequent or unusual words?"}
  Q2 -->|"Yes"| SA["Use a text-aware aggregation, no fielddata needed"]
  Q2 -->|"No"| Q3{"Need a derived value occasionally?"}
  Q3 -->|"Yes"| RF["Use a runtime field"]
  Q3 -->|"No"| FD["Last resort: fielddata with a frequency filter and monitoring"]
        
FIG 10 — Decision path: choosing the right tool before touching fielddata
i
Index Templates Are Your Friend

Put your mapping decisions into index templates, so every new index is created the right way. Reviewing a template once is far easier than repairing mappings across hundreds of indices later.

20More Anti-Patterns and Mistakes to Recognise

These habits show up again and again in troubled clusters.

ANTI-PATTERN-05 Avoid
Problem

Aggregating on a text field with fielddata and expecting whole values, such as full names or cities, in the buckets.

Why It’s Harmful

The buckets contain individual lowercase tokens, so “New York” becomes two separate entries. Results look wrong, and the team spends time debugging a problem that is really a modelling error.

Correct Approach

Aggregate on a keyword sub-field, which keeps each value whole.

ANTI-PATTERN-06 Avoid
Problem

Disabling doc values on fields “to save disk” without checking whether any query will sort, aggregate or script on them later.

Why It’s Harmful

A field without doc values cannot be sorted or aggregated efficiently. If the requirement appears later, the only fix is reindexing, and a hurried workaround may involve fielddata or heavy scripts.

Correct Approach

Disable doc values only on fields that are certain to be used purely for searching or retrieval, and document the decision.

ANTI-PATTERN-07 Avoid
Problem

Running large aggregations across long time ranges and every index at once, with no limits on the number of terms or buckets.

Why It’s Harmful

Each shard must load supporting structures and hold partial results in memory. Combined, these can exhaust heap even when no single field looks unreasonable.

Correct Approach

Narrow queries by time range and index, cap the number of returned buckets, and pre-aggregate data for dashboards that repeat the same heavy question.

ANTI-PATTERN-08 Avoid
Problem

Running with far too many small shards, each of which carries its own segments and its own fielddata or ordinals structures.

Why It’s Harmful

Per-shard overhead multiplies. Even modest fielddata per segment adds up across thousands of shards, and the heap is quietly drained.

Correct Approach

Size shards sensibly, use lifecycle policies to roll over and consolidate old data, and avoid creating a new index per tiny tenant or per day when volumes are small.

“Every byte of fielddata is a byte the rest of your node cannot use.”

21Security and Operational Considerations

Memory-heavy features are also an availability risk, and availability is part of security.

Resource abuse as a risk

Anyone who can run aggregations on a field with heavy memory needs can, deliberately or accidentally, force nodes to load large structures. In a shared cluster, this makes fielddata-enabled fields a route for one team’s queries to degrade everybody else’s service. Restricting which roles can query which indices, and which fields are exposed, reduces the surface area. Circuit breakers help, but they are a last line of defence rather than a substitute for access control and good modelling.

Exposure of token-level content

Enabling fielddata on a text field makes it possible to list the individual tokens found in that field, along with counts. Depending on the content, such tokens could reveal sensitive words, names or fragments. Field-level and document-level security rules still apply in a secured cluster, but you should think about whether allowing token-level aggregation on a field is appropriate before enabling it, especially for fields containing personal or confidential text.

Operational discipline

Practice 1

Review mapping changes

Treat enabling fielddata like a change that needs review, with a written reason and a memory estimate.

Practice 2

Load test before launch

Run realistic queries against realistic data volumes on a staging cluster and watch the heap.

Practice 3

Separate workloads

Put heavy analytical workloads on their own nodes or clusters, so they cannot harm user-facing search.

Practice 4

Set query limits

Use bucket limits, timeouts and sensible defaults in applications to bound the cost of any single request.

!
Do Not Forget

Fielddata memory persists after the query that created it ends. A single expensive query can leave a large footprint that lasts until the segment is gone or the cache is cleared, so the harm is not limited to the moment of the request.

22Fielddata in Managed, Cloud and Container Environments

Running Elasticsearch as a service or on containers changes who presses the buttons, not the physics of memory.

Managed services

Managed offerings, whether from Elastic or from cloud providers, take care of provisioning nodes, configuring the heap and applying upgrades. They do not, however, change how a mapping behaves. A text field with fielddata enabled will consume heap on a managed cluster exactly as it would on your own hardware. Managed services often include monitoring dashboards that show heap use, garbage collection and circuit breaker trips, which are precisely the signals that reveal fielddata trouble, so it pays to learn to read them.

A managed cluster’s instance sizes are often tied to heap sizes, which means that solving a memory problem by moving to a bigger instance has a direct and recurring cost. Since remodelling a field is a one-time effort, while larger instances are billed month after month, fixing the mapping is usually the cheaper path.

Containers and Kubernetes

When Elasticsearch runs in containers, the heap must fit inside the container’s memory limit, with room left over for the operating system’s file cache and other overheads. If the limit is too tight, the container may be killed by the platform when memory rises, which looks like a sudden crash. Because doc values rely on the file system cache, starving the container of non-heap memory quietly slows every aggregation even when fielddata is not in use.

Env 1

Self-managed servers

You control heap and hardware. Follow the half-of-RAM guidance and keep room for the file system cache.

Env 2

Managed cloud services

Heap is set for you by instance type. Monitor breaker trips and pause times, and remodel rather than upsizing blindly.

Env 3

Kubernetes

Set memory requests and limits with headroom above the heap, and avoid overcommitting nodes that host Elasticsearch pods.

Env 4

Local development

Small datasets hide the problem. Do not trust a laptop test to reveal production memory behaviour.

Tiered storage and node roles

Many clusters use tiers: hot nodes for fresh, busy data, warm and cold nodes for older data. Putting heavy aggregation workloads on the tier whose nodes have the most heap headroom, and keeping master-eligible nodes free of such work, is a sound structural choice. Data that is rarely queried should not be forced into memory-hungry structures at all, and the simplest way to ensure that is to avoid fielddata on it.

i
Budget Insight

Memory is the most expensive resource in most Elasticsearch deployments. Every gigabyte of heap spent holding fielddata is a gigabyte not available for real work, and, in a paid cloud environment, a visible line on the bill.

23Advantages, Disadvantages and Trade-offs

Fielddata is a tool with a narrow sweet spot. Here is the balanced view.

Advantages

  • Makes sorting and aggregation possible on analyzed text without changing the mapping
  • Requires no extra disk space and no work at index time
  • Can be enabled or disabled on an existing text field without reindexing
  • Very fast once loaded, because everything is in memory
  • Frequency filters let you load only the useful subset of terms

Disadvantages / Trade-offs

  • Consumes heap memory that all other node work also needs
  • The first request pays a large loading cost
  • Results are token-based, which often surprises users
  • Can trigger long garbage-collection pauses and node instability
  • Memory is retained after the request and grows with data volume
  • Better alternatives exist for nearly every common use case

Comparing the ways to get a document-to-value view

ApproachCost paidBest used for
Keyword field with doc valuesExtra disk at index timeSorting, grouping and filtering on whole values
Text field with fielddataHeap memory at query timeToken-level aggregation on a bounded dataset
Runtime fieldCPU at query timeOccasional derived values, exploration
Text-aware aggregation for significant termsCPU at query time on a sampleFinding unusual words in a set of results
Pre-aggregation or rollup at ingestExtra processing at ingestDashboards that repeat the same heavy question
i
Balanced View

Fielddata is not evil. It is a legitimate feature with a clear purpose. The mistake is using it as a default rather than as a deliberate, measured choice with a plan for monitoring.

24Real-World and Industry Examples

Here is how the ideas play out in typical production settings.

E-commerce catalogue

An online store lets shoppers search product titles and also filter by brand and sort by name. The title is a text field for searching, while the brand and a sortable version of the title are keyword fields. Nothing in the system needs fielddata, and heap usage stays flat as the catalogue grows.

Centralised logging

A platform team stores millions of log lines per hour. The message is a text field for searching, while service name, log level and host are keyword fields for dashboards. A recurring dashboard that once grouped by a text field caused heap alarms until it was rewritten to use keyword fields.

Customer feedback analysis

A product team wants the most common words in free-text reviews for a quarter. They use a specialised text aggregation on a filtered subset, rather than enabling fielddata on the whole review field for every index.

Security analytics

Security teams aggregate on fields such as user names, IP addresses and event types. These are modelled as keyword and IP fields with doc values, giving fast aggregations without large heap costs, which matters when investigations run heavy queries during incidents.

Migration from old versions

A company upgrading from a very old release finds that dashboards depended on analyzed string fields being aggregated directly. During the upgrade, they add keyword sub-fields, reindex, and update the dashboards. Afterwards, the clusters use less heap and behave more predictably.

The lesson across all these examples

In each case, the healthy design separates the two jobs of a string: being found, and being grouped or ordered. Text fields do the first job, and keyword fields do the second. Whenever a system tries to make one field do both jobs through fielddata, it pays in memory. Whenever it models both jobs explicitly, it pays a small, predictable disk cost instead.

25Common Myths About Fielddata

A few persistent misunderstandings cause a surprising share of the trouble, so let us clear them up.

Myth: “Fielddata is what makes aggregations work in Elasticsearch.”

Reality: for nearly all field types, aggregations run on doc values, not fielddata. Fielddata is only relevant for analyzed text fields where it has been deliberately enabled.

Myth: “Enabling fielddata is a harmless setting change.”

Reality: it changes nothing until queries use it, and then it can consume large amounts of heap that stay allocated. The harm is delayed, which is exactly why it is so easy to underestimate.

Myth: “A bigger fielddata cache size makes things faster.”

Reality: by default the cache is unbounded. A size limit only causes eviction. Speed comes from having the structure loaded, not from configuring a larger limit.

Myth: “Keyword sub-fields double my memory usage.”

Reality: they add disk space and some index-time work, but their doc values are read through the operating system cache, not the heap. They typically cost far less memory than fielddata would.

Myth: “Turning fielddata off frees memory instantly.”

Reality: memory is released when segments go away, entries are evicted or the cache is cleared. Turning the setting off only prevents new loads.

Myth: “If the breaker trips, the node is broken.”

Reality: the breaker doing its job means the node is protected. The failed request is the price of keeping everything else alive. The right response is to reduce demand.

Myth: “More RAM always fixes fielddata problems.”

Reality: heap size has a practical ceiling, and bigger heaps can bring longer garbage-collection pauses. Remodelling data is usually more effective than adding memory.

“Most fielddata problems are modelling problems wearing a memory costume.”

26How This Topic Evolved Across Versions

A short history explains why so much older advice online looks different from current practice.

1

Early releases

String fields were analyzed by default, and fielddata was the main way to sort and aggregate. Memory problems were a leading cause of cluster instability.

2

Doc values arrive

Doc values were introduced as an optional, on-disk alternative, letting the operating system cache do the work instead of the heap.

3

Doc values become the default

In the 2.x series, doc values were turned on by default for fields that are not analyzed, making the safer path the automatic one.

4

Text and keyword split

Version 5.0 introduced separate text and keyword types and disabled fielddata on text fields by default, making the memory cost a deliberate choice.

5

Better protections and tools

Later releases improved circuit breakers, including memory-aware parent breakers, and added runtime fields and text-aware aggregations, giving users more ways to avoid fielddata.

!
Beware Old Advice

Many blog posts and forum answers were written for versions where fielddata was on by default. Advice such as “just increase the fielddata cache” or “warm the fielddata at startup” belongs to that era. Always check which version an answer was written for before following it.

27Frequently Asked Questions

Short answers to the questions people ask most often about fielddata.

Q1What is fielddata in one sentence?

It is an in-memory, document-to-terms structure that Elasticsearch builds by flipping the inverted index of a field, so that sorting, aggregations and scripts can read each document’s values quickly.

Q2Why does Elasticsearch say text fields are not optimised for sorting and aggregations?

Because analyzed text fields have no doc values, so the only way to sort or aggregate on them is fielddata, which lives in the heap and can consume a lot of memory. The message nudges you toward a keyword field.

Q3Is fielddata used for keyword fields?

Keyword fields use doc values for sorting and aggregations, not classic fielddata. However, aggregations on keyword fields can build global ordinals in the heap, which are accounted for alongside fielddata in memory statistics.

Q4Should I enable fielddata to fix the error message?

Usually not. First try a keyword sub-field, which is the intended solution for whole-value sorting and grouping. Enable fielddata only when you really need token-level aggregation and have planned for the memory.

Q5Why do my aggregation buckets show single lowercase words?

Because fielddata on a text field contains analyzed tokens. The analyzer split and lowercased your text, so the buckets are tokens rather than original phrases. Aggregate on a keyword field to get whole values.

Q6How do I see how much memory fielddata is using?

Use the cat fielddata API for a quick table, the node or index statistics for exact numbers and evictions, and the breaker statistics to see limits and trips. Combine these with heap and garbage-collection metrics.

Q7Does turning fielddata off free the memory immediately?

No. Already loaded structures stay in the cache until they are evicted, their segments are removed, or you clear the cache. After a mapping change, clear the fielddata cache to release memory promptly.

Q8What does the fielddata circuit breaker do?

It estimates the memory a fielddata load would need and rejects the request if the total would exceed its limit, protecting the node from running out of heap. The failed request gets an error, but the node stays up.

Q9Is it safe to limit the fielddata cache size?

It can help bound memory, but if the limit is smaller than the working set, entries are evicted and reloaded repeatedly, hurting performance. Any limit should also sit below the circuit breaker limit so eviction can act before the breaker trips.

Q10What is the difference between fielddata and doc values in one line?

Doc values are built at index time and stored on disk for most field types, while fielddata is built at query time in memory, mainly for analyzed text fields.

Q11Are global ordinals the same as fielddata?

They are different structures, but they live in the same in-memory accounting. Global ordinals speed up aggregations on keyword-like fields, and their size depends on how many distinct values the field has.

Q12Can I use fielddata to sort by a text field in a sensible way?

Sorting on a text field with fielddata orders documents by tokens, which rarely matches what people expect for names or titles. A keyword sub-field, possibly with a lowercase normalizer, gives predictable whole-value ordering.

Q13How do I find words that stand out in a set of text results without fielddata?

Use an aggregation designed for significant terms in text. It analyses the text of matching documents on the fly and highlights unusually frequent words, without requiring fielddata on the field.

28Summary and Key Takeaways

Fielddata is the in-memory, document-oriented view that Elasticsearch can build by flipping the inverted index of an analyzed text field. It exists because the inverted index answers “which documents contain this word” brilliantly but cannot answer “what does this document contain” without help. Since version 5.0 it has been disabled on text fields by default, because loading it consumes heap, delays the first request, produces token-level results that surprise users, and can push a node into long garbage-collection pauses and even out of the cluster. The dependable way to sort and aggregate on strings is to give them a keyword sub-field with doc values, leaving fielddata as a rare, monitored fallback. Understand the alternatives, watch the memory, respect the circuit breakers, and your cluster will spend its heap on serving users, not on flipping indexes.

Key Takeaways

  • Fielddata flips the inverted index — it builds a document-to-terms structure in heap memory, at query time, so sorting, aggregations and scripts can read each document’s values.
  • It is off by default on text fields — because it is costly in memory and produces token-level results; the error message is a safety feature, not an obstacle.
  • Doc values are the preferred path — built at index time and stored on disk, they serve keyword, numeric, date and similar fields without burdening the heap.
  • Use a keyword sub-field — search on the text field, sort and aggregate on the keyword version, and add a lowercase normalizer when case should not matter.
  • Memory pressure is the real danger — large fielddata leads to long garbage-collection pauses, evicted nodes and cluster-wide instability, so treat it as an availability risk.
  • Use the guard rails and watch the numbers — the fielddata and parent circuit breakers, cache size limits, frequency filters, and the cat, node and breaker statistics all help; never fix a breaker trip by simply raising the limit.
  • Prefer better alternatives first — keyword fields, text-aware significant-term aggregations, runtime fields and pre-aggregation solve most needs, and index templates keep good modelling consistent across every new index.