NEW

Pulse 2025 Product Roundup: From Monitoring to AI-Native Control Plane

Elasticsearch thread_pool.search.size Setting

thread_pool.search.size sets the number of threads in each node's search thread pool. The search pool handles all count, search, and suggest operations - effectively every query that traverses the index. Each shard a search touches consumes one thread from this pool for the duration of the per-shard phase. The pool size therefore caps the per-node concurrency of in-flight shard searches.

  • Default: int((# of allocated processors * 3) / 2) + 1
  • Queue size (thread_pool.search.queue_size): 1000 by default
  • Type: Fixed thread pool
  • Scope: Per-node, static - requires a node restart to change

How the Search Thread Pool Works

When a coordinating node receives a search request, it fans out shard-level sub-requests to each data node holding a relevant shard. Each data node dequeues one shard request per available search thread; remaining requests wait in the queue. When the queue fills, additional requests are rejected with EsRejectedExecutionException.

A node with 8 allocated processors gets a default search pool of int(8 * 1.5) + 1 = 13 threads. A node with 16 processors gets 25. The formula targets a moderate over-subscription of CPU since search threads frequently block on disk and network.

Configuring thread_pool.search.size

Set it in elasticsearch.yml:

thread_pool.search.size: 20
thread_pool.search.queue_size: 1000

The setting is static. Apply changes by restarting the node. Inspect current state with the cat thread pool API:

GET /_cat/thread_pool/search?v&h=node_name,name,active,queue,rejected,size
Column Meaning
active Threads currently executing
queue Requests waiting for a thread
rejected Cumulative rejections since node start
size Effective pool size

When to Change the Default

Symptom Action
Sustained queue > 0 and rejected climbing on _cat/thread_pool/search Investigate slow queries first; then consider a small increase
active consistently at max, CPU < 60% Pool is the bottleneck - increase modestly
active consistently at max, CPU > 85% Increase nodes or shards, not the pool
Low load, large pool sitting idle Leave at default; no benefit to shrinking

Overshooting causes context-switching overhead and worse latency under load. A pool of 100 threads on an 8-core node is almost always counterproductive.

Common Pitfalls

  1. Raising size to mask the symptoms of slow queries. The root cause is usually a query that needs optimization, a hot shard, or oversharding.
  2. Setting size independently of queue_size. Both control rejection behavior - raising one in isolation rarely helps.
  3. Ignoring the allocated_processors setting. If processors are misdetected (common in containers without CPU cgroup limits), the default size will be wrong.
  4. Tuning per-node in a heterogeneous cluster. Mixed node sizes lead to imbalanced load - the cluster behaves as if all nodes are the slowest one.

Monitoring the Search Thread Pool

Track _cat/thread_pool/search and _nodes/stats/thread_pool/search continuously, not just during incidents.

Prevent Search Pool Misconfiguration with Pulse

Pulse is an AI DBA for Elasticsearch and OpenSearch that tracks thread_pool.search.size, thread_pool.search.queue_size, and rejection counts across every node and index, flagging:

  • Drift between intended pool size and the value actually applied (common after node replacements or container restarts where allocated_processors was misdetected)
  • Settings that are unsafe for your workload (e.g. size raised far above the int((processors * 3) / 2) + 1 default while CPU is already at 90%, or queue_size raised to mask slow queries)
  • The downstream operational impact: rejection rate per node, queue depth, and which query families correlate with each spike

When the search pool is the bottleneck, Pulse names the misconfiguration - undersized pool, oversharded indices, regex query family, or hot shard - before it becomes a user-visible incident, instead of leaving operators to chase EsRejectedExecutionException after the fact.

Connect your cluster.

Frequently Asked Questions

Q: What is the default size of the Elasticsearch search thread pool?
A: The default is int((allocated_processors * 3) / 2) + 1. On an 8-core node, that's 13 threads. The default queue size is 1000.

Q: How do I check if search requests are being rejected?
A: Query GET /_cat/thread_pool/search?v&h=node_name,active,queue,rejected. Any non-zero rejected column indicates search requests have been dropped since node start.

Q: Should I increase thread_pool.search.size to improve performance?
A: Usually no. Increasing the pool helps only when the pool is the bottleneck (high queue depth, moderate CPU). If CPU is already saturated, more threads make latency worse. Optimize slow queries and shard layout first.

Q: What is the difference between search and search_throttled thread pools?
A: The search pool handles regular index queries. search_throttled handles queries against searchable snapshots and frozen-tier indices, with a smaller default size to limit resource use on rarely-queried data.

Q: Can I change thread_pool.search.size at runtime?
A: No. Thread pool sizes are static and require a node restart. Restart nodes one at a time during a rolling restart to avoid cluster availability impact.

Q: How does the search pool interact with shard count?
A: Each shard a search touches consumes one search thread per node holding it. Oversharded clusters exhaust the pool faster than necessary. Reducing shard count is often a more effective fix than raising pool size.

Q: What's the best tool to monitor and tune the Elasticsearch search thread pool?
A: Pulse is built for this. It is an AI DBA for Elasticsearch and OpenSearch that continuously tracks thread_pool.search.size, queue depth, and rejection rate per node, correlates spikes with specific queries, and recommends whether the right fix is pool tuning, query rewriting, or scaling out - instead of leaving operators to guess after the fact.

Subscribe to the Pulse Newsletter

Get early access to new Pulse features, insightful blogs & exclusive events , webinars, and workshops.

We use cookies to provide an optimized user experience and understand our traffic. To learn more, read our use of cookies; otherwise, please choose 'Accept Cookies' to continue using our website.