What Is Async Search in Elasticsearch?

What Is Async Search in Elasticsearch?

A complete, beginner-friendly guide to running slow, heavy searches in the background: how you submit them, watch their progress, read partial results, fetch the final answer later, and clean up after yourself.

Imagine you order a huge, freshly baked pizza for a class party. You could stand at the counter, staring at the oven for twenty minutes, unable to do anything else, and hoping nobody closes the shop before it is ready. Or the shop could hand you a numbered ticket, let you sit down, and tell you, “Come back whenever you like, show this ticket, and we will tell you whether it is done. In the meantime, here is a first slice so you can taste how it is going.” The second way is far more comfortable, and it is exactly the idea behind async search.

Most Elasticsearch searches finish in a few milliseconds, so waiting at the counter is fine. But some searches, such as one that crunches months of logs across hundreds of shards, or one that reaches into slow, cheap storage for old data, can take many seconds or even minutes. For those, holding a connection open and hoping for the best is fragile and unfriendly. In this tutorial we start from the very beginning and build up to a full understanding of async search: what problem it solves, how its four operations work, what the fields in its responses mean, what it costs your cluster, how to secure and monitor it, and how to avoid the classic mistakes.

1The Big Picture: How a Normal Search Works

Before we can appreciate the background version, we need to understand what happens when you run an ordinary search.

Clusters, shards and the search request

Elasticsearch stores documents in indices, and each index is divided into shards, which are smaller pieces that can live on different machines called nodes. When you send a search request, one node receives it and becomes the coordinating node for that request. It works out which shards must be asked, sends the query to each of them, and waits for their answers. Each shard searches its own data and returns its best results. The coordinating node then merges all these partial answers into one combined result and sends it back to you.

This two-step dance, ask every shard and then merge, is often called scatter and gather. The important thing for us is the waiting. The coordinating node cannot answer you until every shard has replied, or until the request runs out of time. If one shard is slow, everybody waits for that shard. The client, meanwhile, keeps its connection open the whole time, holding a line until the answer arrives.

Simple Analogy

Think of a teacher asking each of thirty students to count the red marbles in their own bag and report back. The teacher writes down each number and adds them up at the end. If twenty-nine students answer in five seconds but one student has a giant bag and needs two minutes, the teacher cannot announce the final total until that last student finishes.

sequenceDiagram
  participant C as Client
  participant N as Coordinating node
  participant S1 as Shard 1
  participant S2 as Shard 2
  participant S3 as Shard 3
  C->>N: Search request (connection held open)
  N->>S1: Run query
  N->>S2: Run query
  N->>S3: Run query
  S1-->>N: Results
  S2-->>N: Results
  S3-->>N: Results (slowest)
  N-->>C: Merged final result
        
FIG 1 — A normal search: the client waits for the slowest shard

Where the time goes

The time a search takes depends on several things: how many shards are involved, how much data each holds, how complicated the query is, whether aggregations must be computed, and how fast the underlying storage is. A simple lookup on a small index is instantaneous. A wide aggregation over a year of data spread across hundreds of shards is a different story, and the work adds up quickly.

Term 1

Coordinating node

The node that receives a search request, fans it out to shards, and merges the answers.

Term 2

Shard

A slice of an index that holds part of the data and can be searched on its own.

Term 3

Aggregation

A calculation over many documents, such as counts per category or averages per day.

Term 4

Reduce phase

The step in which the coordinating node merges shard-level results into one combined result.

Term 5

Timeout

A limit on how long something is allowed to take before it is cut short or abandoned.

Term 6

Search task

The running unit of work that Elasticsearch tracks internally for each search.

i
Good to Know

Even in a normal search, Elasticsearch can give you a partial answer if you set a search timeout, returning whatever the shards produced in time and marking the response as timed out. Async search takes the idea much further, as we will see.

2The Problem: Why Slow Searches Hurt

A slow search is not just an inconvenience. It creates a chain of small problems that all trace back to one long wait.

Long-held connections are fragile

When a client waits for a long search, a connection stays open between the client and Elasticsearch, and often through several other machines in between, such as load balancers, reverse proxies and API gateways. Each of these middle machines usually has its own idle timeout, commonly somewhere between thirty and sixty seconds. If your search takes longer, one of them may cut the connection, and you receive a gateway error even though Elasticsearch is still happily working on your request.

Mobile networks, office Wi-Fi and laptops that go to sleep add more ways for a connection to break. When it breaks, the client has no answer and no way to get one, even if the cluster finishes the work moments later. All that effort is wasted, and the user must start again, making the cluster do the same heavy work a second time.

The user experience suffers

People are patient with a progress bar and impatient with a frozen screen. A dashboard that shows nothing for forty seconds and then either loads or errors out feels broken. A dashboard that shows a bar creeping forward, along with early numbers that keep improving, feels alive. The difference is not the total time; it is whether the user is kept informed.

Simple Analogy

Compare two delivery apps. One shows a blank screen after you order and gives you your food, or an error, thirty minutes later. The other shows “order received, cooking, on the way” with a map. The food takes the same time in both cases, but the second app keeps you calm, and if you close the app and reopen it, your order is still there.

Slow storage and huge data make it worse

Modern deployments often keep recent data on fast machines and older data on slower, cheaper storage, sometimes even on object storage in the cloud. Searching such data can take much longer, because bytes must be fetched from far away before they can be examined. Users still want to search it, since investigations often need to look back months or years, but they cannot reasonably be asked to wait on an open connection for minutes.

Security investigations

An analyst hunts through half a year of network logs for a suspicious address. The search is inevitably heavy, and the analyst wants early hints while it runs.

Business reporting

A finance dashboard computes totals over several years of transactions. It runs rarely but is expensive, and the person who launched it may switch to another task while it runs.

Cross-cluster searches

A search spans clusters in several regions, and the slowest region dictates the total time, with network delays in the mix.

30-60s
typical idle timeout on proxies and gateways
1
broken connection can waste the entire search
2x
work done if the user must retry from scratch
!
Common Mistake

Some teams respond to timeouts by simply raising every timeout in the chain to five or ten minutes. This helps only a little, keeps precious connections busy, and does nothing for the user who is staring at a blank screen. A better answer is to change the interaction pattern itself.

3What Is Async Search?

Async search lets you start a search, stop waiting for it, and come back later for the answer.

A precise definition

Async search is a feature of Elasticsearch that lets a client submit a search request and get control back immediately, without holding the connection open until the search finishes. The search keeps running inside the cluster. Elasticsearch gives the client an identifier for the running search, and the client can use that identifier to check progress, read partial results while the search is still running, fetch the final result once it completes, and finally delete the search when it is no longer needed.

The word “async” is short for asynchronous, which means “not happening at the same moment.” In a normal search, asking and answering happen in one continuous exchange. In async search, asking and answering are separated in time. You ask now, and you collect the answer whenever it suits you, as long as you do it before the stored result expires.

Simple Analogy

Async search is like leaving a shirt at a dry cleaner. You hand it over, get a numbered slip, and go about your day. You can phone to ask “is it ready yet?” using the slip number. When it is ready, you collect it. If you forget to collect it for a long time, the shop eventually throws the slip away and the shirt is gone.

The three big ideas

Idea 1

Detach

The search no longer depends on your open connection. It runs on its own inside the cluster until it finishes or is cancelled.

Idea 2

Observe

You can look at progress and even partial results while the search is still running, which lets a user interface feel alive.

Idea 3

Retrieve later

The final result can be stored for a chosen period and fetched using an identifier, even from a different connection.

What async search is not

It is very important to understand that async search does not make a search faster. The same shards do the same work, using the same amount of processing time and memory. What changes is how the client and the cluster communicate about that work. It is a change in the conversation, not a shortcut through the data. If a search takes two minutes normally, it will take about two minutes as an async search too, but you will not have to stand still for those two minutes.

graph LR
  A["Client submits search"] --> B["Cluster starts work and returns an id"]
  B --> C["Client does other things"]
  B --> D["Search keeps running in the cluster"]
  C --> E["Client checks progress with the id"]
  D --> F["Result stored for a limited time"]
  E --> G["Client fetches result when ready"]
  F --> G
        
FIG 2 — Async search separates asking from answering
i
Key Insight

Async search gives you three superpowers: you can walk away, you can peek at early results, and you can pick up the answer later. It gives you no speed-up, and it does not remove the cost of heavy queries.

4The Four Operations of the Async Search API

The whole feature is built from four simple operations. Learn these and you understand the entire API.

Submit, get, status and delete

The async search API is a small family of operations. Submitting starts a search and looks very much like the ordinary search request, sent to an async search endpoint under the target index, and it accepts the same kind of query body. Getting fetches the current state and results of a previously submitted search by its identifier. Status returns only the lightweight state of the search, without the results. Deleting removes the search, cancelling it if it is still running, and discarding any stored result.

OperationEndpoint ideaWhat it doesWhen you use it
SubmitPOST to the async search endpoint, optionally under an index nameStarts the search and returns early with an id if still runningOnce, to begin
GetGET on the async search endpoint with an idReturns current state, partial or final results, and can extend the lifetimeTo read progress or the final answer
StatusGET on the async search status endpoint with an idReturns running state and shard progress, but no resultsTo poll cheaply
DeleteDELETE on the async search endpoint with an idCancels a running search and removes any stored resultWhen finished or abandoned
Simple Analogy

Back to the dry cleaner: submit is handing in the shirt, get is collecting it, status is phoning to ask whether it is ready, and delete is telling the shop “I no longer need this, you can throw it away.”

Why a separate status operation?

The get operation returns the whole response, which may contain large lists of hits and complicated aggregation results. If you just want to know whether the search has finished, fetching all that is wasteful. The status operation returns only a small summary: whether the search is still running, whether the result is partial, when it started, when it will expire, how many shards have finished, and, once complete, a completion code. It is meant for polling, the polite repeated checking that a client does while waiting.

The identifier

The submit operation returns an identifier, a long, opaque string. You should treat it as a handle that you pass back unchanged, without trying to read anything into its contents. The identifier is only returned if the search is still running when the submit call returns, or if you asked Elasticsearch to keep the result even when the search completes quickly. If the search finishes fast and you did not ask for storage, there is nothing left to point to, and no identifier is returned at all.

Handle 1

The id

A token used to refer to a running or stored search. Keep it safe and pass it back exactly as received.

Handle 2

The expiry time

The moment after which Elasticsearch will delete the search and its result, reported in every response.

Handle 3

The running flag

A simple true or false telling you whether work is still in progress inside the cluster.

Handle 4

The partial flag

Tells you whether the results you are looking at are incomplete or final.

i
Design Note

Many other Elasticsearch features that can run long, such as event query language searches and SQL queries, have their own asynchronous variants that follow the same submit, check, fetch and delete pattern, so learning it once pays off several times.

5The Life of an Async Search, Step by Step

Let us follow a single async search from birth to cleanup so that every moving part has a place in your mind.

1

The client submits

The client sends the query to the submit endpoint, along with a small wait time, saying “give me the answer if you can within this time, otherwise hand me a ticket.”

2

The cluster starts the search

The coordinating node creates a search task, contacts the relevant shards and begins collecting their answers exactly as in a normal search.

3

The wait window closes

If the search finishes inside the wait window, the complete result is returned straight away. If not, Elasticsearch returns whatever it has so far, with a running flag set and an identifier.

4

Work continues in the background

The connection is now free. As shards report in, the coordinating node periodically merges batches of shard results, keeping an up-to-date partial result available.

5

The client checks in

Using the identifier, the client polls the status endpoint, or asks for the current result, and shows progress or early numbers to the user.

6

The search completes

Once every shard has answered, or failed, the final merge happens. The complete result is stored so that it can be fetched, at least until its expiry time.

7

The client fetches and cleans up

The client retrieves the final result and then deletes the search. If it forgets, Elasticsearch removes the search automatically after the expiry time.

sequenceDiagram
  participant C as Client
  participant N as Coordinating node
  participant S as Shards
  C->>N: Submit search (wait up to a short time)
  N->>S: Run query on all shards
  Note over C,N: Wait window ends, search still running
  N-->>C: Id, running flag, partial result
  S-->>N: Shard results arrive over time
  C->>N: Status check with id
  N-->>C: Still running, 40 of 100 shards done
  C->>N: Status check with id
  N-->>C: Completed
  C->>N: Get result with id
  N-->>C: Final result
  C->>N: Delete search with id
  N-->>C: Acknowledged
        
FIG 3 — The full life of an async search: submit, poll, fetch, delete
i
The Happy Shortcut

If the search completes within the wait window, and you did not ask to keep the result, everything happens in one round trip, just like a normal search. Async search does not force you into the long path for quick queries.

6The Three Key Settings on Submit

Three settings decide almost everything about how an async search behaves. Get comfortable with them.

Wait for completion timeout

This setting says how long the submit call should wait for the search to finish before returning. Its default is a very short time, about one second. If the search finishes within that time, you get the full result immediately. If not, the call returns anyway, with an identifier and whatever partial result is available. Raising it makes fast-ish searches behave like ordinary ones, while lowering it makes the call hand back a ticket almost instantly.

Keep on completion

By default, Elasticsearch stores a search result only if the search is still running when the submit call returns. If the search finishes inside the wait window, the result is returned directly and nothing is stored. Setting keep on completion to true changes this: the result is stored even when the search finishes within the window, so that it can be fetched again later using its identifier. This is useful when a user might reload a page and expect to see the same result.

Keep alive

This is the lifetime of the stored search. After the keep alive period passes, Elasticsearch will delete the search and its result. The default is several days, which is generous. You can shorten it to save space, or extend it when you fetch a result, for example if a user is still looking at a report. Think of it as the number of days the dry cleaner promises to keep your shirt on the rack.

SituationWait windowKeep on completionWhat you get
Search finishes quicklyNot exceededFalse (default)Full result immediately, nothing stored, no id
Search finishes quicklyNot exceededTrueFull result immediately, plus a stored copy and an id
Search is slowExceededEitherPartial result now, an id, and the final result stored on completion
Search fails quicklyNot exceededFalse (default)Error returned directly
Search is slow and later failsExceededEitherId returned; failure information is available when you fetch
~1s
default wait before returning a partial result
Off
default for keeping results of fast searches
Days
default lifetime of a stored search
Simple Analogy

The wait window is how long the shop clerk will let you stand at the counter before handing you a slip. Keep on completion is you asking, “Even if it is done at once, please keep a copy in case I lose mine.” Keep alive is how long the shop promises to hold your order.

!
Common Mistake

Leaving keep alive at its long default for thousands of searches that nobody will ever fetch again quietly fills a system index with stored results. Set the lifetime to match how long the answer is truly useful, and delete results when you are done.

7Reading the Response: Every Field Explained

An async search response is a normal search response wrapped in a small envelope. Understanding the envelope is the key.

The envelope fields

Field 1

id

The identifier of the search. Present when the search is still running or has been stored.

Field 2

is_running

True while shards are still being searched, false once the search has finished, failed or been cancelled.

Field 3

is_partial

While running, always true. After completion, it tells you whether the search failed or was successful on all shards.

Field 4

start_time_in_millis

When the search started, as a timestamp in milliseconds since the beginning of 1970.

Field 5

expiration_time_in_millis

When the search and its result will be automatically deleted, unless the lifetime is extended.

Field 6

response

The familiar search response body, with hits, aggregations and shard information, possibly partial.

The shard progress counters

Inside the response body, a section about shards reports the total number of shards involved, how many have successfully answered, how many were skipped because they could not possibly match, and how many failed. While the search runs, the successful count climbs toward the total. This gives a natural progress measure: forty successful shards out of a hundred means roughly forty percent of the shards have answered, though it is not a precise percentage of time remaining, because shards differ in size and speed.

Simple Analogy

Imagine a teacher collecting homework from a hundred students. “Forty handed in” is a helpful progress note. It does not tell you when the last ones will finish, since some students have short assignments and others have long ones, but it does tell you how far along the pile is.

What the partial flag really means

The partial flag is easy to misread. While the search is still running, the flag is always true, because you are looking at an incomplete picture. Once the search has finished, the flag has a second meaning: it is false if the search succeeded on all shards, and true if it failed or some shards could not be searched. This means a finished search with the partial flag set to true is a warning sign. It tells you that the results may not represent all your data, and you should look at the shard failure information before trusting them.

is_runningis_partialMeaning
truetrueStill working. What you see is a snapshot in progress
falsefalseFinished and succeeded on all shards. Safe to treat as final
falsetrueFinished, but failed or missed some shards. Inspect failures before trusting
!
Never Skip This Check

A user interface that shows numbers as final whenever the running flag turns false, without looking at the partial flag and the shard failure counts, can present incomplete data as if it were complete. In reports and audits, that can be a serious error.

8Partial Results and Progressive Aggregations

One of the nicest features of async search is that early answers arrive while the rest is still being computed.

How partial results are built

As shard answers arrive at the coordinating node, they are not merged all at once at the very end. Instead, the coordinating node merges them in batches. The number of shard results merged at a time is controlled by a setting called batched reduce size, with a default of five. Each time a batch is merged, the running combined result is updated, and that updated result is what a client sees when it asks for the current state.

This has a second benefit that has nothing to do with progress bars: merging in batches keeps memory use under control on the coordinating node. Holding hundreds of full shard results at once before merging can consume a lot of memory, whereas merging as you go lets earlier pieces be released.

Simple Analogy

Imagine adding up a hundred bags of marbles. You could wait for all hundred to arrive and then add them together in a single huge pile, or you could add every five bags as they come in and keep a running total on a piece of paper. The running total is always available, and the table never gets crowded.

graph TD
  S1["Shard results 1-5"] --> R1["Partial merge A"]
  S2["Shard results 6-10"] --> R2["Partial merge B"]
  R1 --> P["Running combined result"]
  R2 --> P
  S3["More shard results"] --> R3["Partial merge C"]
  R3 --> P
  P --> V["Visible to the client as a partial response"]
  P --> F["Final result once every shard has answered"]
        
FIG 4 — Shard results are merged in batches, so a running result is always available

What a user can do with partial results

A dashboard can draw charts from partial aggregations, and let them refine as more shards report in. A search page can display the first hits found while the rest of the shards are still working. An analyst can decide early that a query is on the wrong track and cancel it, saving cluster resources. All of these turn a long blank wait into an active experience.

Progressive charts

A time-series chart appears with rough shapes after a few seconds and sharpens as more shards contribute. Users can spot trends early.

Early cancellation

After seeing the first partial numbers, an analyst realises the filter was wrong and cancels the search, freeing the cluster for other work.

Best-effort answers

In some monitoring uses, a partial answer from most shards is good enough to decide whether something looks alarming, while the exact final number can arrive later.

The honesty problem

Partial results are exactly that: partial. A count computed from thirty percent of the shards is not thirty percent of the final answer in any reliable sense, because data is not evenly spread. Top-ten lists can change entirely as new shards contribute. Averages can shift. Minimums and maximums can jump. A well-designed interface labels early numbers clearly as provisional, for example with a “still loading” indicator, and avoids drawing firm conclusions or triggering actions such as alerts from them.

!
Do Not Automate on Partial Data

Never let a script make an important decision, such as raising an incident or generating an invoice, from a partial result. Wait until the search has finished and the partial flag confirms success on all shards.

9Polling with the Status API

Checking on a search should be cheap, polite and predictable. The status operation exists for exactly this.

What the status operation returns

The status response is a compact summary. It includes whether the search is running, whether it is partial, the start and expiry times, the shard progress counters, and, once the search is complete, a completion status code that mirrors the code an ordinary search would have returned, such as success or a failure code. It does not include hits or aggregations, so it is small and quick to produce.

Polling strategies

Polling means asking repeatedly. Done carelessly, it can flood the cluster with pointless requests. Done thoughtfully, it is almost free. The most common good practice is to start with short intervals, since many searches finish soon, and then lengthen the interval gradually the longer the search runs, a technique known as backoff. A pause of one second, then two, then four, up to a modest ceiling such as ten or fifteen seconds, works well for most interfaces.

1

Submit with a short wait

Wait a second or two for quick wins. If the search finishes, you are done in one call.

2

Poll the status quickly at first

Check after one second, then two, showing shard progress to the user as a progress bar.

3

Back off gradually

Lengthen the delay up to a sensible maximum so that long searches do not cause a stream of requests.

4

Fetch results once, on completion

When the status says the search is finished, fetch the full result a single time and display it.

5

Stop when the user leaves

If the user closes the page, stop polling and, if the result is no longer needed, delete the search.

Simple Analogy

Asking “are we there yet?” every ten seconds on a long car ride is annoying. Asking once every few minutes, with a quick look at the map in between, gets you the same information without driving everyone mad. Backoff is the polite way of asking.

Long polling as an alternative

The get operation itself supports a wait time. If you ask for the current result and provide a short wait, Elasticsearch will hold the request for up to that long, returning early if the search completes. This gives you a form of long polling, where each check waits a little inside the cluster instead of returning immediately. It reduces the number of round trips, at the cost of holding a connection briefly, so keep waits short enough to stay within any proxy timeouts.

flowchart TD
  A["Submit search"] --> B{"Finished within wait window?"}
  B -->|"Yes"| C["Show final result"]
  B -->|"No"| D["Receive id and partial result"]
  D --> E["Wait, then check status"]
  E --> F{"Still running?"}
  F -->|"Yes"| G["Increase delay, update progress bar"]
  G --> E
  F -->|"No"| H{"Partial flag false?"}
  H -->|"Yes"| I["Fetch and show final result"]
  H -->|"No"| J["Inspect failures and warn the user"]
        
FIG 5 — A sensible client loop for async search
i
Practical Advice

Add a little random jitter to polling intervals when many clients poll at once. Without it, hundreds of users who started at the same moment will all poll at the same instant, creating small bursts of traffic.

10Where Results Live: Storage, Expiry and Size Limits

Stored results are real data on real disks. They deserve the same care you give to any other data.

A dedicated system index

Elasticsearch keeps the state and results of async searches in a special hidden system index reserved for this purpose. You do not create or manage it directly, and you should not write to it yourself. It is an ordinary index in terms of storage, which means the stored results occupy disk space on the cluster, take part in replication, and are affected by disk watermarks like any other data.

Expiry and clean-up

Every stored search has an expiry time, based on its keep alive period. After that moment, the search is no longer accessible, and a background maintenance task periodically deletes expired entries from the system index. Because clean-up runs periodically, an expired result may linger briefly on disk, but it can no longer be retrieved. You can extend the lifetime by fetching the search and asking for a longer keep alive, and you can shorten its life by deleting it explicitly.

A size limit for each stored response

To protect the cluster, there is a limit on the size of a stored async search response, controlled by a cluster setting with a default of ten megabytes. If a completed search would produce a response larger than the limit, the search is marked as failed instead of storing an enormous result. This is a good reminder that async search is meant for delivering answers, such as summaries and reasonably sized lists of hits, not for exporting millions of documents. For bulk export, other tools are more appropriate.

Rule 1

Results are data

Stored results consume disk, replicate to other nodes, and may contain sensitive information from your documents.

Rule 2

Everything expires

Each stored search has a limited lifetime. Plan on fetching results well within that time.

Rule 3

Responses are size-limited

A default cap of around ten megabytes stops one search from filling the store with an oversized result.

Rule 4

Clean-up is periodic

Expired entries disappear through a background task, not at the exact instant of expiry.

Simple Analogy

The dry cleaner has a rack with limited space. Every shirt on it takes up room, and the shop puts a maximum size on what it will take. An old shirt that nobody collects is cleared out after a set period. If everyone forgot to collect their shirts, the rack would eventually overflow.

10 MB
default cap on a stored response
1
hidden system index holds all stored searches
Auto
background clean-up of expired entries
!
Do Not Tamper

Never try to read from, write to, or delete documents inside the system index directly. Use the async search API operations instead, which maintain the internal bookkeeping properly and respect access rules.

11Extending, Cancelling and Deleting a Search

Good housekeeping is part of using async search properly. Every search you start should have a planned ending.

Extending the lifetime

When you fetch a search, you may supply a new keep alive value. Elasticsearch then moves the expiry time forward to match. This is handy for interactive tools: as long as the user keeps a report open, the tool can quietly extend the lifetime each time it refreshes, and when the user leaves, the lifetime simply runs out and the search disappears on its own. It is much better than setting an enormous lifetime at the start “just in case.”

Cancelling and deleting

The delete operation does two jobs. If the search is still running, it cancels the underlying work, so shards stop spending effort on it as soon as they can. Then it removes the stored state and any result. This makes delete the right tool both for cleaning up finished searches and for stopping ones that are no longer wanted, such as when a user changes the filters and starts over.

Cancellation is cooperative. Shards check for cancellation at regular points while they work, so a heavy search does not stop in the same instant, but it stops quickly, and, importantly, the cluster no longer keeps merging results that nobody wants.

Simple Analogy

Cancelling is like phoning the pizza shop and saying “I no longer need the pizza.” The cook may already have rolled out the dough, but they stop before adding more toppings and baking, and the shop does not keep waiting for you to collect it.

1

User changes the question

The user edits a filter or time range while the previous search is still running.

2

Client deletes the old search

The application sends a delete for the old identifier, which cancels running work and frees any stored state.

3

Client submits the new search

A fresh search begins with the new conditions, and the cycle continues with a new identifier.

ANTI-PATTERN-01 Avoid
Problem

Abandoning searches without deleting them, for example when users navigate away or retype a query.

Why It’s Harmful

Abandoned running searches keep consuming shard resources until they finish, and abandoned finished searches occupy storage until their lifetime ends. With many users, the waste adds up quickly.

Correct Approach

Delete the previous search whenever a new one replaces it or the user leaves, and keep lifetimes short so forgotten searches clean themselves up.

12Async Search Versus Other Ways to Search

Elasticsearch offers several search styles, and each solves a different problem. Choosing the right one avoids confusion.

The family of search approaches

A regular search is the default and the best choice for anything that finishes quickly. The scroll approach, which is now discouraged for most uses, walked through large result sets by keeping a snapshot open. The point in time feature combined with a search-after parameter is the modern way to page through large results consistently. Multi-search sends several searches in one request but still waits for them all. Async search is the one designed for long-running searches where you want to detach from the connection and observe progress.

ApproachMain purposeConnection held?Progress and partial resultsResult stored for later?
Regular searchFast queries and interactive searchYes, until doneNo, only a timeout optionNo
ScrollReading large result sets in orderPer batch requestNoKept open as a snapshot only
Point in time with search-afterConsistent deep pagingPer page requestNoConsistent view, not a stored result
Multi-searchMany searches in one round tripYes, until all are doneNoNo
Async searchLong-running searches and aggregationsNo, after the wait windowYesYes, until expiry
Simple Analogy

A regular search is a quick chat at the counter. Scroll and point in time are like reading a very long book one chapter at a time. Async search is like leaving a big order, getting a ticket, and being told how far along your order is. They are different tools for different situations, not better and worse versions of the same tool.

Async search and paging are different things

A common confusion is to think of async search as a way to fetch many pages of results. It is not. It returns a single response, the same shape as a normal search response, containing the hits for the requested size and the aggregations you asked for. If you need to walk through millions of documents, use a point in time with search-after, or a purpose-built export process, not a giant async search response.

i
Decision Shortcut

Ask two questions. Will this search possibly take longer than a proxy timeout, or long enough that users need feedback? Then consider async search. Do I need to read a huge number of documents in order? Then consider point in time and search-after instead.

flowchart TD
  Q["I need to run a search"] --> A{"Will it finish in a second or two?"}
  A -->|"Yes"| R["Use a regular search"]
  A -->|"No"| B{"Do I need progress, partial results or to detach?"}
  B -->|"Yes"| AS["Use async search"]
  B -->|"No"| C{"Do I need to read a very large number of documents?"}
  C -->|"Yes"| PIT["Use point in time with search-after"]
  C -->|"No"| R2["Regular search with a sensible timeout"]
        
FIG 6 — Choosing between the search styles

13What Async Search Does Not Do: Limits and Misunderstandings

Knowing the boundaries of a feature is as valuable as knowing its strengths.

It does not make queries cheaper

Each shard still executes the query in full. The processing, memory and disk reads are the same as for a regular search. If a query is expensive, an async version is equally expensive. Async search is a communication improvement. If you want a query to cost less, you must improve the query, the mapping, the number of shards, the time range or the hardware.

It is not a job scheduler

Async search runs a search now, in the background. It does not schedule a search for later, repeat it every hour, or guarantee that it will run to completion after a restart. If a node involved in the search leaves the cluster or restarts, the search may fail or be incomplete. Regular reporting jobs belong in a scheduler, which can then use async search underneath if it wishes.

Some search options are restricted

Not every option of the regular search is supported in the async version. Options that are about walking through results in a stateful way, such as scroll, are not available, and the search type is limited to the standard query-then-fetch approach. Some defaults also differ from a regular search, so it is worth reading the current documentation for your version before assuming that every parameter behaves identically.

Limit 1

No speed-up

The same shard work happens. Only the waiting changes.

Limit 2

No scheduling

It starts immediately and does not repeat itself or resume after failures.

Limit 3

Size-limited results

Stored responses are capped, so it is not a bulk export tool.

Limit 4

Restricted options

Some regular search options are unsupported or default differently. Check your version.

Limit 5

Finite lifetime

Results vanish after expiry. It is not long-term storage.

Limit 6

Not a guarantee of completion

Node loss or shard failures can leave a search failed or incomplete.

!
Common Misunderstanding

Teams sometimes switch all their searches to async search hoping to fix slowness. The searches are exactly as slow as before, and now the application has extra complexity. Use async search only where its three superpowers, detaching, observing and retrieving later, actually help.

14Cluster Resources: What an Async Search Costs

A background search is still a real search. It uses real threads, real memory and real disk.

Threads and queues

Shard-level search work runs on a pool of search threads on each node. When many searches arrive at once, work waits in a queue, and if the queue is full, new work is rejected. Async searches use the same pool as regular searches, so a burst of long-running background searches can crowd out the quick interactive ones that users expect to be instant. Because async searches are longer, they hold the resources longer.

Memory on the coordinating node

The coordinating node keeps the running merged result in memory. For aggregations with many buckets, this can be large. Batched merging helps by releasing memory as it goes, but large partial results still occupy space until the search is finished and the result is handed off to storage. Circuit breakers guard against runaway memory use and will fail a search rather than risking the node.

Disk and indexing of results

When a search completes and its result is stored, Elasticsearch writes the result into the system index. That is an indexing operation with a real cost, though small compared with the search itself, and it also has to be replicated. For heavy use, hundreds of stored results of several megabytes each represent noticeable storage.

ResourceHow async search uses itRisk if unmanaged
Search thread poolShard queries run for a long timeQueues fill and regular searches get rejected
Coordinating node heapHolds the running merged resultMemory pressure and circuit breaker trips
Disk in the system indexStores completed results until expiryGrowing storage from forgotten searches
NetworkShard results travel to the coordinator; results travel to clientsCongestion from large partial responses fetched repeatedly
Storage tier I/OSlow tiers are read for old dataLong searches stacking up on slow disks or object storage
Simple Analogy

Imagine a restaurant kitchen with a fixed number of cooks. A few huge banquet orders take up several cooks for a long time. If too many banquets arrive at once, ordinary customers wait for a simple sandwich. The kitchen has to plan for both kinds of order, or keep separate cooks for banquets.

Ways to protect the interactive experience

Limit concurrency in the application

Restrict how many async searches each user or team can have running at once, so one enthusiastic analyst cannot fill the queues.

Separate heavy workloads

Direct analytical searches to dedicated coordinating or data nodes, or to a separate cluster, so interactive search stays responsive.

Narrow the search

Reduce the time range, the number of indices, or the size of aggregations. The cheapest search is the one that touches less data.

Lean on shard skipping

Use filters on fields such as timestamps, so shards that cannot match are skipped rather than searched.

i
Balance

Async search lets you say yes to heavy questions without freezing a user’s screen. It is still up to you to make sure that saying yes to too many at once does not hurt everybody else.

15Cold Data, Frozen Tiers and Cross-Cluster Searches

The situations that made async search necessary are becoming more common, not less.

Data tiers and slower storage

To control costs, many organisations keep fresh data on fast, expensive nodes, and move older data to cheaper storage through several tiers. On the coldest tiers, data may live in object storage and be fetched on demand into a local cache when searched. A search that touches such data can take many seconds or longer, especially the first time, because the needed pieces must be downloaded before they can be examined.

This is a natural fit for async search. The user asks a question about last year, gets a ticket immediately, sees early results from the faster tiers, and receives the complete answer when the slower tiers finish. Without async search, the user would either face a long blank wait or be told that old data is off limits.

Simple Analogy

Recent books sit on the shelf near the library entrance and are found in seconds. Old archives are stored in a warehouse across town. Asking a librarian to fetch archive boxes takes time, so the library gives you a slip, shows you the nearby books straight away, and calls you when the boxes arrive.

Cross-cluster search

Cross-cluster search lets one cluster query others, often in different regions. The slowest remote cluster, plus network delays, sets the pace for a normal search. With async search, results from faster clusters can appear early while slower ones are still working. Partial results are especially valuable here, since some clusters may be far away or briefly unreachable, and a user would rather see most of the picture than nothing at all.

graph LR
  U["User dashboard"] --> C["Local cluster: coordinating node"]
  C --> H["Hot tier: fast local shards"]
  C --> W["Cold tier: slower shards"]
  C --> R1["Remote cluster in region 1"]
  C --> R2["Remote cluster in region 2"]
  H -->|"answers first"| C
  W -->|"answers later"| C
  R1 -->|"answers later"| C
  R2 -->|"may be slowest"| C
        
FIG 7 — Fast and slow sources contribute at different times, and partial results show the fast ones early
Case 1

Long-term log search

Investigators search across a year of logs stored on several tiers and want early hits from recent data.

Case 2

Multi-region analytics

A global dashboard combines clusters in several regions, and the slowest region should not block the display.

Case 3

Compliance lookups

Rare requests need to search archived data, accepting a longer wait in return for cheap storage.

Case 4

Capacity-friendly analytics

Large aggregations run in the background on shared clusters while users continue other work.

!
Watch for Silent Gaps

When a remote cluster is unreachable, a search may complete with that cluster’s results missing. Always look at the shard and cluster summaries in the response, and show the user a clear note when part of the data could not be searched.

16Async Search in Kibana and Related Features

You may already be using async search without knowing it, because friendly tools rely on it behind the scenes.

Kibana and progress feedback

Kibana, the visual interface for Elasticsearch, uses async search to run many of its queries, which is why you often see a progress indicator while a large dashboard loads. Rather than hold an unbroken connection open, Kibana submits searches, polls their progress, updates the interface as results arrive, and cancels searches when you navigate away or change a filter. Understanding the pattern helps you reason about what Kibana is doing when a dashboard is slow, and about the load it places on your cluster.

Background searches and sessions

Some versions of Kibana have offered a feature that lets a user send a long search to the background and come back later to see its result, often called a search session. This relies on stored async search results with a suitable lifetime. If you use such a feature, remember that each stored session keeps data in the system index until it expires, and that the lifetimes you configure directly affect storage use.

The same pattern elsewhere

Event query language searches

Searches that look for sequences of events, common in security analytics, have an asynchronous form with the same idea: submit, check status, fetch and delete.

SQL queries

Queries written in the SQL interface can also run asynchronously, returning an identifier that can be polled and cleared.

Client libraries

Official and community client libraries wrap the async search operations, so applications can submit, poll and fetch through familiar methods instead of raw web requests.

Custom applications

Your own dashboards, reporting tools and internal portals can adopt the same pattern to give users progress bars and early results.

Simple Analogy

Async search is like the tracking page of an online parcel. You place the order once, and afterwards every view of the tracking page is a quick check on a job that is being done elsewhere. The stores and couriers that show you tracking are all using the same idea.

i
Operational Insight

If you notice searches on your cluster that seem to come in bursts every time someone opens a big dashboard, the cause may be a dashboard that submits dozens of async searches at once, one per chart. Simplifying dashboards or staggering panels often reduces the load more than tuning the cluster.

17Security: Who Can See a Stored Search?

A stored result is a copy of data taken from your documents, so it must be protected like the documents themselves.

Results belong to the submitting user

When security features are enabled, each async search is tied to the user who submitted it. Other users cannot simply fetch, extend or delete that search by knowing its identifier. Administrators with sufficiently powerful privileges can typically manage other users’ searches, which is important for clean-up and for stopping runaway queries. The exact privileges required are documented for your version, and it is worth reviewing them when you design roles.

Data access rules still apply

A search submitted by a user runs with that user’s permissions. Index-level, field-level and document-level restrictions apply to the search just as they would in a normal search, so the stored result contains only what that user was allowed to see at the time. This is good news, but it also means a stored result reflects a moment in time. If permissions are later withdrawn, the stored copy may still exist until it expires or is deleted.

Treat identifiers as sensitive

Even though access is tied to the user, it is sensible to treat identifiers as sensitive and avoid pasting them into public chat channels, tickets or logs. They are handles to stored data. If an application logs identifiers for debugging, protect those logs with the same care as other operational data.

Control 1

Authentication binding

The search is bound to the user who submitted it, limiting who can retrieve the result.

Control 2

Permissions at run time

Index, field and document restrictions shape what the stored result contains.

Control 3

Short lifetimes

The shorter the lifetime, the shorter the window in which a stored copy of sensitive data exists.

Control 4

Encryption and access to disks

Stored results are on disk like other data, so disk encryption and snapshot policies matter here too.

Control 5

Auditing

Audit logs can record who submitted and fetched searches, helping with investigations and compliance.

Control 6

Administrative clean-up rights

Reserve the ability to manage others’ searches for trusted operators.

Simple Analogy

The dry cleaner hands each customer a slip, and staff normally check who is picking up the shirt. A slip found on the street should not be enough to walk away with someone else’s clothes. Treat your slip numbers with the same care, and ask the shop to discard old items promptly.

ANTI-PATTERN-02 Avoid
Problem

Using one shared service account for every user’s async searches in a multi-user application, with results stored under that single identity.

Why It’s Harmful

All users effectively share the same permissions and visibility. One user’s identifier could be used by another user’s session, and per-user restrictions are lost.

Correct Approach

Run searches under the end user’s identity where possible, or enforce strict access checks in your application layer for every identifier it hands out.

18Monitoring and Metrics

A healthy async search setup shows up in a few simple numbers. Watch them and problems announce themselves early.

What to watch

Metric 1

Running async searches

How many are in flight. A steady rise suggests searches are starting faster than they finish.

Metric 2

Time to completion

The distribution of durations, with attention to the slowest few percent, which drive user complaints.

Metric 3

Size of the system index

Growth in stored results. Sudden increases point to forgotten searches or unusually large results.

Metric 4

Search thread pool queues and rejections

Evidence that heavy background work is crowding out interactive queries.

Metric 5

Heap and circuit breaker trips

Signals that large partial results are stressing coordinating nodes.

Metric 6

Failed and partial completions

The share of searches that end with shard failures or errors, a direct measure of data quality.

Where to look

The status operation gives per-search detail. The task management view lists running search tasks, which is useful for finding long-running or stuck searches and cancelling them. Node statistics show thread pool queue lengths and rejections, and the cluster’s health and disk statistics reveal storage pressure. Slow logs help identify which queries take the longest, so that they can be improved. Your own application should also log the durations and outcomes of the async searches it submits, since it sees the entire experience from the user’s side.

Queues
rising rejections signal crowded search threads
Size
growth of stored results reveals forgotten searches
Partial
rate of incomplete finishes measures data quality
flowchart LR
  A["Alert: search rejections rising"] --> B["List running search tasks"]
  B --> C{"Many long async searches?"}
  C -->|"Yes"| D["Find owners, cancel or narrow their queries"]
  C -->|"No"| E["Check regular search load and hardware"]
  D --> F["Add limits on concurrent async searches per user"]
        
FIG 8 — A simple triage path when async searches crowd the cluster
i
Alerting Advice

Alert on causes you can act on, such as a growing number of long-running searches or a rapidly growing system index, rather than only on the symptom of slow user experience. Early alerts leave time to act calmly.

19Failure Modes and Error Handling

Things go wrong in distributed systems. A good client is ready for each situation in advance.

SituationWhat you will seeRecommended handling
Identifier has expired or was deletedA not-found error when fetchingTell the user the result is no longer available and offer to rerun the search
Some shards fail during the searchFinished, with the partial flag true and failure detailsShow results with a clear warning, offer a retry
A node holding shards restarts mid-searchShard failures or an incomplete resultRetry the search, since work in progress is not resumed
Stored response would exceed the size limitThe search is marked failedReduce the requested size or aggregation buckets
Circuit breaker trips on the coordinating nodeAn error mentioning that data is too largeSimplify the aggregation, narrow the time range, or reduce buckets
Search thread queues are fullRejections for some shard requestsBack off and retry later, and reduce concurrency
Client polls foreverEndless status checks for a stuck searchSet a maximum total wait, then cancel and report a timeout
Network drops between client and clusterConnection errors on pollingRetry the poll; the search itself is unaffected

The reassuring part

One of the great advantages of async search is that a dropped client connection does not destroy the search. If the network hiccups while you are polling, you can simply reconnect and poll again with the same identifier, as long as it has not expired. This is a large improvement over the regular search, where a dropped connection often means starting from scratch.

Simple Analogy

If your phone battery dies while you wait for your dry cleaning, the shirt is not lost. You charge the phone, find your slip, and pick up where you left off. Only if you wait so long that the shop clears its rack is the shirt gone.

ANTI-PATTERN-03 Avoid
Problem

Treating a finished search as successful without checking the partial flag and shard failure counts.

Why It’s Harmful

Missing shards mean missing data. Reports and decisions built on incomplete numbers may be quietly wrong, and the error is hard to notice later.

Correct Approach

Always inspect the completion state and shard summary. Surface warnings to users and provide an easy way to retry.

!
No Automatic Resume

Async search does not resume interrupted work. If part of the search fails because a node restarted, the honest answer is to run it again. Design your application so that rerunning is easy, cheap in effort and clearly explained to the user.

20A Worked Example: A 90-Day Log Dashboard

Let us walk through a realistic story to see all the pieces working together.

The scenario

A retail company collects web server logs into daily indices, keeping ninety days of data. A support engineer uses an internal dashboard to see the number of errors per hour for each service over the last ninety days. The dashboard sends one search with a date histogram aggregation nested inside a terms aggregation across all ninety daily indices, which together contain around nine hundred shards. On a busy day, this search takes about forty seconds.

The old behaviour

With a regular search, the dashboard shows a blank chart for forty seconds. The office reverse proxy cuts connections after thirty seconds, so the engineer often sees a gateway error, reloads the page, and starts another heavy search, doubling the load on the cluster. Sometimes three or four of these pile up before anyone gets an answer.

The new behaviour

1

Submit with a two-second wait

The dashboard submits the same query as an async search with a wait of about two seconds and a keep alive of ten minutes. Nothing finishes that fast, so it receives an identifier and an initial partial result.

2

Show early data and a progress bar

The chart draws the first partial buckets, and a progress bar shows shards completed out of the total, updating every few seconds with gentle backoff.

3

The engineer spots the problem early

After fifteen seconds, the partial chart already shows a spike in errors for one service. The engineer cancels the search and applies a filter for that service.

4

The dashboard deletes and resubmits

The application deletes the first search, cancelling remaining work, and submits a narrower search that finishes in six seconds.

5

Verify completeness and clean up

When the narrower search finishes, the dashboard checks that the partial flag is false and shard failures are zero, shows the final chart, and deletes the search.

sequenceDiagram
  participant E as Engineer
  participant D as Dashboard
  participant ES as Elasticsearch
  E->>D: Open 90-day error chart
  D->>ES: Submit async search (wait 2s, keep alive 10m)
  ES-->>D: Id, running, partial buckets
  D-->>E: Early chart and progress bar
  D->>ES: Status check with backoff
  ES-->>D: 30 percent of shards done
  E->>D: Filter to one service
  D->>ES: Delete first search
  D->>ES: Submit narrower async search
  ES-->>D: Finished, no failures
  D-->>E: Final chart
  D->>ES: Delete search
        
FIG 9 — A dashboard that uses progress, early results and cancellation
~900
shards touched by the wide search
40s
total time of the original heavy search
15s
time to spot the issue using partial results
i
What Changed

The cluster did not get any faster. What changed was that the engineer received information sooner, no connection was lost, useless work was cancelled, and the cluster ran one focused search instead of several piled-up heavy ones. The benefit came from a better conversation, not from a faster engine.

21Designing the Client: A Practical Recipe

Most of the quality of an async search experience is decided in the client code, not in the cluster.

The building blocks of a good client

A well-behaved client has five habits. It submits with a short wait so that quick searches finish in one round trip. It records the identifier as soon as it receives one. It polls the status with backoff and jitter. It checks the completion state and shard failures carefully before showing results as final. And it always deletes searches it no longer needs. If you build these five habits into a small shared library, every screen in your application gets them for free.

Habit 1

Short initial wait

Give the cluster a moment to answer directly, avoiding the long path for easy queries.

Habit 2

Remember the id

Store the identifier in your application state so a page reload can resume watching the same search.

Habit 3

Polite polling

Use backoff, jitter and a maximum total wait so polling never becomes a problem in itself.

Habit 4

Verify completeness

Check the partial flag and shard counts, and communicate any gaps clearly to the user.

Habit 5

Always clean up

Delete on completion, on replacement and on user departure, and keep lifetimes short as a safety net.

Habit 6

Limit concurrency

Cap the number of simultaneous async searches per user or per page to protect the cluster.

Designing the interface

Good interfaces label early results honestly. A small “still loading” tag, a progress bar based on shards completed, and a gentle change of colour when the search is complete let the user understand what they are looking at. Offer a visible cancel button, since the ability to stop a wrong search is one of the most valuable features of the pattern. If the search fails partway, show a clear message with a one-click retry rather than an unexplained error.

Working with proxies and gateways

Because each individual request in the pattern is short, proxy timeouts stop being a problem. The submit call returns after the short wait, each status check is quick, and the final fetch is normally quick as well. If you use long polling with a wait on the get operation, keep the wait comfortably below the shortest timeout in your chain, so that no middle machine ever cuts a request.

Simple Analogy

A good client is like a considerate customer. They place the order, keep the ticket safe, check back politely, look inside the box before accepting it, and tell the shop when they no longer need the order. A shop that has many customers like this runs smoothly.

i
Resume After Reload

Storing the identifier in the page address or in browser session state lets a user refresh the page and continue watching the same search, instead of starting another one. This small detail saves a surprising amount of cluster work.

22Design Patterns That Work Well

These patterns have proved themselves in many production systems.

Try fast, fall back to slow

Submit with a wait of a couple of seconds. If the answer comes back complete, render it and move on. Only when the search is still running does the interface switch to progress mode. Most searches never see the slow path.

Progressive dashboards

Render partial aggregations as soon as they are available and refine them as more shards report in, clearly labelled as provisional until the search finishes cleanly.

Cancel on change

Whenever the user changes filters or navigates away, delete the previous search before starting the next. This keeps the cluster from wasting effort on questions nobody is asking any more.

Short, extendable lifetimes

Start with a lifetime of a few minutes and extend it while the user is actively looking at the result. Forgotten searches then disappear quickly.

Per-user concurrency caps

Allow each user a small number of simultaneous async searches, queueing or refusing the rest with a friendly message.

Narrow before you widen

Encourage users to start with a small time range and expand if needed. Small searches are cheap, and they often answer the question outright.

Pre-computed summaries for the repeated heavy questions

If the same expensive aggregation is run by many people every day, compute it once on a schedule and store the summary, rather than paying for it repeatedly, even in the background.

Dedicated capacity for analytics

Route heavy analytical searches to separate nodes or a separate cluster so that they cannot harm interactive user-facing search.

graph TD
  UI["User interface"] --> API["Application service with async search helper"]
  API --> LIM["Concurrency limiter per user"]
  LIM --> ES["Elasticsearch cluster"]
  API --> STATE["Session state: current search id"]
  ES --> IDX["Hidden system index for stored results"]
  API -->|"delete on change or exit"| ES
        
FIG 10 — A tidy architecture: a helper library handles limits, state and clean-up
“The best background search is the one with a clear beginning, a visible middle and a planned end.”

23Anti-Patterns to Avoid

Recognise these habits early and you will save yourself and your cluster a lot of trouble.

ANTI-PATTERN-04 Avoid
Problem

Using async search for every request, including simple lookups that finish in milliseconds.

Why It’s Harmful

It adds needless complexity and extra round trips. Where a search finishes inside the wait window with no storage requested, the async form gives no benefit over a regular search.

Correct Approach

Reserve async search for searches that may be slow, and keep quick lookups on the regular search path.

ANTI-PATTERN-05 Avoid
Problem

Polling in a tight loop with no delay, or with a fixed short delay for searches that run for minutes.

Why It’s Harmful

Thousands of pointless requests create load and log noise, and the benefit of each additional check falls to almost nothing.

Correct Approach

Use backoff with jitter, cap the interval, and set a maximum total wait time after which the search is cancelled.

ANTI-PATTERN-06 Avoid
Problem

Setting very long lifetimes and never deleting results.

Why It’s Harmful

The system index grows, stored data lingers longer than necessary, and sensitive results stay around long after their usefulness has ended.

Correct Approach

Choose lifetimes to match real need, extend on demand, and delete after fetching.

ANTI-PATTERN-07 Avoid
Problem

Expecting async search to export millions of documents.

Why It’s Harmful

Stored responses are size-limited, and one enormous response is not a sensible way to move bulk data. The search will fail or strain the cluster.

Correct Approach

Use a point in time with search-after, or a dedicated export process, for bulk reading of documents.

ANTI-PATTERN-08 Avoid
Problem

Firing dozens of heavy async searches at once from a single page, one per chart, with no limits.

Why It’s Harmful

The search queues fill, interactive traffic is rejected, and the user’s page becomes slower rather than faster.

Correct Approach

Limit concurrency, stagger panels, share filters between charts, and combine related aggregations into fewer searches.

ANTI-PATTERN-09 Avoid
Problem

Believing that async search fixes a badly designed index, such as thousands of tiny shards or missing time filters.

Why It’s Harmful

The underlying inefficiency remains, and the cluster keeps burning resources. The problem is hidden behind a progress bar instead of being solved.

Correct Approach

Fix the data model, shard sizing and query filters first, and use async search as an interaction improvement on top of a healthy design.

24Capacity Planning for Stored Searches

A little arithmetic tells you how much space and effort a busy async search setup will need.

The three multiplying factors

The storage consumed by async search results depends on three things multiplied together: how many searches are stored at any moment, how big the average stored result is, and how many copies of the system index exist. The first factor is driven by your user numbers and by how long lifetimes are. If two hundred analysts each store five results at any one time, that is a thousand stored results. If each averages two megabytes, the store holds about two gigabytes, which is modest. If lifetimes are days long and results are never deleted, the number of stored results could grow into the tens of thousands and beyond.

FactorWhat drives itHow to control it
Number of stored searchesUsers, dashboards, lifetimes, whether keep on completion is usedShort lifetimes, delete after use, avoid storing fast searches
Average result sizeNumber of hits returned and number of aggregation bucketsLimit hit counts, reduce bucket sizes, drop unneeded fields
ReplicationReplica settings of the hidden system indexAccept the defaults unless you have special needs
Peak concurrencyHow many searches run at oncePer-user caps and staggered dashboards
Simple Analogy

A cloakroom at a busy school event needs enough hooks for the number of coats at the same time, not the total number of coats over the whole day. Coats collected promptly free their hooks. Coats left for days block hooks and force the school to buy a bigger cloakroom.

Estimating concurrency pressure

On the compute side, estimate how many async searches will be running simultaneously at peak, multiply by the average number of shards each touches, and compare with the number of search threads available across your data nodes. If the requested shard work greatly exceeds what your threads can handle, queues will grow and rejections will appear. Cutting the number of shards a search touches, through better time filters and sensible shard sizes, has an enormous effect on this calculation.

1

Measure a typical search

Note its duration, number of shards touched and response size, using a realistic test with realistic data.

2

Estimate peak users

Work out how many people are likely to run heavy searches at the same time during your busiest period.

3

Multiply and compare

Compare total simultaneous shard work with your search thread capacity, and total stored size with free disk space.

4

Add limits and headroom

Set per-user caps, lifetimes and alerts, and keep spare capacity for spikes.

i
Practical Advice

Capacity for async search is usually limited by compute, not by storage. A thousand stored results are cheap; a hundred simultaneous heavy searches are not. Spend your planning effort on concurrency and on reducing the shards each search touches.

25Advantages, Disadvantages and Trade-offs

Every feature is a bargain. Here is what you gain and what you pay.

Advantages

  • Frees the client from holding a long connection open
  • Survives client and network hiccups, since the search continues in the cluster
  • Provides progress information and partial results that improve user experience
  • Allows early cancellation, saving cluster resources
  • Makes searches over slow tiers and remote clusters practical
  • Merges shard results in batches, reducing peak memory on the coordinating node

Disadvantages / Trade-offs

  • No speed-up: the work done by the cluster is identical
  • Client logic is more complex than a single request
  • Stored results consume disk and must be managed and secured
  • Partial results can mislead if presented as final
  • Heavy background searches can crowd out interactive ones
  • Some regular search options are unavailable or behave differently

Regular search compared with async search

AspectRegular searchAsync search
Client complexityVery low, one requestModerate, needs polling and clean-up
Behaviour on dropped connectionResult usually lostSearch continues, result can be fetched later
Progress visibilityNoneShard progress and partial results
Storage of resultsNoneOptional, until expiry
Suitability for very fast queriesExcellentUnnecessary overhead
Suitability for long queriesFragileDesigned for it
i
How to Think About It

Async search trades a little extra complexity for a lot of resilience and a much better experience on slow searches. On fast searches, the trade is not worth it. The skill lies in knowing which kind of search you are dealing with.

26Real-World and Industry Examples

Here is how organisations with different needs put the pattern to work.

Security operations centres

Analysts hunt for suspicious behaviour across months of logs, often spanning fast and archived tiers. Async search provides early hints while the deep archive is still being read, and cancellation prevents wasted effort when a hunt goes in the wrong direction.

Observability platforms

Engineers examine latency percentiles, error rates and traces across many services and long periods. Progressive dashboards show trends quickly and refine them, which keeps investigations moving during incidents.

E-commerce analytics

Teams compute sales and behaviour summaries across years of orders and clickstream events. Heavy analytical queries run in the background on dedicated capacity while shoppers continue to enjoy fast interactive search.

Financial and compliance reporting

Auditors run long searches over archived transactions. They accept longer waits in exchange for cheaper storage, and they rely on the completeness flags to prove that no shard was skipped.

Multi-region enterprises

Global dashboards combine several clusters. Partial results let the nearest regions show up at once while distant regions contribute when they can, with clear indicators for any region that could not be reached.

Managed and shared platforms

Platform teams provide search as a service to many internal teams. Per-user limits, short lifetimes and monitoring of stored results keep the shared cluster healthy while every team benefits from background searches.

The lesson across all these examples

In every case, the value came from respecting the difference between the computer’s timescale and the human’s. Clusters can work for a minute without complaint, but people cannot stare at nothing for a minute without frustration. Async search bridges the gap by keeping the person informed while the machine does its work, and by letting the person change their mind while work is still in progress.

27Common Myths About Async Search

A few misunderstandings appear again and again. Let us set them straight.

Myth: “Async search makes my queries faster.”

Reality: the cluster does exactly the same work. The improvement is in how the client waits, observes and recovers, not in how quickly the shards finish.

Myth: “Every async search stores its result.”

Reality: by default, a search that finishes within the wait window is returned directly and nothing is stored. Storage happens when the search is still running or when you explicitly ask to keep the result.

Myth: “Partial results are almost the final answer.”

Reality: partial results can differ greatly from the final ones, especially for rankings, minimums, maximums and averages, because data is not evenly spread across shards.

Myth: “When the running flag is false, the result is guaranteed complete.”

Reality: a finished search may have failed on some shards. You must also check the partial flag and the shard failure information.

Myth: “Results are kept forever.”

Reality: every stored search has an expiry time, after which it is deleted. Fetch what you need in good time.

Myth: “Deleting is optional housekeeping.”

Reality: deleting also cancels running work. Skipping it wastes cluster resources on searches nobody wants, and leaves stored results lying around.

Myth: “Async search can page through any amount of data.”

Reality: it returns a single, size-limited response. Bulk reading of documents belongs to other tools.

“Async search changes how you wait, not how much work there is to do.”

28How the Feature Evolved

A short history helps you read older articles and understand why the feature looks the way it does.

1

Before async search

Long searches relied on raising timeouts everywhere and hoping connections survived. Users had no visibility into progress, and cancelling was awkward.

2

Introduction in the 7.x series

Async search arrived in the 7.x line, around version 7.7, with submit, get and delete operations, batched merging, and stored results with a lifetime.

3

Status operation added

A lightweight status operation followed in a later 7.x release, making polling cheap and giving clients a completion status without downloading the whole response.

4

Wider adoption

Kibana and other tools adopted the pattern, and related features such as event query language and SQL gained asynchronous forms built on the same ideas.

5

Fit with tiered storage

As data tiers and searchable snapshots on cheaper storage became common, the value of background searches grew, since slow tiers make long searches routine.

!
Check Your Version

Defaults, supported parameters and required privileges have evolved over time. Before relying on a specific behaviour, confirm it in the documentation for the exact version you run, and test it on a non-production cluster first.

29Frequently Asked Questions

Short answers to the questions beginners ask most often about async search.

Q1What is async search in one sentence?

It is a way to submit a search, receive an identifier and control back immediately, watch progress and partial results while it runs, and fetch the final result later, without holding a connection open.

Q2Does async search make my query faster?

No. The shards do the same work. What improves is the experience of waiting: you can detach, see early results, cancel, and recover from dropped connections.

Q3When should I use it instead of a regular search?

Use it when a search may take long enough to hit proxy timeouts or to frustrate users, for example wide aggregations, cold tier data or cross-cluster searches. Use regular search for quick lookups.

Q4Why did I not get an identifier back?

Because the search finished within the wait window and you did not ask to keep the result, so nothing was stored. Set keep on completion to true if you want an identifier even for fast searches.

Q5What does is_partial mean?

While the search runs it is always true, because you see an incomplete picture. After completion it is false if the search succeeded on all shards and true if it failed or missed some shards.

Q6How long are results kept?

Until the expiry time shown in the response, which is based on the keep alive setting. You can extend it when you fetch, or shorten it by deleting the search.

Q7What is the status operation for?

It returns a small summary of the search, including running state, shard progress and completion code, without the potentially large results, so it is ideal for polling.

Q8Does deleting a search cancel it?

Yes. Deleting a running search cancels the underlying work and removes its stored state. Deleting a finished search removes the stored result.

Q9Can another user fetch my search if they know the identifier?

With security enabled, searches are tied to the user who submitted them, so ordinary users cannot retrieve someone else’s search. Privileged administrators can typically manage them. Still, treat identifiers as sensitive.

Q10Is there a limit to how big a stored result can be?

Yes. There is a cluster setting that limits the size of a stored response, with a default of around ten megabytes. Larger responses cause the search to fail rather than being stored.

Q11What happens if a node restarts during my search?

The search may finish with shard failures, marked as partial, or fail. Async search does not resume interrupted work, so rerun the search if the results are incomplete.

Q12How often should I poll?

Start with short intervals, such as a second, and lengthen them gradually up to a modest ceiling, adding a little random jitter. Stop polling when the user leaves and set a maximum total wait.

Q13Can I use async search to export a large number of documents?

Not sensibly. It returns a single size-limited response. Use a point in time with search-after, or a dedicated export approach, for bulk reads.

Q14Do Kibana dashboards use async search?

Kibana commonly uses it to run searches, which is why you see progress indicators on heavy dashboards. Related features such as event query language and SQL have their own asynchronous variants.

Q15What is the biggest mistake to avoid?

Treating partial or finished-but-incomplete results as final, and forgetting to delete searches. Always check completion flags and shard failures, and always clean up.

30Summary and Key Takeaways

Async search is a way of running Elasticsearch searches in the background. You submit a query, receive an identifier if the search is still running, poll a lightweight status, read partial results as shards report in, fetch the final result when it is ready, and delete the search when you are done. It solves the practical problems of long searches: broken connections, blank screens, wasted work and users who cannot change their mind. It does not make the underlying work any smaller, so it must be combined with good data modelling, sensible shard counts, narrow queries and controlled concurrency. Used with care, checking completion flags, limiting lifetimes, securing identifiers and cleaning up after itself, it turns a long, fragile wait into a calm, informative conversation between people and their data.

Key Takeaways

  • Async search detaches asking from answering — you submit, get control back, and collect the result later using an identifier.
  • It is a change in communication, not in speed — the shards do the same work, so expensive queries remain expensive.
  • Four operations cover everything — submit, get, status and delete, with delete also cancelling running work.
  • Three settings shape behaviour — the wait window, keep on completion, and keep alive decide when you get an identifier and how long results live.
  • Read the flags carefully — running and partial tell different stories, and a finished search with the partial flag set may be missing data.
  • Treat stored results as real data — they use disk, are size-limited, expire, and must be secured and cleaned up.
  • Build a polite, careful client — short initial wait, backoff polling, concurrency limits, honest labelling of early results, and always delete when finished.