<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title><![CDATA[Elastic Cloud Serverless - Elasticsearch Labs]]></title>
    <description><![CDATA[Articles and tutorials from the Search team at Elastic]]></description>
    <copyright><![CDATA[© 2026. Elasticsearch B.V. All Rights Reserved]]></copyright>
    <image>
      <title><![CDATA[Elastic Cloud Serverless - Elasticsearch Labs]]></title>
      <url>https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1121c0bf0e8a6e65/6a88da6340a1841030ef456f/search-labs-thumbnail.png</url>
      <link>https://www.elastic.co/search-labs/blog/category/elastic-cloud-serverless</link>
    </image>
    <link>https://www.elastic.co/search-labs/blog/category/elastic-cloud-serverless</link>
    <atom:link href="https://www.elastic.co/search-labs/rss/category/elastic-cloud-serverless.xml" rel="self" type="application/rss+xml"/>
    <language><![CDATA[en]]></language>
    <lastBuildDate>Fri, 25 Sep 2026 04:33:11 GMT</lastBuildDate>
  <item>
    <title><![CDATA[Elasticsearch Vector Database: Ship in minutes, scale affordably to hundreds of billions]]></title>
    <description><![CDATA[The hard parts of hybrid retrieval, already done, with optimized defaults, third party and native Jina AI models, and managed GPU inference all out of the box. Build fast, scalable AI apps, not infrastructure.]]></description>
    <content:encoded><![CDATA[<p>Elasticsearch is one of the most widely deployed platforms for vector workloads in the world, powering semantic search, retrieval augmented generation (RAG), and recommendations for companies like GitHub, Docusign, Seismic, and many others. Today we're announcing Elasticsearch Vector Database, a new serverless offering optimized for vector based applications. You bring your documents and your queries, and we handle the embeddings and index tuning, along with the infrastructure. Plus, we keep it cheap and scalable. </p><p>For new users, this is the fastest way to get high-quality vector search running. If you already use Elasticsearch, the new offering is vector search on the platform where your data already lives, with no new system to adopt. Elasticsearch Vector Database supports a range of scenarios, from grounding a large language model (LLM), to giving an AI agent retrieval and memory, to serving hundreds of billions of vectors. <a href="https://cloud.elastic.co/registration?onboarding_token=vector">Spin up a new project</a> and get started in minutes.</p><h2>One engine, every vector use case</h2><p>Elasticsearch Vector Database is built for anyone building applications using vectors:</p><ul><li><p><strong>RAG:</strong> Retrieve the right context for your LLM with dense and sparse vector retrieval, or go with hybrid search combining both vector and lexical retrieval. The quality of your generation improves with the quality of your retrieval.</p></li><li><p><strong>AI agents:</strong> Give agents fast, filtered retrieval over documents and conversation memory, with the low latencies that multistep agent loops demand.</p></li><li><p><strong>Semantic search:</strong> Match on meaning, not keywords, with one field type and zero pipeline code.</p></li><li><p><strong>Recommendations and similarity:</strong> Find nearest neighbors across products, images, or whatever content you have, at scale.</p></li></ul><h2>Everything your vector workload needs, optimized out of the box</h2><p>Building a vector-based application means wiring together several separate pieces: setting up and hosting embedding models, indexing your documents through them, storing the vectors efficiently, applying the embedding model to each query, matching against the vector store, and finally, retrieving the documents behind the matches. Elasticsearch Vector Database handles all of it for you, with no additional configuration or setup.</p><h3>Vector indexing with vectordb_document index mode</h3><p><a href="https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/dense-vector#dense-vector-vectordb-document-mode"><code>vectordb_document</code></a> index mode, a new index configuration purpose-built for vector-first workloads, is on by default, so you get the settings that experts would choose. Here's what it turns on:</p><ul><li><p><strong>bfloat16 by default:</strong> Vectors are stored at half the size of float32 with negligible impact on recall, cutting your disk footprint roughly in half before quantization even enters the picture.</p></li><li><p><strong>Source vectors excluded:</strong> In Elasticsearch, your embeddings already live in the index structures used for search; keeping a second raw copy in <code>_source</code> just inflates storage and slows down fetching results. We exclude the duplicate so responses return faster and you store less.</p></li><li><p><strong>The right files preloaded into cache:</strong> The data structures that vector queries touch first are warmed into memory ahead of time, so your first (and your thousandth) query is lightning fast.</p></li><li><p><strong>Parallel merging:</strong> Merging consolidates segments into better-organized vector structures, which lifts both recall and latency, and running those merges multi-threaded means you get there faster.</p></li></ul><h3>Vector storage, compression, and auto-tuning</h3><ul><li><p>Your vectors are compressed automatically.<a href="https://www.elastic.co/search-labs/blog/better-binary-quantization-lucene-elasticsearch"> Better Binary Quantization (BBQ)</a> shrinks vector memory footprints by up to 32x while preserving recall, and DiskBBQ reduces memory requirements further for large-scale workloads.<a href="https://www.elastic.co/search-labs/blog/vector-quantization-auto-calibration-diskbbq"> </a></p></li><li><p>Opt in to<a href="https://www.elastic.co/search-labs/blog/vector-quantization-auto-calibration-diskbbq"> auto-calibration</a>, which tunes each segment's quantization to your data and retunes on every merge as data drifts. When tested across 18 datasets, queries per second (QPS) improved by an average of 16.7%, with recall gains in most of them.</p></li></ul><h3>Embeddings on managed GPU inference</h3><ul><li><p>Generate embeddings with native <a href="https://www.elastic.co/jina-search-models">Jina AI embedding and reranking models</a>, or bring third-party models, all on managed GPUs via <a href="https://www.elastic.co/docs/explore-analyze/elastic-inference/eis">Elastic Inference Service (EIS)</a> with no model servers to operate. Or self-host, if you prefer your own.</p></li><li><p>The <a href="https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/semantic-text"><strong><code>semantic_text</code></strong></a> field type automatically handles chunking and embedding, along with querying, the simplest path to semantic search in the market. </p></li></ul><h3>Hybrid search and filtered vector search</h3><ul><li><p><a href="https://www.elastic.co/elasticsearch/hybrid-search">Hybrid search</a> is built in, combining full-text and vector retrieval in a single query. Blend the results with reciprocal rank fusion (RRF) or any other blending mechanism you want. Vector search is usually the hardest part of hybrid search to configure well. With Elasticsearch Vector Database, you have it handled, and your whole hybrid stack gets better. </p></li><li><p>With <a href="https://www.elastic.co/search-labs/blog/filtered-hnsw-knn-search">filtered vector search</a>, apply metadata filters as part of vector retrieval itself and not as an afterthought that wrecks recall.</p></li></ul><h3>Enterprise on day one</h3><p>You also get role-based access control (RBAC), audit logging, and the compliance certifications that pure-play vector databases generally lack.</p><h2>Affordable at scale and predictable</h2><p>Elasticsearch Vector Database is built to stay affordable as you grow: BBQ and DiskBBQ compression that keeps storage linear and memory low means scaling to hundreds of billions of vectors doesn't blow up your bill. And <a href="https://cloud.elastic.co/pricing/serverless?s=vectordb">what you do pay</a> is built from numbers you already know: how much data you store and how much you index, along with how much search capacity you need. Estimate your document count and vector dimensions, plus your query load, and you can work out what you'll pay before you create the project. You can also understand your bill line by line at the end of the month. There are no opaque compute units and no surprise charges for background operations.</p><h2>How to get started with Elasticsearch Vector Database</h2><h3>Create a serverless vector database project</h3><p>Create a new <a href="https://cloud.elastic.co/registration?onboarding_token=vector">serverless Vector Database project in Elastic Cloud</a>. Point your data at the endpoint, and you're ready to index.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt556cbdfba551f248/6aa10b4332b53038406d321a/image1.png" alt="Elastic Cloud Serverless project types: Elasticsearch, Vector Database, Observability and Security" /><h3>Create an index using semantic_text</h3><p>Vector index mode handles the vector configuration. Using <code>semantic_text</code> means that embeddings and chunking setup are managed for you, as is index setup, on managed GPU inference, with no embedding pipeline to build.</p>PUT my-vectors
{
"mappings": {
"properties": {
"description": { "type": "semantic_text" }
    }
  }
}<h3>Ingest documents</h3><p>Index text, and the embeddings are generated for you.</p>POST /my-vectors/_doc
{
  "id": "park_rocky-mountain",
  "title": "Rocky Mountain",
  "description": "Bisected north to south by the Continental Divide, this portion of the Rockies has ecosystems varying from over 150 riparian lakes to montane and subalpine forests to treeless alpine tundra."
}<h3>Run a semantic search query</h3><p>Query the same semantic field you just created:</p>GET /my-vectors/_search
{
  "query": {
    "semantic": {
      "field": "description",
      "query": "a mountain range in the middle of north america"
    }
  }
}<p>And you get results back:</p>{
  "took": 80,
  "hits": {
    "max_score": 0.7792325,
    "hits": [
      {
        "_index": "my-vectors",
        "_score": 0.7792325,
        "_source": {
          "id": "park_rocky-mountain",
          "title": "Rocky Mountain",
          "description": "Bisected north to south by the Continental Divide, ..."
        }
      }
    ]
  }
}<p>Semantic search is just the start. Run fully textual queries or combine both into hybrid queries. You can even craft your own vector queries for full control. Follow the <a href="https://www.elastic.co/docs/solutions/vector-database/vector-full-text-search">semantic search quickstart</a> in the docs for the full instructions.</p><h2>What's next for vector search in Elasticsearch</h2><p>We're already working on the next improvements:</p><ul><li><p><strong>Better multi-tenant handling:</strong> If your data needs to stay separated per tenant, we'll give you a way to do it faster and with less code.</p></li><li><p><strong>Automatic index optimization:</strong> From "brand new index" to "fully optimized," with as little tinkering as possible.</p></li><li><p><strong>Continuous infrastructure improvements:</strong> Ongoing tuning of Vector Database's settings and infrastructure so you're always getting the best throughput and fastest responses.</p></li></ul><h2>Try Elasticsearch Vector Database on Elastic Cloud Serverless</h2><p>Go from an empty project to a hybrid, filtered vector query in minutes, with production-grade defaults doing the tuning for you. Build fast, scalable AI apps, not infrastructure.</p><p>Start on <a href="https://cloud.elastic.co/registration?onboarding_token=vector">Elastic Cloud Serverless</a>, or dive into the <a href="https://www.elastic.co/docs/solutions/vector-database">full documentation </a>and <a href="https://www.elastic.co/docs/api/doc/elastic-cloud-serverless/group/endpoint-vectordb-projects">API reference.</a> You can also access the new offering on<a href="https://aws.amazon.com/marketplace/pp/prodview-voru33wi6xs7k"> AWS Marketplace</a>,<a href="https://console.cloud.google.com/marketplace/product/elastic-prod/elastic-cloud"> Google Cloud Marketplace</a> and<a href="https://portal.azure.com/#view/Microsoft_Azure_Marketplace/GalleryItemDetailsBladeNopdl/id/elastic.ec-azure-vector/"> Microsoft Marketplace</a>.</p><p></p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/vector-database-rag-serverless</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/vector-database-rag-serverless</guid>
    <category><![CDATA[Vector Database]]></category>
    <category><![CDATA[Elastic Cloud Serverless]]></category>
    <category><![CDATA[Hybrid Search]]></category>
    <dc:creator><![CDATA[Dustin Coates]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4def84aae6aff861/6aa10ab1ee57e53d9b05253c/cover.png" length="0" type="image/png"/>
    <pubDate>Wed, 09 Sep 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[No more allocation delays: Decoupling snapshots from shard relocation in stateless Elasticsearch]]></title>
    <description><![CDATA[Clusters scale out under load without waiting for a snapshot to finish, because snapshots now read straight from the object store and no longer pin shards in place.]]></description>
    <content:encoded><![CDATA[<p>Stateless snapshots now read directly from the object store. Server-side "undesired allocation due to snapshot" warnings stopped entirely after the release. Primary shards stay free to relocate while a snapshot runs, so clusters scale out under load without waiting for one to finish. Across the fleet, cache misses dropped by more than 60% and median cache population throughput rose roughly 50%. </p><h2>Why snapshots pin primary shards in stateful Elasticsearch</h2><p>In traditional stateful Elasticsearch, snapshots lock primary shards to their active nodes, completely preventing relocation. That works fine when cluster topology is stable and nodes stay online between maintenance windows, but stateless Elasticsearch works differently. Index data lives in an external object store, with local disk as a cache, and the cluster scales automatically based on CPU, memory, and data size, both vertically (upsizing nodes) and horizontally (adding nodes).</p><p>During vertical scale-up, existing nodes must vacate all shards and shut down before new hardware takes over. Since Elasticsearch version 8.13, shard snapshots can pause during node shutdowns and resume after relocation, so a long-running snapshot doesn't block an infrastructure update.</p><p>Horizontal scale-out is a different story: No nodes shut down, so pause logic never triggers. New nodes sit idle while existing nodes finish their snapshots, and as soon as a snapshot is queued, the primary shard is pinned to its node, significantly delaying relocation.</p><p>Clusters typically scale out because they're already under heavy load. Blocking shard relocations at that moment limits the cluster's ability to reduce pressure, which shows up as degraded indexing throughput and higher latency. The resource imbalance can also trigger unexpected autoscaling behavior. And even when overall topology stays the same, shard locking disrupts hotspot mitigation and workload distribution. These failures used to surface as server-side warnings: "undesired allocation due to snapshot."</p><p>
</p><p><strong>Stateful Elasticsearch</strong></p><p><strong>Stateless Elasticsearch</strong></p><p>Snapshot reads from</p><p>Local shard data on the node holding the primary</p><p>The object store, using file locations recorded in the commit</p><p>Primary shard during snapshot</p><p>Pinned to its node until the snapshot completes</p><p>Free to relocate at any time</p><p>Effect on horizontal scale-out</p><p>New nodes wait for in-flight snapshots before taking shards</p><p>New nodes take shards immediately, regardless of snapshot state</p><p></p><h2>How stateless snapshots read directly from the object store</h2><p>A shard snapshot pins primary shards because it needs to read local shard data. In stateless Elasticsearch, that data already lives in the object store, so reading from local disk is unnecessary. Letting snapshots read directly from the object store removes the requirement to lock primary shards. They can relocate freely, and backup is decoupled from cluster balancing.</p><p>Stateless commits include location information for each data file in the object store, so snapshots can read and stream directly to the snapshot repository (a separate object store bucket). In the future, we plan to look at server-side ranged copies, which object stores support natively, to skip the local copy step entirely.</p><h2>Tracking commits when shards relocate mid-snapshot</h2><p>A snapshot is bound to a specific commit point that determines which files to back up, and those files must remain accessible for the full duration of the operation. In stateful clusters, this is simple: The snapshotting node and the data node are the same, so the commit is managed locally and held until completion.</p><p>In a stateless model, the snapshotting node and the data node can be entirely separate, or they can diverge if a shard relocates mid-snapshot. To handle this, we added a transport action that acquires commits on remote data nodes over the network. The data node tracks which commit belongs to which snapshot and releases it once cluster state signals completion.</p><p>There's a wrinkle during relocation. A stationary shard relies on its commit point to preserve files. A relocating shard must release its commit so its local store can close cleanly. To keep files accessible through that transition, a newly recovered primary temporarily preserves all existing data files in the object store until notified of snapshot completion via cluster state. This handles both graceful relocations and ungraceful recovery from node or engine failures.</p><h2>No more allocation delays and improved cache stats</h2><p>After stateless snapshots shipped, the server-side "undesired allocation due to snapshot" warnings stopped. The chart below shows the before and after, with the release marked by the red arrow. Hotspot mitigation became more responsive because shard relocations no longer had to wait for backup operations.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0c08d57928ea1c6c/6a97a33f2707c544c5329695/unnamed.png" alt="Bar chart showing undesired allocation due to snapshot warnings dropping to zero after stateless snapshots shipped" /><p>Cache use is also improved. Snapshots that bypass local shard data stop competing with indexing for cache space. After the release (also marked in the chart), we observed the following two positive changes in cache metrics:</p><ol><li><p>The median cache population throughput, defined as bytes per second for filling the local disk cache from the object store, increased about 50%.</p></li><li><p>Cache misses, where data must be retrieved from the object store to fill local disk cache, have dropped more than 60%. </p></li></ol><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0b85caa56b35485d/6a97a3683eabd0c326440fab/unnamed_(1).png" alt="Charts showing cache population throughput rising 50% at p50 and cache misses falling over 60% after release" /><h2>What comes after stateless snapshots</h2><p>Object-store-native architectures are increasingly the standard for cloud-native data systems, and stateless snapshots are a step toward fully exploiting that model across Elasticsearch operations. Backups read from the object store, and shards move freely. Neither process waits on the other. Removing the local shard dependency is a step toward further modularizing the stateless architecture.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/stateless-snapshots-shard-relocation</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/stateless-snapshots-shard-relocation</guid>
    <category><![CDATA[Elastic Cloud Serverless]]></category>
    <category><![CDATA[Inside Elastic]]></category>
    <category><![CDATA[Operations]]></category>
    <dc:creator><![CDATA[David Turner,Yang Wang]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt685f7746435d0451/6a97a2aaf08ee14b39853cbb/unnamed.png" length="0" type="image/png"/>
    <pubDate>Wed, 02 Sep 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Avoiding and Correcting Hotspots: How Elasticsearch Serverless Balances Shards]]></title>
    <description><![CDATA[Elasticsearch Serverless replaces the Elasticsearch node-weight based shard rebalancing algorithm with resource usage aware rebalancing that avoids index shard colocation, OOM events and write load hotspotting]]></description>
    <content:encoded><![CDATA[<p>The Elasticsearch Serverless Balancer addresses write load hotspots, prevents data node out-of-memory (OOM) events and avoids index-level hotspots in Elasticsearch Serverless clusters: these are workload edge cases that in non-Serverless require manual intervention and custom tuning of cluster settings. Serverless shard balancing focuses on staying within the bounds of node-level resource constraints. Rebalancing moves are explainable, where moves are made explicitly to either avoid performance degradation or correct hotspots when they develop. Shard movements are generally found to be fewer, as well.</p><h2>How Elasticsearch Shard Balancing Works</h2><p>Elasticsearch uses a weights-based algorithm to create a Desired Balance, an assignment of shards to data nodes. The Balancer determines the target allocation of shards across a cluster of nodes using four key metrics weighted in a linear algorithm. A total weight is calculated per node, and the shard balancer aims to equalize the total weights across cluster nodes. A final Desired Balance shard allocation is precomputed based on the latest cluster state information, and then the elected master node initiates incremental shard moves to reach the desired shard allocation.</p><p>The four metrics are:</p><ul><li><p><strong>Write Load:</strong> the total write threadpool activity per node, using the sum of threadpool indexing activity per data-stream shard.</p></li><li><p><strong>Disk Usage:</strong> the total disk usage of shards per node, using the sum of disk space used per shard.</p></li><li><p><strong>Shard Count:</strong> the total number of shards assigned to a node.</p></li><li><p><strong>Index Balance (shard anti-affinity):</strong> per index, how many shards in the index are assigned to the node.</p></li></ul><p>The total weight of a node is calculated using a linear algorithm that finds the deviation from the node-level cluster average for each individual metric, applies a different weight factor multiplier to each, and then takes the sum of all resultant values. The weight factor multipliers attempt to equalize the relative magnitude of each metric so that metrics with large values do not eclipse metrics with naturally small values. Write load tends to be a small value, related to thread usage, and thus gets multiplied by a relatively larger weight factor of <code>10</code>; whereas disk usage in bytes is a very large number and therefore gets multiplied by a tiny weight factor of <code>2e-11</code>.</p><p>The following are the cluster settings with default values, representing the different weight factors:</p><p><code>cluster.routing.allocation.balance.shard: 0.45</code></p><p><code>cluster.routing.allocation.balance.index: 0.55</code></p><p><code>cluster.routing.allocation.balance.disk_usage: 2e-11</code></p><p><code>cluster.routing.allocation.balance.write_load: 10.0</code></p><p>The linear algorithm looks something like this:</p>final float shardWeightFactor =
    settingValue("cluster.routing.allocation.balance.shard");
final float writeLoadWeightFactor = 
    settingValue("cluster.routing.allocation.balance.write_load");
final float diskUsageWeightFactor = 
    settingValue("cluster.routing.allocation.balance.disk_usage");
final float indexWeightFactor = 
    settingValue("cluster.routing.allocation.balance.index");

final float shardCountDeviation = numShardsOnNode - averageShardsPerNode;
final float writeLoadDeviation = totalWriteLoadOnNode - averageWriteLoadPerNode;
final float diskUsageDeviation = totalShardDiskUsageOnNode - averageShardDiskUsagePerNode;
final float indexDeviation = numIndexShardsOnNode - averageNumIndexShardsPerNode;

return shardCountDeviation * shardWeightFactor
    + writeLoadDeviation * writeLoadWeightFactor
    + diskUsageDeviation * diskUsageWeightFactor
    + indexDeviation * indexWeightFactor;<p>Shard movements are triggered to ensure that the difference in total node weight across cluster nodes remains below the <code>cluster.routing.allocation.balance.threshold</code> with a default value of <code>1</code>: whenever the threshold is exceeded, shards are moved from the most heavily weighted nodes to the least heavily weighted nodes until the difference between the most heavily weighted and least heavily weighted node is at or below the <code>threshold</code>. Whenever cluster activity occurs that changes shard allocation (e.g., create/delete index, add/remove node, or the disk usage grows), the Balancer rechecks the weights across nodes and triggers shard rebalancing if the delta between the most and least heavily weighted nodes exceeds the configured threshold. The threshold-based approach attempts to balance the trade-off between keeping the cluster perfectly balanced and minimizing shard movements. Large Elasticsearch deployments that use nodes with greater resources typically benefit from raising the <code>threshold</code> setting: a larger weight delta between nodes reduces shard rebalancing.</p><p>Shard movement is also constrained by strict shard assignment rules that prohibit certain node assignments according to cluster and index level settings. Examples include: not assigning copies of the same shard to the same node or host; not allowing further assignment of shards to a node that does not have spare disk space; and excluding node(s) as host for a particular index. More on this below.</p><h2>How a Balanced Cluster Looks (Based on Weights)</h2><p>Using the linear algorithm and cluster setting defaults previously described, the following is an example of what the Balancer considers balanced. Notably, it can sometimes allow considerable deviation across nodes in any one particular metric. For simplicity, index balance is not included.</p><p><em>Weight Node1 = 0</em>.45 (5 - 6) + 10 (0.3 - 0.33) + 2e-11 (1e+11 - 8e+10) =  <em> - 0.35</em></p><p><em>Weight Node2 </em>= 0.45 (7 - 6) + 10 (0.4 - 0.33) + 2e-11 (4e+10 - 8e+10) = <em>  0.35</em></p><p><em>Weight Node3 </em>= 0.45 (6 - 6) + 10 (0.3 - 0.33) + 2e-11 (1e+11 - 8e+10) = <em>  0.10</em></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt716ecf26a404be16/6a969bee0897906115efbc2d/2.png" alt="Weights-based shard balancing: three Elasticsearch data nodes with 5, 7 and 6 shards, differing disk usage and write load" /><h2>Limitations of Weights-Based Shard Allocation</h2><p>Elasticsearch Serverless deployments are managed by Elastic and could run into many edge cases that, without additional configuration, the weights-based shard allocation handles poorly. In self-managed Elasticsearch deployments, it is possible to work around many of these issues by configuring the cluster to suit the user’s workload. However, Elasticsearch Serverless is configured once and must work across all customer use cases. Issues experienced by some Elasticsearch customers (early adopters of Serverless among them) include:</p><ul><li><p>Continuous rebalancing background noise in active clusters. This could be because the <code>threshold</code> setting needs tuning or because the cluster is very busy.</p></li><li><p>The Balancer’s behavior cannot be tuned in a predictable manner. Adjusting the Balancer settings (individual weight factors) can lead to unpredictable outcomes due to the linear algorithm. For example, decreasing the shard count weight factor relative to the other weight factors can lead to data node OOM events when shard count balancing is deprioritized and too many shards pile up on a single node.</p></li><li><p>No explanation of why the Balancer is making shard moves. The linear algorithm is difficult to understand without relevant node metrics.</p></li><li><p>The linear algorithm allows a high value in one metric to cancel out a low value in another metric. For example, a node can have a higher than average (across cluster nodes) write load, but counterbalance with a lower than average shard count (or vice versa), and the linear algorithm cancels out the spikes: no shards are moved to address the write load hotspot.</p></li><li><p>Index-level hotspots can occur when a disproportionate number of index shards are assigned to the same node, rather than spreading out across nodes, despite the index balance weight in the linear algorithm. Index balance weight can, in some situations, be little compared to the other weight factors. It can also get skewed and counterbalanced by another non-average individual weight in the linear algorithm, as described in a previous bullet.</p></li><li><p>No search load balancing.</p></li><li><p>Regular indices do not have write load estimate support, leaving some write load hotspots unaddressed. Only data stream indices have write load estimates.</p></li><li><p>Write load hotspots can be missed. Write load estimates are only refreshed at rollover time, which can be infrequent in some configurations, causing new load to be ignored for some time. The write load is also the average write load activity over a potentially large window of time between index rollover events, so temporary write load increases can disappear when averaged with inactive write periods.</p></li></ul><p>The above issues persist in some Elasticsearch deployments and require monitoring and workload tuning to manage when they do occur. Shard allocation balancing in Elasticsearch Serverless aims to address these issues and avoid any manual intervention requirements using a new approach that is explained in subsequent sections of this article.</p><h2>Elasticsearch Serverless Shard Allocation </h2><p>Elasticsearch Serverless considers node resources individually: shards are rebalanced away from a node when any resource usage on that node grows to threaten performance, and shard movements to a node are declined when the assignment could threaten that node’s performance.</p><p>The Elasticsearch single combined score per node is replaced in Elasticsearch Serverless with independent per-resource decisions:</p><p>
</p><p><strong>Elasticsearch Weights-Based Balancing</strong></p><p><strong>Elasticsearch Serverless Resource-Aware Deciders</strong></p><p><strong>Decision Basis</strong></p><p>Single weighted sum across four metrics</p><p>Each resource evaluated independently</p><p><strong>Metric Interaction</strong></p><p>A high value can offset a low one</p><p>No offsetting; each decider acts separately</p><p><strong>Decision Types</strong></p><p><code>YES</code> / <code>NO</code></p><p><code>YES</code> / <code>NO</code> / <code>NOT_PREFERRED</code></p><p><strong>Rebalancing Trigger</strong></p><p>Weight delta across nodes exceeds <code>threshold</code></p><p>Individually configurable safe limits per resource</p><p><strong>Explainability</strong></p><p>Can only make an educated guess</p><p>Each move traces to a named decider</p><p>The Elasticsearch Balancer has three phases, in order of priority, for shard movement decisions. The first phase is to assign unassigned shards. Assignment of unassigned shards is the top priority for data availability reasons. The second phase is to move shards that can no longer remain where they are assigned due to cluster configuration changes. Internally, <code>AllocationDecider</code> implementations enforce cluster settings, like <a href="https://www.elastic.co/docs/reference/elasticsearch/index-settings/shard-allocation#index-allocation-filters">index-level shard allocation filtering</a>, <a href="https://www.elastic.co/docs/deploy-manage/distributed-architecture/shard-allocation-relocation-recovery/shard-allocation-awareness">shard allocation awareness</a>, <a href="https://www.elastic.co/docs/reference/elasticsearch/configuration-reference/cluster-level-shard-allocation-routing-settings#disk-based-shard-allocation">disk usage thresholds</a>, or moving shards off of a node before shutdown. The third phase rebalances shards when the <code>cluster.routing.allocation.balance.threshold</code> is exceeded, using the previously described weights algorithm.</p><p>The new Serverless balancing approach adds additional logic to the Balancer’s first and second phases, leveraging the existing <code>AllocationDecider</code> logic, and eliminates the third phase. Previously, each <code>AllocationDecider</code> had simple responses of <code>YES</code> and <code>NO</code>. Now, the decision type of <code>NOT_PREFERRED</code> has been added, along with several new <code>AllocationDecider</code> implementations. An <code>AllocationDecider</code> will return <code>NOT_PREFERRED</code> when it observes that performance might suffer from a shard’s assignment to a particular cluster node. The Serverless Balancer will prefer a node assignment for the shard where all <code>AllocationDecider</code> implementations reply <code>YES</code>.</p><p>A <code>NOT_PREFERRED</code> shard allocation may be left uncorrected if all other node assignments return <code>NO</code> or <code>NOT_PREFERRED</code>. Such responses mean that the shard cannot be assigned elsewhere without either violating a cluster/index rule or potentially degrading the performance of another cluster node. Serverless Autoscaling activates before all cluster nodes hotspot: even one unaddressable hotspot leads to a scale-up event. New <code>AllocationDecider</code> implementations have also been added for important finite resources, like available heap memory (further discussion below), using only the original <code>YES</code> and <code>NO</code> decisions: exceeding certain categories of resources can lead to node unavailability.</p><p>The individual weight metrics in the Balancer’s linear algorithm have been replaced by resource-aware <code>AllocationDecider</code> implementations, and new <code>AllocationDecider</code> implementations are being built for additional resources: Serverless Search Tier load-balancing improvements are currently in development. Each shard migration will have a clear purpose to address a potential resource usage bottleneck.</p><p>Internal stats have shown far fewer shard movements in general, without any noticeable accompanying node performance degradations – one workload showed a 50% reduction in shard movements with the same write throughput. Fewer shard movements has the benefit of: avoiding momentary read/write latencies from warming up local caches; and saving on cloud infrastructure costs moving data between servers.</p><h3>Serverless IndexBalanceDecider: Avoid Colocation of Index Shards</h3><p>The <code>IndexBalanceDecider</code> ensures index shard anti-affinity much more strictly than the original weights-based linear algorithm could achieve. Colocation of index shards in excess of the index’s average shards per available node is avoided, except in the case of a strict <code>NO</code> assignment (essentially non-existent right now in Serverless except for shutting down nodes and rolling upgrade incompatible version checks) or <code>NOT_PREFERRED</code> assignment due to temporary node hotspotting.</p><p>The <code>IndexBalanceDecider</code> is a very effective means of pre-balancing both write load and search load before user workloads begin to generate load statistics: each index begins life with its shards distributed across as many nodes as possible.</p><h4>IndexBalanceDecider Results: Even Write Load Distribution Across Cluster Nodes</h4><p>Write load across data nodes became much more evenly distributed after the <code>IndexBalanceDecider</code> was enabled in the Serverless Production environment. Projects fleet-wide generally show even ingest load (counted in saturated <code>WRITE</code> threadpool threads), combining the release of the <code>IndexBalanceDecider</code> and many other prior improvements:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb1d22b863724026b/6a969c19ecdaa7898505223b/4.png" alt="Ingestion load per data node across an Elasticsearch Serverless project, showing even write load distribution over time" /><p>A reproducible workload demonstrates a clear before and after view of the impact of the new <code>IndexBalanceDecider</code> when an ingest workload was run with and without it enabled:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb3788a358c3a3043/6a969c385c3126893d43ef2b/5.png" alt="Scale test ingestion load per node with the IndexBalanceDecider off then on, showing write load spread across data nodes" /><p>The <code>IndexBalanceDecider</code> also serves in the Serverless Search Tier to distribute shards of the same index as much as allowed, similarly limited only by the tier’s node count and the number of shards in each index.</p><h3>Serverless HeapUsageDecider: Assign Shards by Available Heap</h3><p>The <code>HeapUsageDecider</code> limits shard count on a node based on available heap to hold in-memory shard metadata and run associated write/read operations, removing the dependency on shard count limits per node. The <code>HeapUsageDecider</code> returns a strict <code>YES</code> or <code>NO</code> decision, rather than using the new <code>NOT_PREFERRED</code> decision type, because a data node risks an OOM event if the estimated available heap memory is exceeded.</p><h4>HeapUsageDecider Results: Reduced Data Node OOMs</h4><p>Data node OOMs in the serverless index tier decreased significantly as the <code>HeapUsageDecider</code> rolled out to the Serverless production environment.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5c28891290e3a635/6a969c88d04dac5ed56ca2f1/6.png" alt="Indexing OOM errors on Elasticsearch Serverless data nodes falling to near zero after the HeapUsageDecider rollout" /><p>Index tier OOM errors still occur from time to time in the Serverless Index Tier, though at a much reduced rate, as miscellaneous runaway memory usage edge cases are surfaced. The remaining OOM errors are being progressively resolved as they are identified, through a combination of memory usage improvements in the code, adding component level limits, and updating the internal Elasticsearch Serverless memory model service to more completely account for memory usage.</p><p>The <code>HeapUsageDecider</code> is not yet turned on in the Serverless Search Tier, due to the need for additional and different metrics, but that work is in active development.</p><h3>Serverless WriteLoadDecider: Prevent and Correct Write Load Hotspots</h3><p>The <code>WriteLoadDecider</code> receives periodically refreshed (every 30 seconds by default) per shard and per node write load stats and uses the data to correct and avoid write load hotspots. The master node retrieves stats directly from each data node’s write threadpool: an Elasticsearch node tracks the total time that its <code>WRITE</code> threadpools is in use, and each individual Elasticsearch shard instance tracks how much time it spent using its node’s <code>WRITE</code> threadpool.</p><p>A write load hotspot is identified at the node level. The criteria for a hotspot is the presence of <code>WRITE</code> threadpool queue latency above a configured threshold and sufficiently high, and sustained, <code>WRITE</code> threadpool thread saturation. Once that situation is detected, the Balancer is signaled to select shards to move away from a hotspotting node, until fresh non-hotspotting write load stats are received from the node. The Balancer will do nothing if all nodes are hotspotting at once, expecting the Autoscaler to solve the problem by introducing more, or bigger, data nodes to the cluster.</p><p>The <code>WriteLoadDecider</code> uses a heuristic to choose shards to move away from a hotspotting node that aims to minimize ingest disruptions while still effectively reducing a node’s write load. A shard write load <code>threshold</code> is identified on a hotspotting node: the <code>threshold</code> is currently calculated as ½ the ingest load of the hottest shard on that node. Shards that can be moved are then prioritized in the following order:</p><p><code>threshold</code><code> = ½ * </code><code>maxWriteLoadShardOnNode</code></p><ol><li><p>Shards with write load in the range [<code>threshold</code>, <code>maxWriteLoadShardOnNode</code>), the shard at or closest to threshold preferred.</p></li><li><p>Shards with write load in the range (<code>threshold</code>, <code>0</code>], the shard closest to threshold preferred.</p></li><li><p>Shards with write load equal to <code>maxWriteLoadShardOnNode</code>.</p></li><li><p>Shards with zero write load.</p></li></ol><p>The heuristic prefers to avoid disruption to the highest ingest shards and instead chooses middlingly loaded shards. Movement of the hottest shard will cause the most latency disruption; and movement of the coldest shards will be the least effective in resolving a hotspot.</p><p>The Balancer limits write load hotspot correction shard moves to one move per hotspotting node per stats refresh period, in order to see the effect of a move in real-time node-level write load, before attempting any further corrections. This was a simple initial design that proved effective. Furthermore, the Balancer will not move a shard whose write load alone is sufficient to meet the node-level hotspot criteria: this would just relocate a hotspot to another data node, not actually resolve the hotspot. The Serverless Autoscaler and Serverless Autosharding components are relied upon to resolve hotspots that reallocation of shards cannot.</p><p>The <code>WriteLoadDecider</code> returns <code>NOT_PREFERRED</code> when acceptance of a shard could cause a node to start experiencing <code>WRITE</code> threadpool queue latency and create a hotspot. A shard will still be relocated to a <code>NOT_PREFERRED</code> node, however, and risk some performance degradation, as a better option than, say, risking a data node OOM from keeping a shard on a data node where the <code>HeapUsageDecider</code> returns <code>NO</code>.</p><h4>WriteLoadDecider Results: Hotspots are Quickly Corrected </h4><p>Hotspot stats showed general improvement as the <code>WriteLoadDecider</code> was rolled out to Serverless production, in particular the fleet-wide time to correct a hotspot decreased greatly:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1e3ad68727d2121d/6a969cb28814aa3f7c89c987/7.png" alt="Write load hotspot duration p50, p95 and p100 in Elasticsearch Serverless dropping after the WriteLoadDecider rollout" /><p>Since these graphs were collected, additional work has been released incrementally to better prevent and correct hotspots, and improvements are still in progress.</p><h2>Serverless Autoscaling, Autobalancing, and Autosharding</h2><p>Elasticsearch Serverless relies on both new autobalancing logic and new autoscaling logic. The Serverless Balancer must sufficiently distribute shard resource usage across nodes in order to fully saturate the cluster’s resources. The Serverless Autoscaler will trigger a scale-up event when it receives a report that a certain percentage of the total cluster resources are in use and more resources are needed. The Autoscaler will not scale up the cluster if one node is hotspotting and another node has an excess of available resources because the resources are summed across nodes. Therefore, the Balancer must first do a good job on load distribution, and then the Autoscaler will activate as needed.</p><p>Autosharding based on write load is also in progress and coming soon to address shard hotspots. Elasticsearch Serverless projects have a default number of shards per index based on the project type. These defaults generally work, but do not account for all possible workloads. Hotspots can occur when an index has too few shards, as well as too many. Too few index shards leads to the Balancer being unable to further distribute an index’s write load across available data nodes, and then the Autoscaler will not see a problem because the cluster-level resources are not fully consumed. Conversely, indices cannot by default have too many shards, since that could degrade search performance for small indices and potentially strain cluster metadata operations if the total number of shards in a cluster grew too large.</p><h2>Production Example: 708 TB Data Set, 37 Index Tier Nodes (not counting Search Tier), 4,100 Indices, 30,000 Shards</h2><p>The following graphs cover a period when the Index Tier, in an Elasticsearch Serverless project, scales up from 10 to 37 indexing nodes and then back down to 10 after a write load spike dissipated.</p><h3>Graph of the Ingest Load Per Index Node</h3><p>This graph shows fairly even distribution of load, though a little less even temporarily during scale-up. There are nearly 250 fully saturated write threads at peak load. </p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6daf46a0823c4a37/6a969cd437d7f3a2008e9204/8.png" alt="Ingestion load per Elasticsearch Serverless index node, peaking near 250 saturated write threads during a load spike" /><h3>Graph of CPU Saturation Per Index Node</h3><p>CPU usage remains within safe bounds. Usage is mostly below 60%, except for momentary outliers that reach into the 90% range as write load rises before nodes are added to the cluster.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf60cff9da89290c9/6a969d203eabd090dd4409b4/9.png" alt="CPU usage per Elasticsearch Serverless data node, mostly below 60% with brief peaks above 90% during scale-up" /><h3>Graph of WRITE Threadpool Queue Latency Per Node </h3><p>When a node’s <code>WRITE</code> threadpool is fully saturated, tasks are placed in the threadpool’s queue. Queuing can happen with few tasks, if active write tasks are long-running, or there may simply be a lot of tasks.</p><p>This graph’s time window is zoomed in further than the others. One node reaches 75 seconds of queue latency during the scale-up spike. There are 29 nodes when the queue latency spike occurs at 19h25m, before autoscaling calls for 37 nodes at 19h28m.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9c16dbf83897366c/6a969d478814aa399089c98b/10.png" alt="Maximum WRITE threadpool queue latency per data node, with one Elasticsearch Serverless node reaching 75 seconds" /><h3>Graphs of Total Cluster Ingest per Second, in Documents and MBs</h3><p>Ingest rate peaks at 190,000 documents / second and 54.40MB / second. The document ingest rate is respectable at 4000-5000 docs/sec per node. The MBs ingest rate, however, is very low in this case: this can happen when indexing operations involve heavy computation. Document ingestion rate can also vary depending on the size of the documents.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8cec5b62e8339a7f/6a969d7e37d7f35c438e9208/12.png" alt="Total indexing request rate for an Elasticsearch Serverless cluster, peaking at 190,000 documents per second" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta9c147b7bd608b73/6a969dae5f9db76cd1560dc8/11.png" alt="Bulk byte indexing rate for an Elasticsearch Serverless cluster, peaking at 54.40 MB per second during the write spike" /><h2>What’s Next for Elasticsearch Serverless Balancing</h2><p>The team is currently working on shard balancing improvements for the Serverless Search Tier, focusing on creating metrics and <code>AllocationDecider</code> implementations for search performance. The team is excited to share these improvements soon!</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-shard-balancing-serverless</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-shard-balancing-serverless</guid>
    <category><![CDATA[Elastic Cloud Serverless]]></category>
    <category><![CDATA[Inside Elastic]]></category>
    <dc:creator><![CDATA[Dianna Hohensee]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltca84dead3c455000/6a969ba12707c589983290d7/1.png" length="0" type="image/png"/>
    <pubDate>Tue, 01 Sep 2026 15:25:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Your AI agent doesn't need your API key: OAuth 2.1 for Elasticsearch MCP server authentication]]></title>
    <description><![CDATA[OAuth 2.1 lets you connect AI agents to the Elasticsearch MCP server with a browser sign-in instead of an API key. Your agent gets a short-lived token tied to your permissions that you can revoke any time.]]></description>
    <content:encoded><![CDATA[<p>Claude Desktop, Cursor or any MCP host can now connect to your Elasticsearch data with a one-time browser sign-in. OAuth 2.1 is now GA for the <a href="https://www.elastic.co/docs/explore-analyze/ai-features/agent-builder/mcp-server">Agent Builder MCP server</a> in Elastic Cloud Serverless. Instead of pasting an API key into a config file, your agent gets a short-lived token tied to your permissions. Every connection can be audited individually and revoked without affecting anything else on your account. Refresh tokens roll for 30 days, so you rarely need to sign in again. Org owners can see exactly who authorized which agents, and Agent Builder is the first Elastic surface using this model, with the rest of the Elastic API to follow.</p><h2>Why OAuth is better than API keys for MCP server authentication</h2><p>With OAuth, tokens are short-lived credentials that expire on their own, so a leaked token is a narrowing window rather than a standing grant. Every token traces back to an explicit consent: which user, which client, which time.</p><p>In contrast, an API key is a long-lived credential. It lives in a configuration file on the machine that runs the agent, working for whoever uses it until someone rotates or deletes it. That model is manageable for a CI pipeline you wrote and deployed for your team. It gets uncomfortable when the key is held by an AI agent that assembles its own requests, retrieves untrusted content that may contain injected instructions, and sometimes passes context to sub-agents.</p><p>The failure mode is familiar from every credential-leak postmortem: the key ends up somewhere it shouldn't (a log file, a prompt), and from that moment anyone who has the key can access everything its creator could. The audit trail doesn't help much: API key logs tell you that a key with a given name did something, but not who authorized the client that used it or when.</p><p><strong>Attribute</strong></p><p><strong>OAuth 2.1</strong></p><p><strong>API Key</strong></p><p>Credential lifetime</p><p>Short-lived, auto-refreshing</p><p>Long-lived until manually rotated</p><p>Audit trail</p><p>User, client and timestamp per connection</p><p>Key name only</p><p>Revocation</p><p>Per connection, immediate</p><p>Requires key rotation</p><p>Blast radius</p><p>Single client connection</p><p>Everything the key creator can access</p><h2>How to set up OAuth 2.1 for the Elasticsearch MCP server</h2><p>Setup is a one-time step per project:</p><p>1. In your Elastic Cloud Serverless project, open Agent Builder → Tools library → MCP clients → Create MCP client (OAuth). This gives you a client ID and the MCP server URL.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt083d8f85c74de3e0/6a7db08bb8c2e6c02dbe5027/image8.png" alt="Agent Builder MCP clients page showing the Client ID and MCP server URL needed for OAuth setup in Elastic Cloud Serverless" /><p></p><p>2. Add the server to your MCP host. In Cursor or Claude Desktop, the configuration file entry looks like this:</p>{
  "mcpServers": {
        "kibana-mcp": {
          "command": "npx",
          "args": [
            "mcp-remote",    "https://&lt;your-project&gt;.kb.&lt;region&gt;.aws.elastic.cloud/api/agent_builder/mcp",
            "--static-oauth-client-info",
            "{\"client_id\":\"MYCLIENTID111\"}"
          ]
     }
   }
}<p>3. The first time the agent calls a tool, the host opens your browser on an Elastic Cloud consent screen. You sign in with your normal Elastic Cloud credentials and see what the agent is requesting access to.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte83792ca688a17df/6a7db0cac8b7ac2b925221e8/image1.png" alt="Elastic Cloud OAuth consent screen where a user authorizes an MCP client to access Agent Builder in a Serverless project" /><p>4. Click Authorize. This creates an <a href="https://www.elastic.co/docs/deploy-manage/app-connections">application connection</a> between you, your machine, and your project, and Elastic Cloud issues the agent a short-lived access token.</p><p>From there, your agent has access to your project’s data. The mechanics are invisible. When the access token expires, the host refreshes it using a refresh token with a 30-day rolling expiry, so you are not re-authenticating every hour. If you stop trusting a connection, open the application connections page in Elastic Cloud and revoke the connection. Both tokens die immediately, and nothing else about your account changes.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9ce697d344c24ebd/6a7db12a2888394e8707eaaa/image4.png" alt="Application connections page in Elastic Cloud showing an active OAuth MCP client connection with option to revoke access" /><p>The agent acts with the permissions of the user who consented. Calls to <a href="https://www.elastic.co/docs/explore-analyze/ai-features/agent-builder/tools">Agent Builder tools</a>, such as ES|QL queries, Workflows, and Streams, are evaluated based on your role. If you want an agent with less access than your own, authorize the connection as a user with a tighter role, or keep using a scoped API key for that workload. </p><h2>How to manage and revoke MCP server connections in Elastic Cloud</h2><p>Org owners can list every active application connection across an organization or a specific project: which MCP hosts were authorized, by whom, and when. Revocation is per connection, so cutting off one misbehaving agent does not disturb the authorizing user's account or any other integration. There is no shared credential to rotate and no blast radius beyond the one client.</p><p>This is the practical difference for teams. An OAuth app connection records who consented, to which client, and when. An API key log shows that <code>agent-key-3</code> queried an index, but not who authorized that agent. </p><h2>What's next for OAuth authentication across the Elastic API</h2><p>Agent Builder is the first Elastic surface behind OAuth, and the same authorization model will carry to the rest of the Elastic API surface, including Elasticsearch and Elastic Cloud management, as we work toward a single Elastic MCP endpoint.</p><p>To try it now, open Agent Builder in an Elastic Cloud Serverless project and create an OAuth client, or start with the <a href="https://www.elastic.co/docs/deploy-manage/app-connections/oauth-clients">documentation</a>. If you don't have a project yet, you can <a href="https://cloud.elastic.co/registration">start a free trial</a>.</p><p><em>The release and timing of any features or functionality described in this post remain at Elastic's sole discretion. Any features or functionality not currently available may not be delivered on time or at all.</em></p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-mcp-server-oauth-authentication</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-mcp-server-oauth-authentication</guid>
    <category><![CDATA[Agentic AI]]></category>
    <category><![CDATA[Elastic Cloud Serverless]]></category>
    <dc:creator><![CDATA[Alex Chalkias]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt08bd254292cdfc15/6a7dafffef5bef01744fa2be/image7.png" length="0" type="image/png"/>
    <pubDate>Thu, 13 Aug 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[17% faster search, zero config: auto-calibrating vector quantization in Elasticsearch]]></title>
    <description><![CDATA[Automatic calibration at merge time picks vector quantization parameters for each segment by predicting recall from a small sample. Here's how we built it into Elasticsearch's merge path.]]></description>
    <content:encoded><![CDATA[<p>Elasticsearch's <a href="https://www.elastic.co/search-labs/blog/diskbbq-elasticsearch-introduction">DiskBBQ</a> format (IVF clustering plus binary quantization, built for on-disk ANN search at scale) offers several knobs to shape the recall/cost tradeoff of an index. Automatic calibration seeks to optimize those knobs to achieve optimal performance.</p><p>In our <a href="https://www.elastic.co/search-labs/blog/vector-quantization-auto-calibration-elasticsearch">previous blog</a>, we laid out the statistical model behind that calibration: a manifold model for how nearest-neighbor distances scale with index size, a Gaussian error model for quantization noise, and a closed-form way to combine the two into an expected recall@k for a given rerank depth. If you haven't read it, the one thing you need going in is this: given a candidate quantization encoding and a rerank depth, we can predict recall@k without building an index and benchmarking it, by fitting two small models to a sample of the corpus.</p><p>In this post we’ll go through how to score candidate configurations cheaply and how to leverage that to make merge-time decisions that are themselves cheap, correct, and consistent across real, constantly-merging indexes. This led to some pretty impressive improvements: we see almost 17% average improvement in QPS across a broad range of datasets all while increasing recall (in one case by a factor of 3). What’s more you get this immediately by adding one line to your index options, <code>"auto_calibrate": true</code>, and our plan is to make this our default once it has had the chance to bake a bit.</p><h2>Why manual vector quantization tuning is unreliable</h2><p><code>bbq_disk</code> exposes several knobs: quantization bits for documents (1, 2, 4 or 7), a separate bit width for queries, an oversampling factor for reranking, and whether to <a href="https://www.elastic.co/search-labs/blog/elasticsearch-bbq-preconditioning-vectors">precondition</a> vectors before quantizing. None of these act independently, and their effect on recall depends on the data: a 4-bit/1-bit encoding might be plenty for one embedding model and clearly insufficient for another. A single index is also built out of many segments, merged over time, each with an eventually different vector distribution. Hand-tuning one configuration for an entire index is, at best, a compromise, which is the motivation for <a href="https://github.com/elastic/elasticsearch/pull/152894">automatic calibration</a>: let each segment have its own configuration, re-evaluated every time it is involved in a merge operation.</p><h2>How Elasticsearch runs auto calibration at merge time</h2><p>When a number of segments are merged and automatic calibration is enabled, Elasticsearch samples documents and queries from the vectors being merged and:</p><ol><li><p>fits the manifold model over a sequence of nested samples of the merged corpus;</p></li><li><p>fits the error model, predicting the quantization error's standard deviation for each candidate <code>(query bits, document bits, precondition)</code> combination;</p></li><li><p>sweeps candidate configurations in ascending cost order; the candidate encodings are <code>(1,1)</code>, <code>(4,1)</code>, <code>(4,2)</code>, <code>(4,4)</code> and <code>(7,7)</code> (query bits, document bits), each tried across oversampling factors of <code>1.25</code>, <code>1.5</code>, <code>1.75</code>, <code>2.0</code>, <code>2.5</code> and <code>3.0</code>;</p></li><li><p>estimates recall@10 for each candidate using the model described in our first post, and stops at the first (cheapest) configuration predicted to hit the target of 90% recall@10.</p></li></ol><p>The winning configuration (encoding, oversample factor, precondition flag) is stored directly in the segment's metadata, so it travels with the segment and is picked up automatically at query time unless a request explicitly overrides it.</p><p>Small segments skip this altogether: below 10,000 merged vectors, there isn't enough data to fit a reliable model, so Elasticsearch just uses the current DiskBBQ defaults (4-bit query / 1-bit document encoding, no preconditioning, 3x oversampling).</p><h2>How the vector quantization cost model works</h2><p>Following the principles described in our first post, we started by picking candidates with three nested loops that are essentially how you might imagine hand jamming a lookup table. Start with the quantization scheme as the outer loop, ordered cheapest to most expensive by document bits (<code>(1,1) → (4,1) → (4,2) → (4,4) → (7,7)</code>). Then we set the rerank depth within the middle loop, ordered shallow to deep (<code>1.25× → 3.0×</code>). Finally we set preconditioning within the inner loop (<code>off → on</code>).</p><p>That ordering has a cost model baked into it, it's just implicit rather than written down: exhaust every rerank depth at the current bit tier before ever trying more bits. Document bits were effectively the only resource priced as expensive; oversampling was treated as nearly free by comparison, since the sweep would always max out rerank depth on a cheap encoding before considering a pricier one.</p><p>The current implementation replaces that with an explicit, continuous cost function:</p>cost = document_bits + 1.3 × rerank_depth<p>Query bits still don't factor into cost at all, only document bits (which drive index size) and rerank depth (which drives how many candidates get rescored per query). Preconditioning also stays outside the formula: Elasticsearch runs the whole cost-ordered sweep once with preconditioning off, and only if nothing meets the recall target does it re-run the sweep with preconditioning on, treating it as a fallback lever rather than something priced bit-for-bit against the other two.</p><p>With this cost model, rerank depth costs noticeably more per unit than a document bit, so the sweep will often prefer stepping up a bit tier over pushing oversampling deeper.</p><p>The main reason for this is that once you're running in a serverless deployment, compute and storage are billed and scaled independently, on very different clocks. An extra document bit is mostly a one-time, indexing-time cost; it makes the segment marginally bigger on object storage, which is cheap and doesn't need to be pre-provisioned against a spike in query traffic. It does carry a smaller recurring cost too, since quantized vectors sitting in page cache or loaded for scoring take proportionally more RAM per document as bit width grows, but that scales linearly and predictably with corpus size, and doesn't spike with query load. Rerank depth is the opposite: it's a recurring, per-query cost. </p><p>Every extra unit of oversample factor means fetching and rescoring that many more full-precision candidate vectors from disk, on <em>every</em> search request, for as long as the index is queried. That's compute and DRAM pressure on the search-serving tier, which has to autoscale in close to real time to match query concurrency. It sits on the hot path of the latency-and-cost budget in a way storage capacity, and the RAM footprint of the bits themselves, does not. Weighting rerank depth higher than document bits in the cost formula is what makes the sweep reflect that asymmetry.</p><h2>Efficiently estimating vector quantization error</h2><p>The cost model above works with the premise that the recall estimate behind it is trustworthy. The manifold and error models need to be accurate for the recall assessment to be trustworthy. While the manifold model of the k-th to N-th nearest neighbors distance is cheap to compute, the standard deviation of the quantization noise for a given candidate encoding is a bit more expensive in principle.</p><p>DiskBBQ uses fixed count clusters to accelerate nearest neighbor queries. Our quantization procedure takes advantage of this by only quantizing the vector residuals from the cluster centroids. This means as the data scales, the magnitude of vectors we quantize relative to the various components of the similarity calculation shrinks. As such, quantization accuracy increases. We need to account for this when converting our sample estimates to the segment as a whole.</p><p>Clustering the corpus at several sample sizes and fitting how the error scales with cluster size requires re-clustering a real sample of the corpus at several different sizes and fitting a regression model to see how the error shrinks as the effective cluster size grows. We also add a conservative +3σ margin on top of the fitted estimate to guard against noise in the fit itself. This is accurate and appropriately cautious; however, while benchmarking on common dense retrieval datasets, we found that performing several hierarchical k-means passes per candidate was expensive.</p><p>To speed things up, we tried approximating residuals with a synthetic isotropic-Gaussian formula. Instead of clustering increasing-size samples, this approach generated synthetic residuals from the manifold model's local density estimate. It was fast and fit for background merges, with the full repeated clustering approach reserved for force-merges only. However, it turned out to inflate error when embeddings (residuals) are anisotropic (some directions carry a lot more variance than others). As a result, the estimated error could grow significantly on strongly anisotropic data (e.g., Fashion-MNIST-style image embeddings).</p><p>So instead we looked for a still fast but more accurate way of calculating residuals. We opted for using a single clustering pass over a smaller sample (2,048 vectors). The clustering runs once per merge and is then warm-started for every candidate encoding evaluated afterward, instead of re-clustering from scratch each time. To get the error's dependence on corpus size, which the baseline learns by re-clustering at multiple sizes, this approach instead reuses the manifold model's <code>invDim</code> as a <a href="https://web.stanford.edu/class/archive/stats/stats200/stats200.1172/Lecture17.pdf">plug-in</a> for that dependence, extrapolating from the single real measurement rather than fitting the size relationship separately. </p><p>We also trimmed the query sample used during calibration from 1,024 to 256 vectors, on the reasoning that a smaller sample is enough once the error is being measured from real data rather than synthesized (and validated by benchmarks). The net effect was comparable wall-clock cost to the synthetic residual formula it replaced, but grounded in real per-cluster residuals, accurate enough that force-merge and background merge could be unified onto one path.</p><p>As an example, we take five different benchmark datasets and calculate the quantization error <a href="https://en.wikipedia.org/wiki/Standard_deviation">standard deviation</a> (SD) by directly measuring the gap between exact and quantized dot products on a sample of real (or, for the synthetic residual formula, fabricated) residuals, then extrapolating that measurement to the full corpus size. They differ only in how much sampling and regression goes into that extrapolation: the multi-sample scaling fit sweeps fifteen sample sizes and fits how error scales with cluster size, the single-pass real residual measurement takes one larger real residual sample and reuses the manifold's intrinsic dimension to estimate the size dependency, and the synthetic residual formula skips real residuals altogether and samples from a synthetic Gaussian from the manifold's expected rank distance. We treat the multi-sample scaling fit as ground truth in this comparison because it's the most sample rich of the three, not because it's a zero variance measurement of the "true" corpus-wide error (it has its own sampling noise too). The table below summarises the methods and findings.</p><p>Method</p><p>How it works</p><p>Speed</p><p>Accuracy</p><p>When used</p><p>Multi-sample scaling fit</p><p>Clusters at 15 sample sizes, fits regression</p><p>Slow</p><p>	Gold standard</p><p>Ground truth baseline</p><p>Single-pass real residual</p><p>One clustering pass + manifold invDim plugin</p><p>Fast</p><p>Near gold standard</p><p>	Background + force merge</p><p>Synthetic residual formula</p><p>Gaussian from manifold density estimate</p><p>Fast</p><p>	Inflated on anisotropic data</p><p>Deprecated</p><p>In order to exchange methods, we only need to be confident that they agree. This question can be answered independently of the correctness of the actual estimates, which we verified in our <a href="https://www.elastic.co/search-labs/blog/vector-quantization-auto-calibration-elasticsearch">previous post</a> for the multi-sample scaling fit. The figures below report the predicted quantization SD and the predicted recall@10, which is influenced by how we estimate the error. We report the analytical recall the manifold model predicts as a function of the quantization parameters, given the estimated error distribution perturbing the true distance ordering. This way, we isolate the quantization error's effect on ranking from any separate recall loss the IVF index itself might introduce, which is a distinct error.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2ab129decffc7de5/6a6a33f15af6b78d878d6898/8e38157b97d3ab6ff0b8e711e7586c408e2368a8-2048x766.jpg" alt="Bar charts comparing vector quantization error estimation methods across five datasets for predicted recall and error std" /><p>The single-pass real residual measurement's calculated error SD is closer to the multi-sample scaling fit (our gold standard), with respect to the synthetic Gaussian residuals. Consequently, the predicted recall is closer when using the single-pass + manifold plugin method. Indeed, we found the models to be essentially interchangeable regarding the indexing decisions they lead to. Critically, we lower the calibration overhead by an order of magnitude.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt92f5f35bd60f01ec/6a6a33f20a222b3ff8877f36/2198ab91820a1f90fc70005dc27d7ae95c7ddb91-1744x1170.jpg" alt="Bar chart comparing wall-clock calibration time across three vector quantization error estimation methods and five datasets" /><h2>Auto calibration overhead on indexing performance</h2><p>We compared the cost of auto calibration on indexing, when compared with ES defaults, over 18 public benchmarks. We noticed that more than 50% of the datasets report an auto calibration overhead below 2%. Three datasets report 16-27% overhead, while two datasets sit in the 31-35% overhead.</p><p>The merge overhead is larger for smaller datasets (Fashion-MNIST, FiQA) that get indexed in a few seconds; that is expected as the size of the vector samples being used for calibration is fixed and therefore more noticeable with tiny datasets. In fact, for larger datasets like DBPedia-Entity and HotpotQA (5M doc vectors) the overhead is sometimes not noticeable and within 11% in the worst case.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt344490ae214fc84c/6a6a33f315fc5c197b9e4941/d73ffb22c77f669a0b4205cc2825bda7611494b9-1424x1256.jpg" alt="Bar chart showing auto-calibration indexing time overhead as a percentage across 18 vector quantization benchmark datasets" /><h2>What quantization parameters does auto calibration choose?</h2><p>Looking at the encoding auto-calibration landed on for each of the real datasets:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt085423af7a4831fd/6a6a33f4f3dc0ea46a6b78a2/527d33a1ac915bd84700447a936cd0113e84a856-2048x996.jpg" alt="Auto-calibration quantization parameter choices across 18 datasets: document bit-width and oversample depth distribution" /><p>Query bits were 4 in every dataset. While query bits aren't priced into the cost formula, we still iterate through lower query bits first (e.g., at 1 bit doc vectors, we first evaluate recall for 1 bit query vectors, then for 4 bit query vectors); so it’s possible for some datasets to even choose symmetric 1-bit quantization. The center of mass is a 2-bit document encoding with somewhere between 1.5x and 1.75x oversampling; 4-bit only shows up for two genuinely harder datasets (Fashion-MNIST's image embeddings, GIST-1M), and 1-bit only for a handful of the text-embedding models that are most robust to quantization. In fact, our own models are among those that quantize best: we selected 1 bit documents for all three corpuses we tested with <a href="https://www.elastic.co/search-labs/blog/jina-embeddings-v3-elastic-inference-service">Jina v3</a>.</p><h2>Recall and QPS improvements from automatic calibration</h2><p>Auto-calibration is a broad win across the eighteen datasets: QPS improves in 15 of 18 cases (often substantially, double digits on about ten, and over +50% on FiQA GTE, Fashion MNIST, and Glove-200), and recall improves in 15 of 18 cases too, including a dramatic +295.7% rescue on Fashion MNIST. Most datasets see gains on both metrics simultaneously, and even the more modest cases still land solidly positive, recall improvements are commonly in the high single digits to double digits, QPS gains follow a similar pattern. Where either metric does dip, the drops are small and contained: the three QPS regressions all stay under 1.5%, and the three recall regressions all stay under 2%.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbb5e4929226cdbff/6a6a33f440a4946b5dca5c9e/517b55375a9a4bfb81ed2bcf8a2a24757f5b0373-2048x1140.jpg" alt="QPS and recall percentage change from auto-calibrated vector quantization vs Elasticsearch defaults across 18 datasets" /><h2>How to enable auto-calibrated vector quantization in Elasticsearch</h2><p>The feature is not enabled by default for now, and opt-in via <code>auto_calibrate</code> on <code>bbq_disk</code> index options:</p>"index_options": {
    "type": "bbq_disk",
    "auto_calibrate": true
}<p>With this set, you no longer need to guess at bits, oversampling, or preconditioning: each segment picks the cheapest configuration that's predicted to hit 90% recall@10 for its own vector distribution, and re-evaluates that choice every time it's merged.</p><h2>What's next for automatic vector quantization in Elasticsearch</h2><p>Our <a href="https://www.elastic.co/search-labs/blog/vector-quantization-auto-calibration-elasticsearch">first post</a> showed that recall could be predicted in closed form from a small sample. Turning that into something running inside a real merge path meant a second round of engineering decisions that the model itself doesn't answer: how to order a sweep over candidates so it's cheap in the common case, how to price oversampling against document bits given how each is actually paid for at query time, and how to estimate the error term itself cheaply without quietly wrecking its accuracy.</p><p>In the end, we have a feature that allows us to tailor indexing choices to the data characteristics, with less than 11% overhead to index time for large indices. This gives us the ability to accurately control recall while optimizing quantization and oversampling choices for query performance. We got an average increase of 16.7% in QPS when we enabled this feature compared to our previous default settings for DiskBBQ. All while reliably achieving our target recall. Taking away the configuration burden from the user actually allows us to make better choices; it is a win-win.</p><p>This is the beginning of a longer journey that we’re working on to bring automatic configuration based on a combination of better understanding of the operating environment and better understanding of the data characteristics. We look forward to sharing more of this work with you in the near future.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/vector-quantization-auto-calibration-diskbbq</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/vector-quantization-auto-calibration-diskbbq</guid>
    <category><![CDATA[Vector Database]]></category>
    <category><![CDATA[ML Research]]></category>
    <category><![CDATA[Elastic Cloud Serverless]]></category>
    <dc:creator><![CDATA[Tommaso Teofili,Thomas Veasey]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcd9291668fb96d26/6a6a33f58c87dc83b00d067e/6f40d849745ffb10d753d47d76c12b4639213c90-2382x1326.png" length="0" type="image/png"/>
    <pubDate>Tue, 28 Jul 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Elasticsearch replicas for load balancing in Serverless]]></title>
    <description><![CDATA[Learn how Elastic Cloud Serverless automatically adjusts index replicas based on search load, ensuring optimal query performance without manual configuration.]]></description>
    <content:encoded><![CDATA[<p>In Elastic Cloud Serverless, we automatically adjust the number of replicas for your indices based on search load, ensuring optimal query performance without any manual configuration. In this blog, we’ll explain how replicas are scaled, when the system adds or removes them, and what this means for your indices.</p><h2>The party is getting crowded</h2><p>You're hosting a pizza party. You've got a few friends helping you serve, each stationed at different spots around the room. You give each friend a pizza, and they start handing out slices to hungry guests as they arrive.</p><p>At first, things run smoothly. A few guests trickle in, your friends serve slices, everyone's happy. But then word spreads about your sourdough pizzas. The doorbell keeps ringing. Guests pour in. Soon, there's a crowd forming around one of your friends, the one holding the pepperoni pizza, which everyone seems to want.</p><p>Your friend with the pepperoni pizza is overwhelmed. Guests are waiting, getting impatient, and a large queue has formed. Meanwhile, your friend holding the margherita pizza is standing around with barely anyone asking for a slice.</p><p>What do you do?</p><p>You order a couple more pepperoni pizzas and hand them to other friends. Now three friends are holding pepperoni instead of one. The crowd spreads out, and suddenly you can serve three times as many guests at once.</p><p>A few things become clear as you host more parties:</p><ul><li><p><strong>Not all pizzas are equally popular.</strong> Some are in high demand, others have fewer takers. You don't need extra "copies" of the unpopular ones. You need extras of the ones with queues.</p></li><li><p><strong>Order more pizzas before the queue gets too long.</strong> If you wait until your friend is completely overwhelmed and guests are leaving angry, you've waited too long. Better to get an extra pizza when you see a crowd forming.</p></li><li><p><strong>Don't throw away pizzas too quickly.</strong> Just because the crowd around the pepperoni thinned out for five minutes doesn't mean the rush is over. Maybe they're just refilling drinks, or even talking among themselves (is that still a thing?). Keep the extra pizzas ready. If the lull continues for a while, then you can put them away.</p></li><li><p><strong>You can only hand out as many pizzas as you have friends who are helping.</strong> If you've only got four friends helping, ten pizzas won’t change the outcome. Only four can be served at once. Match your pizza count to your available hands.</p></li><li><p><strong>When a friend leaves, take their pizza.</strong> If one of your friends needs to head out, grab their pizza immediately. You can't have pizzas sitting unattended. Hand it to someone else, or put it away.</p></li></ul><h2>From pizzas to replicas</h2><p>Let's map this back to Elasticsearch.</p><p>In our analogy, pizzas are replicas (copies of your index shards), your friends helping serve are search nodes, hungry guests are search queries, and that popular pizza with a crowd around it is a hot index with high search load.</p><p>When search traffic increases on a particular index, we create additional replicas and distribute them across your search nodes. Any replica can serve any query for that index, just like any friend holding pepperoni can hand out pepperoni slices. More replicas means higher throughput: Three replicas can handle three times the queries per second of a single replica.</p><h2>Measuring the hunger</h2><p>Before we decide how many pizzas to order, we need to know how hungry the crowd is.</p><p>Elasticsearch tracks the <strong>search load</strong> for every shard. It's a metric that captures how much search activity a shard is handling. We aggregate this across all shards of an index to understand the total search demand.</p><p>What matters most is the <strong>relative search load</strong>: What proportion of your project's total search traffic is hitting each index? If one index is receiving 60% of all searches while another gets 5%, we know where to add capacity.</p><h2>The math behind the pizzas</h2><p>We calculate the optimal number of replicas following this formula:</p>desired_replicas = min(ceil(L × N / (S × X)), N)<p>Where:</p><ul><li><p><strong>L</strong> = the index's relative search load (between 0 and 1).</p></li><li><p><strong>N</strong> = the number of desired search nodes in your project.</p></li><li><p><strong>S</strong> = the number of shards in the index.</p></li><li><p><strong>X</strong> = a threshold to avoid hot spots (default: 0.5).</p></li></ul><p>An example: four search nodes, one index with two primary shards receiving 80% of search traffic:</p>desired_replicas = min(ceil(0.8 × 4 / (2 × 0.5)), 4)
                 = min(4, 4)
                 = 4<p>This hot index gets four replicas distributed across the search nodes.</p><p>The threshold X (defaulting to 0.5) is important. We don't wait until a replica is completely overwhelmed; we scale up when it's at half capacity. Hand out the extra pizza when you see the crowd forming, not when guests are already leaving.</p><h2>Scale up fast, scale down slow</h2><p>When search load increases, we add replicas immediately. No reason to make users wait.</p><p>When search load drops, we wait a bit before taking any action. We need to see consistent low demand for about 30 minutes before reducing replicas. (This is to deal with spiky traffic where a quiet moment doesn't mean the party is over.)</p><p>This matters because adding a replica has a cost. The new replica copies data and warms its caches before serving queries efficiently. Removing replicas too eagerly means constantly paying this startup cost as traffic naturally fluctuates.</p><h2>Respecting topology bounds</h2><p>Replicas can never exceed the number of search nodes. Having more replicas than nodes provides no benefit (you can only serve as many pizzas as you have friends who are helping to serve slices).</p><p>When nodes are removed from your project, we reduce replicas immediately to match. No waiting for the cooldown, as you can't have unassigned replicas. The moment a friend leaves, we remove their pizza.</p><h2>The bigger Serverless picture</h2><p>Replicas for search load balancing works alongside other autoscaling systems:</p><ul><li><p><strong>Search autoscaling</strong> adjusts the number of search nodes (how many friends are helping).</p></li><li><p><strong>Replicas for search load balancing</strong> distribute traffic by adjusting replica counts per index (how many pizzas of each kind we need).</p></li><li><p><strong>Data stream autosharding</strong> optimizes shard counts for writes (how to slice each pizza, covered in the <a href="https://www.elastic.co/search-labs/blog/datastream-autosharding-serverless">previous post</a>).</p></li></ul><p>An important design principle: Replicas for load balancing don't directly trigger search autoscaling. Instead, by distributing search requests across more replicas, it enables increasing resource utilization across your search nodes. This higher utilization then triggers our existing autoscaling logic to add capacity if needed. Replicas for load balancing enables autoscaling to do its job, making sure your search nodes are actually being used, rather than having all traffic bottlenecked on a single replica while other nodes sit idle.</p><h2>What this means for you</h2><p>You don't need to predict which indices will be popular. You don't need to manually adjust replicas when traffic patterns change. You don't need to wake up at 3 a.m. because a surge overwhelmed your busiest index.</p><p>The system watches where queues are forming and orders more pizzas for those spots. Cold indices don't waste resources on unnecessary replicas. Hot indices get the capacity they need. Your budget goes where it matters.</p><h2>Conclusion</h2><p>In the <a href="https://www.elastic.co/search-labs/blog/datastream-autosharding-serverless">autosharding post</a>, we made sure your pizzas are sliced right. Now, with replicas for search load balancing, we make sure you have enough pizzas, in the right hands, when the hungry crowds arrive.</p><p>Try <a href="https://www.elastic.co/cloud/serverless">Elastic Cloud Serverless</a> and let us handle the pizza logistics.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-replicas-load-balancing-serverless</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-replicas-load-balancing-serverless</guid>
    <category><![CDATA[Elastic Cloud Serverless]]></category>
    <dc:creator><![CDATA[Andrei Dan]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte3b371b70b12b9ef/6a170f240e2e49999441a1de/3c4c1e99b892f026b7aba098973593f8298e2ea6-1280x717.png" length="0" type="image/png"/>
    <pubDate>Tue, 24 Mar 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[The stateless architecture of Elasticsearch Serverless]]></title>
    <description><![CDATA[Exploring the stateless architecture of Elasticsearch Serverless. Learn how the stateful architecture was transformed into stateless for Serverless.]]></description>
    <content:encoded><![CDATA[<p><strong>We're thrilled to announce</strong> the publication of our new peer-reviewed paper, <a href="https://doi.org/10.1145/3772052.3772245"><em><strong>Serverless Elasticsearch: the Architecture Transformation from Stateful to Stateless</strong></em></a><em><strong>,</strong></em> which was accepted and presented at the industrial track of the 2025 Association for Computing Machinery (ACM) Symposium on Cloud Computing (SoCC). The paper gives a concise view of our recent innovations in Elasticsearch. At Elastic, we’re relentlessly focused on the future of search. From optimizing performance to simplifying operations, our teams are always exploring what's next. </p><p>This paper isn't just an academic exercise. It's a foundational exploration of how the core of a search engine could be reimagined for a purely serverless world. We <a href="https://www.elastic.co/search-labs/blog/stateless-your-new-state-of-find-with-elasticsearch">decouple</a> storage from compute: Data lives in a cloud blob store with virtually infinite storage and scalability. That vision is the main driver behind our <a href="https://www.elastic.co/cloud/serverless">Elastic Cloud Serverless</a> offering: seamless search over massive datasets, with the economics and operational simplicity of serverless.</p><h2>The challenge: Rethinking stateful search for the cloud</h2><p>For decades, search engines have been powerful, stateful systems. Deploying a production-grade cluster like Elasticsearch has meant:</p><ul><li><p>Provisioning servers and managing storage.</p></li><li><p>Carefully tuning configurations for cost, performance, and reliability.</p></li><li><p>Paying for idle capacity when workloads are spiky or unpredictable.</p></li><li><p>Significant operational effort to scale up and down.</p></li></ul><p>Modern cloud platforms have made some of this easier, but the fundamental tension remains:</p><p><em>Can we build a search engine that delivers the power and rich query capabilities of Elasticsearch with the economics and operational simplicity of a serverless architecture?</em></p><p>That question drove our research.</p><h2>Our key contributions</h2><p>The paper presents concrete innovations that make Elasticsearch Serverless possible:</p><ul><li><p><strong>Object store as single source of truth: </strong>We offload index data, the transaction log (translog), and cluster state to a cloud object store. That eliminates replica shards for durability and makes the object store the sync point between indexing and search.</p></li><li><p><strong>"Thin" (stateless) shards: </strong>Shards recover and relocate quickly across nodes without copying large amounts of data. Disks are used only for caching, not for persistent storage.</p></li><li><p><strong>Batched compound commits (BCC): </strong>We wrap index commits in a custom format, cutting upload costs, while keeping the same read-after-write semantics as Elasticsearch.</p></li><li><p><strong>Batched translog uploads: </strong>Translog uploads are batched at the node level, cutting upload costs.</p></li><li><p><strong>Smart garbage collection:</strong> We track the usage of BCCs and translogs we’ve uploaded, and we delete them once they’re unused, to reduce storage footprint and retention costs.</p></li><li><p><strong>Autoscaling: </strong>We scale automatically with ingestion and search load so clients can call APIs without managing cluster size.</p></li></ul><p><strong>The bottom line:</strong> In our experiments, Elasticsearch Serverless achieves up to <strong>twice</strong> the indexing throughput of stateful Elasticsearch on comparable hardware and scales linearly with autoscaling to match ingestion load.</p><h2>Visualizing the architecture</h2><p>Figure 1 in the paper gives a clear side-by-side view: stateful Elasticsearch versus the new stateless architecture Elasticsearch Serverless.</p><p><strong>Stateful Elasticsearch (top):</strong> Familiar data tiers: hot, warm, cold, frozen. Data lives on local disks; primaries and replicas are spread across nodes; colder tiers may use searchable snapshots on an object store.</p><p><strong>Elasticsearch Serverless</strong> <strong>(bottom):</strong> Just two tiers: <strong>indexing</strong> and <strong>search</strong>. All durable data (Lucene commits, translogs, cluster state) lives in the object store. Indexing nodes write and upload; search nodes read from the object store and a shared cache, with no local persistence of index data.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt991c8013cfaf4be0/6a1703fddc55dedcbee00cc1/c4ca8c725cc60c06625cee3b5d1045c42367c166-1080x1116.png" alt="Elasticsearch architecture with data tiers (above), and new serverless Elasticsearch architecture separating storage from compute." /><p>The takeaway: <em>a complete separation between the resources used for indexing and those used for querying.</em></p><h2>A tale of two data flow paths</h2><p>Figures 2 and 3 in the paper contrast how data flows in stateful versus Elasticsearch Serverless.</p><p><strong>Stateful Elasticsearch </strong>(figure 2):</p><ul><li><p>Documents go to the primary shard's Lucene buffers and translog and then to replica shards.</p></li><li><p>After refresh, the documents go to new searchable segments.</p></li><li><p>After flush, they’re committed to disk.</p></li><li><p>Thus, durability is given by the disk and the replicas.</p></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt54ff3d8e7e4a4cc0/6a1703fea6c2b9e933e795cb/eed45de365b8475b8f258342d344ad71491d39e4-1088x1022.png" alt=" Index logs Alt text: An index with a primary and replica shard. Docs are: a) added to the primary's Lucene and the translog; b) forwarded to the replica; c) refreshed to a new searchable segment; and d) committed to disk upon flush." /><p><strong>Elasticsearch Serverless </strong>(figure 3):</p><ul><li><p>Documents go to Lucene and the translog on an indexing node.</p></li><li><p><em>Before</em> acknowledging the client, the translog is uploaded to the object store.</p></li><li><p>After refresh, the documents go to new searchable segments and are committed to disk in the indexing nodes.</p></li><li><p>After flush, they go into BCCs and are uploaded to the blob object store.</p></li><li><p>Search nodes serve queries from the object store (and, for recent data not yet uploaded, directly from the indexing node).</p></li><li><p>Thus, durability comes from the object store, not from disk or replicas.</p></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7a263135d14af80c/6a170400509168939fe1b9a5/5374213dbac9c84e0d672045f663582b25f57e7a-1090x986.png" alt="In Elasticsearch Serverless, docs are: a) added to Lucene and the translog; b) uploaded to the object store before ack'ing the client; c) refreshed into a new committed segment; d) searched via the network while not uploaded; e) uploaded as a BCC upon flush; and f) truncating unnecessary translogs." /><p>Result: <em>The indexing and search paths are fully decoupled</em>.</p><h2>Autoscaling</h2><p>Section 7 of the paper describes the autoscaler. Because data lives in the object store, relocating shards doesn't mean copying full segment data; only metadata and, when needed, cache warming. So the cluster can scale up and down <em>much</em> faster than in stateful Elasticsearch.</p><p>How it works:</p><ul><li><p>The autoscaler is an external component that monitors metrics from Elasticsearch Serverless.</p></li><li><p><strong>Indexing tier:</strong> Scale-up is driven by memory usage and ingestion load (including queued work).</p></li><li><p><strong>Search tier:</strong> Scale-up is driven by memory, search load, and the user-configurable "search power" (how much of the dataset is cached locally).</p></li><li><p>It polls every few seconds and adjusts each tier independently.</p></li></ul><p>Outcome: <em>automatic, workload-driven scaling so clients can focus on their applications instead of on capacity planning</em>.</p><h2>The experimental results</h2><p>Section 8 of the paper presents our experimental evaluation.</p><p><strong>Microbenchmarks</strong> show the impact of batching: fewer object store operations for both commits and translogs, with some trade-offs.</p><p><strong>Autoscaling experiments:</strong> As we increase the number of indexing clients, throughput scales linearly while P50 and P99 latency stay stable. A real-world example shows bulk response times improving and stabilizing as the indexing tier scales up with demand.</p><p><strong>Head-to-head comparison of stateful Elasticsearch versus Elasticsearch </strong>Serverless<strong>:</strong></p><ul><li><p>Elasticsearch Serverless achieves roughly <strong>twice</strong> the indexing throughput of stateful Elasticsearch at the 50th percentile.</p></li><li><p>The gain comes largely from using the object store for durability instead of replicating every operation to replica shards.</p></li><li><p>Latency stays competitive.</p></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt681fff38c7d4a49d/6a170402839dfa6661dcfdb6/353ca1e865535e7211d22547a0d9eaa60e47b4aa-1084x578.png" alt="The throughput and latency of Elasticsearch, with different shards, versus Elasticsearch Serverless, which uses autosharding." /><p>The takeaway: <em>The stateless design delivers both better peak performance and more efficient, automatic scaling.</em></p><h2>Why this matters for the future of Elastic</h2><p>The stateless architecture isn't just a technical achievement; it's the foundation for how we want search to work in the cloud.</p><ul><li><p><strong>Pay-as-you-go:</strong> Customers can index and search over practically limitless data without provisioning clusters, tuning tiers, or managing replicas and snapshots.</p></li><li><p><strong>Automatic scaling: </strong>Each tier scales on its own automatically; no capacity planning required.</p></li><li><p><strong>Frequent, automated upgrades:</strong> Better security and time-to-value, without the operational cost of rolling upgrades over stateful data.</p></li></ul><p>This work is a step toward making powerful search more accessible, cost-effective, and scalable for everyone.</p><h2>Read the full paper, and join the conversation</h2><p>We believe in the power of open research and collaboration to move technology forward. We encourage you to dive into the details. We provide a <a href="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt231e84167c46f87e/6ab3e3efa70e8f7a2cf29121/socc25-p217-preprint-do-not-share.pdf">preprint of this paper</a> for your information, which details in depth the architecture transformation.</p><h2>Dive deeper: Explore related blog posts</h2><p>While our paper offers a concise overview of the Elasticsearch Serverless architecture, the details and underlying innovations are explored more fully in a collection of in-depth blog posts written by our engineering team. These articles provide the background, nuance, and specific technical deep dives that make the stateless transformation possible.</p><p>We encourage you to delve into the following resources to gain a richer understanding of the components and concepts presented in the paper:</p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/stateless-your-new-state-of-find-with-elasticsearch">Stateless — your new state of find with Elasticsearch (2022)</a> and <a href="https://www.elastic.co/blog/elastic-serverless-architecture">Serve more with Serverless (2023)</a>. Read the foundational posts introducing the concept of decoupling storage and compute.</p></li><li><p><a href="https://www.elastic.co/search-labs/blog/data-safety-stateless-elasticsearch">Stateless: Data safety in a stateless world (2024).</a> Learn how data durability is achieved in the absence of local replicas.</p></li><li><p><a href="https://www.elastic.co/search-labs/blog/datastream-autosharding-serverless">Autosharding of data streams in Elasticsearch Serverless (2024).</a> Discover the logic behind automatic and dynamic data stream sharding.</p></li><li><p><a href="https://www.elastic.co/search-labs/blog/elasticsearch-refresh-costs-serverless">How we optimized refresh costs in Elasticsearch Serverless (2024).</a> Understand the specific optimizations applied to reduce the cost of making data searchable.</p></li><li><p><a href="https://www.elastic.co/search-labs/blog/thin-indexing-shards-elasticsearch-serverless">Introducing Serverless Thin Indexing Shards (2024).</a> Explore the innovation of "thin" shards that enable rapid relocation and recovery.</p></li><li><p><a href="https://www.elastic.co/search-labs/blog/elasticsearch-serverless-tier-autoscaling">Search tier autoscaling in Elasticsearch Serverless (2024).</a> Gain insight into the mechanisms driving the automatic scaling of search resources.</p></li><li><p><a href="https://www.elastic.co/search-labs/blog/elasticsearch-ingest-autoscaling">Ingest autoscaling in Elasticsearch (2024).</a> Learn how the ingestion tier scales automatically to meet fluctuating indexing load.</p></li><li><p><a href="https://www.elastic.co/blog/elastic-cloud-serverless-pricing-packaging">Elastic Cloud Serverless pricing and packaging (2025)</a>. Learn how the pricing and packaging was initially structured for Elastic Cloud's Serverless offering.</p></li><li><p><a href="https://www.elastic.co/blog/elasticsearch-opensearch-performance-gap">Elasticsearch vs. OpenSearch: Unraveling the performance gap (2023)</a>. Learn about the performance differences and key optimizations that distinguish Elasticsearch from OpenSearch, as observed in 2023.</p></li></ul><h2>Acknowledgments</h2><p>We would like to thank all the co-authors of the paper: Iraklis Psaroudakis, Pooya Salehi, Jason Bryan, Francisco Fernández Castaño, Brendan Cully, Ankita Kumar, Henning Andersen, and Thomas Repantis. We would also like to thank the Elasticsearch Distributed Systems team for their contributions, and also the entire Elasticsearch engineering team.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-serverless-stateless-architecture</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-serverless-stateless-architecture</guid>
    <category><![CDATA[Elastic Cloud Serverless]]></category>
    <dc:creator><![CDATA[Iraklis Psaroudakis]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt464f8e5c0f543a57/6a170404b0367d756f72bc06/5ce3d804dd4652ce2114ce6a20f53cb41e5826c5-1396x812.png" length="0" type="image/png"/>
    <pubDate>Thu, 12 Mar 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Autosharding of data streams in Elasticsearch Serverless]]></title>
    <description><![CDATA[In Elastic Cloud Serverless we spare our users from the need to fiddle with sharding by automatically configuring the optimal number of shards for data streams based on the indexing load.]]></description>
    <content:encoded><![CDATA[<h2>How Elastic Cloud Serverless autosharding works</h2><ol><li><p><strong>Monitors indexing write load: </strong>Elasticsearch continuously tracks the <code>write_load </code>metric, representing the average number of write threads used for indexing. This metric informs sharding decisions.</p></li><li><p><strong>Calculates optimal shard count: </strong>The system uses a formula that considers the current <code>write_load</code>, the minimum and maximum write threads available per node, to determine the ideal number of shards. This balances performance with overhead.</p></li><li><p><strong>Triggers rollover based on write load:</strong> When the <code>write_load</code> necessitates a shard increase, a rollover operation is triggered. This creates a new index in the data stream with the calculated optimal number of shards. Regular rollover conditions (like shard size) also trigger rollovers, potentially leading to shard reduction if the <code>write_load</code> is lower.</p></li><li><p><strong>Applies cooldown periods: </strong>To prevent rapid shard adjustments, cooldown periods are enforced. There's a 4.5-minute wait before increasing shards and a 3-day wait before reducing them.</p></li><li><p><strong>Autoscaling integration: </strong>Autosharding works in conjunction with autoscaling. By dynamically adjusting shard counts, autosharding enables autoscaling to more effectively increase resources as needed, preventing the system from being constrained at low capacity during high indexing workloads. It also enables autoscaling to more effectively increase resources as needed, preventing the system from being constrained at low capacity during high indexing workloads.</p></li></ol><h2>Background</h2><p>Traditionally, users change the sharding configuration of data streams in order to deal with various workloads and make the best use of the available resources. In <a href="https://www.elastic.co/docs/current/serverless">Elastic Cloud Serverless</a> we've introduced autosharding of data streams, enabling them to be managed and scaled automatically based on indexing load. </p><p>This post explores the mechanics of autosharding, its benefits, and its implications for users dealing with variable workloads. The autosharding philosophy is to increase the number of shards aggressively and reduce them very conservatively, such that an increase in shards is not followed prematurely by a reduction of shards due to a small period of reduced workload.</p><h2>Autosharding of data streams in Serverless Elasticsearch</h2><p>Imagine you have a large pizza that needs to be shared among your friends at a party. If you cut the pizza into only two slices for a group of six friends, each slice will need to serve multiple people. This will create a bottleneck, where one person hogs a whole slice while others wait, leading to a slow sharing process. Additionally, not everyone can enjoy the pizza at the same time; you can practically hear the sighs from the friends left waiting. If more friends show up unexpectedly, you’ll struggle to feed them with just two slices and find yourself scrambling to reshape those slices on the spot.</p><p>On the other hand, if you cut the pizza into 36 tiny slices for those same six friends, managing the sharing becomes tricky. Instead of enjoying the pizza, everyone spends more time figuring out how to grab their tiny portions. If the slices are too small, the pizza might even fall apart.</p><p>To ensure everyone enjoys the pizza efficiently, you’d aim to cut it into a number of slices that matches the number of friends. If you have six friends, cutting the pizza into 6 or 12 slices allows everyone to grab a slice without long waits. By finding the right balance in slicing your pizza, you’ll keep the party running smoothly and everyone happy.</p><p>You know it’s a good analogy when you immediately follow-up with the explanation; the pizza represents the data, the slices represent the index shards, and the friends are the Elasticsearch nodes in your cluster.</p><p>Traditionally, users of Elasticsearch had to anticipate their indexing throughput and manually configure the number of shards for each <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/data-streams.html">data stream</a>. This approach relied heavily on predictive heuristics and required ongoing adjustments based on workload characteristics whilst also balancing <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/size-your-shards.html">data storage, search analytics, and application performance</a>.</p><p>Businesses with seasonal traffic, like retail, often deal with spikes in data demands, while IoT applications can experience rapid load increases at specific times. Development and testing environments typically run only a few hours a week, making fixed shard configurations inefficient. New applications might struggle to estimate workload needs accurately, leading to potential over- or under-provisioning.</p><p>We've introduced autosharding of data streams in <a href="https://www.elastic.co/docs/current/serverless">Elastic Cloud Serverless</a>. Data streams in <a href="https://www.elastic.co/docs/current/serverless">Serverless</a> are managed and scaled automatically based on indexing load - automatically slicing your pizza as friends arrive to your party or finish eating.</p><h2>The promise of autosharding</h2><p>Autosharding addresses these challenges by automatically adjusting the number of shards in response to the current indexing load. This means that instead of users having to manually tweak configurations, Elasticsearch will dynamically manage shard counts for the data streams in your project based on real-time data traffic.</p><p>Elasticsearch keeps track of the indexing load for every index as part of a metric named write load, and exposes it for on-prem and ESS deployments as part of the <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-stats.html">index stats API</a> under the indexing section.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbf8a17014280842a/6a170cf55091687333e1bb3e/b83c902ebadc04d7e0e0a794b6b2ec925b0f4cb4-1200x1600.png" alt="Autosharding in Elasticesarch:  indexing load " /><p>The <code>write_load</code> represents the average number of write threads used while indexing documents.</p><p>For an index with one shard the maximum possible value of the <code>write_load</code> metric is the number of write threads available (e.g. all write threads are busy writing in the same shard).</p><p>For indices with multiple shards the maximum possible value for the write load is the number of write threads available in a node times the number of indexing nodes in the project. (e.g. all write threads on all the indexing nodes that host a shard for our index are busy writing in the shards belonging to our index, exclusively)</p><p>To get a sense of the values allowed for <code>write_load</code> let’s look at index <code>logs</code> with one shard running on one Elasticsearch machine with 2 <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-threadpool.html#node.processors%60">allocated processors.</a> The <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-threadpool.html">write thread pool</a> will be sized to 2 threads. This means that if this Elasticsearch node is exclusively and constantly writing to the same index <code>logs</code>, the <code>write_load</code> we’ll report for index <code>logs</code> will be <strong>2.0</strong> (i.e. 2 write threads fully utilized for writing into index <code>logs</code>).</p><p>If <code>logs</code> has 2 primary shards and we’re now running on two Elasticsearch nodes, each with 2 <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-threadpool.html#node.processors">allocated processors</a> we’ll be able to get a maximum reported <code>write_load</code> of <strong>4.0 </strong>if all write threads on both Elasticsearch nodes are exclusively writing into the <code>logs</code> index.</p><h3>Serverless autoscaling</h3><p>We just looked at how the write load capacity doubled when we increased the number of shards and Elasticsearch nodes. <a href="https://www.elastic.co/docs/current/serverless">Elastic Cloud Serverless</a> takes care automatically of both these operations using data stream autosharding and <a href="https://www.elastic.co/search-labs/blog/elasticsearch-ingest-autoscaling">ingest autoscaling</a>. Autoscaling refers to the process of dynamically adjusting resources - like memory, CPU, and disk - based on current demands.</p><p>In our serverless architecture, we start with a small 2GB memory server and use a step-function scaling approach to increase capacity efficiently. We scale up memory incrementally and then scale out by adding servers. This cycle continues, increasing memory per server incrementally up to 64GB while managing the number of servers.</p><h4>Linking autoscaling and autosharding</h4><p>The connection between auto<strong>scaling</strong> and auto<strong>sharding</strong> is essential for optimizing performance. When calculating the optimal number of shards for a data stream, we consider the minimum and maximum number of available write threads per node in our scaling setup.</p><ul><li><p>For small projects, the system will move from 1 to 2 shards when the data stream uses more than half the capacity of a node (i.e., more than one indexing thread).</p></li><li><p>For medium-sized projects, as the system scales across multiple nodes, it will not exceed 3 shards to avoid excessive overhead.</p></li><li><p>Once we reach the largest node sizes, further sharding is enabled to accommodate larger workloads.</p></li></ul><p>Autosharding also enables autoscaling to increase resources as needed, preventing the system from staying at low capacity during high indexing workloads, by enabling projects to reach higher ingestion load values.</p><h3>Auto sharding formula</h3><p>To determine the number of shards needed, we use the following formula:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt93cb63543b31d1b3/6a170cf660084b4d273c45c4/2185640ab125aaf4cd300fbaff74b3d83cf0de31-667x275.png" alt="Autosharding formula in Elasticsearch" /><p>This equation balances the need for increasing shards based on <code>write_load</code> while capping the number of shards to prevent oversharding. The division by 2 reflects the strategy of increasing shards only after exceeding half the capacity of a node. The min/max write threads represent the minimum and maximum number of write threads available in the autoscaling step function (i.e. the number of write threads available on the smallest 2GB step and the number of write threads available on the largest server)</p><p>Let’s visualize the output of the formula:</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd5ebade9321a608b/6a170cf8ab7f085179db9ef7/ca928d959397c42a57311a91269d5418e983609a-1600x986.png" alt="Output of autosharding formula formula in Elasticsearch" /><p>On the Y axis we have the <strong>number of shards</strong>. And on the X axis we have the<strong> write load</strong>. We start with 1 shard and we get to 3 shards when the write load is just over 3.0. We remain with 3 shards for quite some time until the write load is about 48.0.</p><p>This covers us for the time we scale up through the nodes but haven’t really got to 2 or more or the largest servers, at which point we unlock auto sharding to more than 3 shards, as many as needed to ingest data.</p><p>While adding shards can improve indexing performance, excessive sharding in an Elasticsearch cluster can have negative repercussions - imagine that pizza with 56 slices being shared by only 7 friends. Each shard carries overhead costs, including maintenance and resource allocation. Our algorithm accounts for and avoids the peril of excessive sharding until we get to the largest workloads where adding more than 3 shards makes a material difference to indexing performance and throughput.</p><h3>Implementing autosharding with rollovers</h3><p>The implementation of autosharding relies on the concept of <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-rollover-index.html">rollover</a>. A rollover operation creates a new index within the <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/data-streams.html">data stream</a>, promoting it to the write index while designating the previous index as a regular backing index, which no longer accepts writes. This transition can occur based on specific conditions, such as exceeding a shard size of 50GB. We take care of configuring the <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/data-stream-lifecycle-settings.html#_cluster_level_settings_3">optimal rollover conditions</a> for data streams in <a href="https://www.elastic.co/docs/current/serverless">Serverless</a>.</p><p>In <a href="https://www.elastic.co/docs/current/serverless">Serverless</a> alongside the usual rollover conditions that relate to maintaining healthy indices and shards we introduce a new condition that evaluates whether the current write load necessitates an increase in shard count. If this condition is met, a rollover will be triggered and the new resulting data stream <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/data-streams.html#data-stream-write-index">write index</a> will be configured with the optimal number of shards.</p><p>For downscaling, the system will monitor the workload and will not trigger a rollover solely for reducing shards. Instead, it will wait until a regular rollover condition, like the primary shard size, triggers the rollover. The resulting write index will be configured with a lower number of shards.</p><h3>Cooldown periods for shard adjustments</h3><p>To ensure stability during shard adjustments, we implement cooldown periods:</p><ul><li><p><strong>Increase shards cooldown</strong>: A minimum wait time of 4.5 minutes is enforced before increasing the number of shards since the last adjustment. The 4.5 minutes cooldown might seem peculiar but the interval has been chosen to make sure we <strong>can </strong>increase the number of shards every time <a href="https://www.elastic.co/search-labs/blog/data-lifecycle-simplified-for-data-streams">data stream lifecycle</a> checks if data streams should rollover (currently, every 5 minutes) but not more often than 5 minutes, covering for internal Elasticsearch cluster reconfiguration.</p></li><li><p><strong>Decrease shards cooldown</strong>: We maintain a 3-day minimum wait time before reducing shards to ensure that the decision is based on sustained workload patterns rather than temporary fluctuations.</p></li></ul><h2>Conclusion</h2><p>The data streams autosharding feature in <a href="https://www.elastic.co/docs/current/serverless">Serverless</a> Elasticsearch represents significant progress in managing data streams effectively. By automatically adjusting shard counts based on real-time indexing loads, this feature simplifies operations and enhances scalability.</p><p>With the added benefits of <a href="https://www.elastic.co/search-labs/blog/elasticsearch-ingest-autoscaling">autoscaling</a>, users can expect a more efficient and responsive experience, whether they are handling small projects or large-scale applications. As data workloads continue to evolve, the adaptability provided by auto sharding ensures that Elasticsearch remains a robust solution for managing diverse indexing needs.</p><p>Try out our <a href="https://www.elastic.co/docs/current/serverless">Serverless</a> Elasticsearch offering to take advantage of data streams auto sharding and observe the indexing throughput scaling seamlessly as your data ingestion load increases.</p><p>Your pizzas will be optimally sliced as more friends arrive at your party, keen to try those sourdough craft pizzas you prepared for them.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/datastream-autosharding-serverless</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/datastream-autosharding-serverless</guid>
    <category><![CDATA[Elastic Cloud Serverless]]></category>
    <dc:creator><![CDATA[Andrei Dan]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt84da396c370b06ec/6a170cfa6234e00dd3db1a55/d92e2e9fbae1dca1f18e623b2f5eb2a835307130-1600x1066.jpg" length="0" type="image/jpeg"/>
    <pubDate>Tue, 10 Dec 2024 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[How we optimized refresh costs in Elasticsearch Serverless]]></title>
    <description><![CDATA[We explore how serverless Elasticsearch facilitates searches using data stored in a blob store while maintaining the same visibility semantics as stateful Elasticsearch. We discuss the challenges encountered during implementation and share strategies for balancing costs and complexity.]]></description>
    <content:encoded><![CDATA[<p>Recently, we’ve <a href="https://www.elastic.co/blog/search-ai-lake-elastic-cloud-serverless">launched</a> the Elastic Cloud Serverless offering that aims to provide a seamless experience to run search workloads in the cloud. To launch this, we’ve rearchitected Elasticsearch to <a href="https://www.elastic.co/search-labs/blog/stateless-your-new-state-of-find-with-elasticsearch">decouple</a> storage from compute, where data is stored in a cloud blob store that provides virtually infinite storage and scalability. In this blog post, we’ll dive into how we removed a strong relationship between the number of indices and the number of object store calls, allowing us to improve UX and reduce costs at the same time.</p><p>Before we dive into the changes we made, it’s essential to first understand the interplay between Elasticsearch and Lucene.</p><p>Elasticsearch uses Lucene, a high-performance, open-source library written in Java, for full text indexing and search. When a document is indexed into Elasticsearch, it isn't immediately written to disk by Lucene. Instead, Lucene updates its internal in-memory data structures. Once enough data accumulates or a <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-refresh.html">refresh</a> is triggered, these documents are then written to disk, creating a new set of immutable files known as segments in Lucene terminology. The indexed documents are not available for search until the segments are written to disk. That’s the reason why <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-refresh.html">refresh</a> is such an important concept in Elasticsearch. You might be wondering how durability is ensured when documents are kept in memory until a refresh is triggered. This is achieved through the Translog, which stores durably every operation to guarantee data persistence and recovery in case of failure.</p><p>Now that we know what Lucene segments are and why refreshes are needed in Elasticsearch, we can explore how refresh behavior differs between stateful Elasticsearch and <a href="https://www.elastic.co/search-labs/blog/stateless-your-new-state-of-find-with-elasticsearch">serverless Elasticsearch</a>.</p><h2>Refreshes in stateful Elasticsearch</h2><p>In Elasticsearch, indices are divided into multiple shards, each consisting of a primary shard and potentially multiple replica shards. In stateful Elasticsearch, when a document is indexed, it is first routed to the primary shard, where Lucene processes and indexes it. After indexing on the primary shard, the document is then routed to the replica shards, where it is indexed by these copies.</p><p>As mentioned earlier, a refresh is needed to make these indexed documents searchable. In stateful Elasticsearch, a refresh writes the Lucene in-memory data structures to disk without performing an fsync. Refreshes are scheduled periodically, with each node executing them at different times. This process will create distinct Lucene segment files on each node, all containing the same set of documents.</p><h2>Refreshes in serverless Elasticsearch</h2><p>In contrast, serverless Elasticsearch employs a segment-based replication model. In this approach, one node per shard handles document indexing and generates Lucene segments. These segments are uploaded to the blob store once a refresh is initiated. Subsequently, search nodes are informed about these new Lucene segments, which they can read directly from the blob store.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7cc4aefbc63dca3c/6a17d7783e03d793524f2ac9/efc718c485d64c1911365a7e20a9435aeb1fbdc0-1440x754.png" alt="Refresh flow before optimizations in Elasticsearch" /><p>The illustration above demonstrates how a refresh works in serverless Elasticsearch:</p><ol><li><p>The indexing node, where all the documents were indexed, receives the refresh request and Lucene writes the in-memory data structures to disk, similar to how a stateful refresh operates.</p></li><li><p>The segment files are uploaded to the blob store as a single file (known as a stateless compound commit). In the illustration, S4 is uploaded.</p></li><li><p>Once the segment files are uploaded to the blob store, the indexing node sends a message to each search node, notifying them of the new segment files so they can perform searches on the newly indexed documents.</p></li><li><p>The search nodes fetch the necessary data from the blob store when executing searches.</p></li></ol><p>This model offers the advantage of lightweight nodes, as data is stored in the blob store. This makes scaling or reallocating workloads between nodes more cost-effective compared to stateful Elasticsearch, where data must be transferred to the new node containing the new shard.</p><p>One aspect worth considering is the additional object store request costs associated with each refresh in serverless Elasticsearch. Every refresh operation created a new object in the object store, resulting in an object store PUT request that incurs associated costs. This led to a linear relationship between the number of indices and the number of object store PUT requests. With enough refreshes, object store costs could surpass the cost of the hardware itself. To address this, we initially implemented refresh throttling measures to manage costs effectively and mitigate potential issues over time. This blog post describes the next step in that effort, which allowed us to refresh faster and at a manageable cost.</p><h2>Refresh cost optimizations in serverless Elasticsearch</h2><p>As previously mentioned, the serverless Elasticsearch architecture provides numerous benefits. However, to manage refresh costs effectively, we made decisions that occasionally impacted user experience. One such decision was enforcing a default refresh interval of 15 seconds, meaning that in some cases, newly indexed data won't become searchable until 15 seconds have passed. Despite our efforts, scenarios arose where object store expenses became prohibitive, prompting us to reassess our approach. In this section, we will delve into how we successfully decoupled refresh operations from object store calls to address these challenges without compromising user experience.</p><p>After evaluating various solutions—from temporary storage of segments in distributed file systems like NFS to direct pushing of segments into search nodes—we settled on an approach relying on serving segment data from indexing nodes directly to search nodes.</p><p>Rather than letting refresh immediately upload new Lucene segments to the blob store, index nodes now accumulate segments from refreshes and upload them as a single blob later. This enables index nodes to serve reads from search nodes in a manner akin to a blob store, delaying segment uploads until sufficient data accumulates or a predetermined time interval elapses.</p><p>This strategy grants us complete control over the size of the blobs uploaded to the blob store, enabling us to determine when request costs become negligible in comparison to hardware costs.</p><h3>Batched compound commits</h3><p>We aimed to implement this enhancement incrementally and ensure backward compatibility with existing data stored in the blob store. Therefore, we opted to maintain the same file format for storing Lucene segments in the blob store. For context, Lucene segments comprise multiple files, each serving a distinct role. To streamline the upload process and minimize PUT requests, we introduced compound commits: single blobs containing all segment files consecutively, accompanied by a metadata header, including a directory of the files in the compound commit.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7207e2d6008df66e/6a17d779ec0f8984445a6446/a503ec1c16498a4ad86de3c1fce4d13e472144da-1440x441.png" alt="Compound commit file format" /><p>When retrieving a compound commit from the blob store, such as during shard relocation, our primary focus is typically on the compound commit header. This header is crucial as it contains the essential data needed to promptly populate internal data structures. With this in mind, we realized we could maintain the existing file format but streamline it so that each blob would sequentially append one compound commit after another. We denominated this new file format, batched compound commit.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt321e94e2043ef619/6a17d77aec0f8907455a644a/3c264c4b43632f508c96a6ebd2c381402a83fd5f-1440x374.png" alt="Batched compound commit file format" /><p>Since each compound commit's size is stored in its header, retrieving the headers of all compound commits within a batched compound commit is straightforward; we can sequentially read each header by simply seeking the next entry. When handling blobs in the old format, they are treated as singleton batched compound commits. Another critical aspect of our file format is maintaining fixed offsets for each Lucene segment file once it's appended into a batched compound commit. This ensures consistency whether the file is served from the index node or the blob store. It also prevents the need to evict cached entries on search nodes when the batched compound commit is eventually uploaded to the blob store.</p><h3>New refresh lifecycle</h3><p>Index nodes will now accumulate Lucene segments from refreshes until enough data is gathered to upload them as a single blob. Let us explore how index and search nodes coordinate to determine where to access this data from.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta3c527801c519b6d/6a17d77ce9ea8761a5a9c41d/578e9dbfeb31673e86429820479c211db5a27434-1440x802.png" alt="Optimized refresh flow in Elasticsearch serverless" /><p>As shown in the illustration above, the following steps occur during the optimized refresh process in serverless Elasticsearch:</p><ol><li><p>The index node receives a refresh request, writes a new set of Lucene segments to its local disk, and adds these segments to the pending batched compound commit for eventual upload.</p></li><li><p>The index node notifies the search node about these new segments, providing details about the involved segments and their locations (blob store or index node).</p></li><li><p>When a search node needs a segment to fulfill a query, it decides whether to get it from the blob store or the index node and caches the data locally.</p></li></ol><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt782c93954782c163/6a17d77d4b055d0b68432050/8e051b6251fe96510dd1d31f679c54c042cd95e5-1440x721.png" alt="Optimized refresh upload flow in Elasticsearch serverless" /><p>The image above illustrates the process of uploading data to the blob store in serverless Elasticsearch once enough segments have accumulated in the indexing nodes or after a specified amount of time has elapsed.</p><ol><li><p>A refresh adds a new segment to the batched compound commit and the accumulated data reaches 16 MB, or a certain amount of time has passed since the last refresh, from this point onwards new segments are accumulated into a new batched compound commit.</p></li><li><p>The indexing node begins uploading the accumulated segments as a single blob to the object store.</p></li><li><p>The indexing node notifies the search node replicas of the latest segment uploaded to the object store, instructing them to fetch data from these segments from the blob store going forward.</p></li><li><p>If a search requires data that isn't cached locally, it will retrieve the necessary information from the blob store, while any previously fetched data from the indexing node remains valid even after the upload.</p></li></ol><h3>Considerations and tradeoffs</h3><p>The approach chosen blurs the clear separation between storage and compute, requiring index nodes to handle storage requests until Lucene segments are eventually uploaded to the blob store. However, the overhead from these storage requests is minimal and we have not observed impact on indexing throughput.</p><p>We'll note that we keep translog entries until corresponding data has been uploaded to the blob store, hence the approach maintains existing data safety guarantees. Recovery times after a crash may be slightly longer, but we consider this an acceptable trade-off.</p><h2>Conclusions</h2><p>This blog post has explored our transition towards a more cloud-native approach, emphasizing its many benefits alongside the critical cost consideration. We traced our evolution from a model where each new Lucene segment generated a distinct object in the object store. This led to cost and user experience challenges in specific serverless workloads compared to stateful Elasticsearch. Batching object store uploads enabled us to minimize the number of object store requests and enhance the cost efficiency of our serverless offering.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6478e2975a6ccedb/6a17d77f3e03d7925a4f2acd/58096951dd3f12d0b60072867febc6b7c90ecc26-1440x673.png" alt="Reduction in PUT requests" /><h2>Acknowledgments</h2><p>We would like to acknowledge the contributions of Iraklis Psaroudakis, Tanguy Leroux, and Yang Wang. Their efforts were instrumental in the success of this project.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-refresh-costs-serverless</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-refresh-costs-serverless</guid>
    <category><![CDATA[Elastic Cloud Serverless]]></category>
    <dc:creator><![CDATA[Francisco Fernández Castaño,Henning Andersen]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt88526af16bafdb7c/6a17d7807f6f15825dc0998d/d11e1ba058784ec92b8953fb8db62e1bad21c210-720x420.jpg" length="0" type="image/jpeg"/>
    <pubDate>Wed, 31 Jul 2024 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Ingest autoscaling in Elasticsearch]]></title>
    <description><![CDATA[Learn more about how Elasticsearch autoscales to address ingestion load.]]></description>
    <content:encoded><![CDATA[<p>Sizing an Elasticsearch cluster correctly is not easy. The optimal size of the cluster depends on the workload that the cluster is experiencing, which may change over time. Autoscaling adapts the cluster size to the workload automatically without human intervention. It avoids over-provisioning resources for the cluster only to accommodate peak usage and it also prevents degrading cluster performance in case of under-provisioning.</p><p>We rely on this mechanism to free users of our <a href="https://www.elastic.co/docs/current/serverless">Elastic Cloud Serverless</a> offering from having to make sizing decisions for the <a href="https://www.elastic.co/search-labs/blog/stateless-your-new-state-of-find-with-elasticsearch">indexing tier</a>. Ingest autoscaling requires continuously estimating the resources required to handle the incoming workload, and provisioning and de-provisioning these resources in a timely manner.</p><p>In this blog post we explore ingest autoscaling in Elasticsearch, covering the following:</p><ul><li><p>How ingest autoscaling works in Elasticsearch</p></li><li><p>Which metrics we use to quantify the indexing workload the cluster experiences in order to estimate resources required to handle that workload</p></li><li><p>How these metrics drive the autoscaling decisions.</p></li></ul><h2>Ingest autoscaling overview</h2><p>Ingest autoscaling in Elasticsearch is driven by a set of metrics that is exposed by Elasticsearch itself. These metrics reflect the ingestion load and the memory requirement of the indexing tier. Elasticsearch provides an autoscaling metrics API that serves these metrics which allows an external component to monitor these metrics and make decisions whether the cluster size needs to change (see Figure 1).</p><p>In the Elastic Cloud Serverless service, there is an autoscaler component which is a Kubernetes Controller. The autoscaler polls the Elasticsearch autoscaling metrics API periodically and calculates the desired cluster size based on these metrics. If the desired cluster size is different from the current one, the autoscaler changes the cluster size to consolidate the available resources in the cluster towards the desired resources. This change is both in terms of the number of Elasticsearch nodes in the cluster and the CPU, memory and disk available to each node.</p><p></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltce3b99ecd11442dd/6a17d7126df73179750a0d41/7c0cb0b822ca2a6531d35df15a0226a51d18a1cb-1440x1119.png" alt="overview" /><p><strong>Figure 1</strong>: ingestion autoscaling overview</p><p></p><p>An important consideration for ingest autoscaling is that when the cluster receives a spike in the indexing load the autoscaling process can take some time until it effectively adapts the cluster size. While we try to keep this reaction time as low as possible, it cannot be instantaneous. Therefore, while the cluster is scaling up, the Elasticsearch cluster should be able to temporarily push back on the load it receives if the increased load is otherwise going to cause cluster instability issues. The increase in the indexing load can manifest itself in the cluster requiring more resources, i.e., CPU, memory or disk. Elasticsearch has protection mechanisms that allows nodes to push back on the indexing load if any of these resources becomes a bottleneck.</p><p>To handle indexing requests Elasticsearch uses dedicated thread pools sized based on the number of cores available to the node. If the increased indexing load results in CPU or other resources becoming a bottleneck, incoming indexing requests are queued. <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-threadpool.html">The maximum size of this queue</a> is limited and any request arriving at the node when the queue is full will be rejected with a 429 HTTP code.</p><p>Elasticsearch also keeps track of the required memory to address ongoing indexing requests and rejects incoming requests (with a 429) if the indexing buffer <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-indexing-pressure.html">grows beyond 10% of the available heap memory</a>. This limits the memory used for indexing and ensures the node will not go out of memory.</p><p>The Elastic Cloud Serverless offering relies on the object store as the main storage for indexed data. The local disk on the nodes are used temporarily to hold indexed data. Periodically, Elasticsearch uploads the indexed data to the object store which allows freeing up the local disk space as we rely on the object store for durability of the indexed document. Nonetheless, under high indexing load, it is possible for the node to run out of disk space before the periodic upload task gets a chance to run and free up the local disk space. To handle these cases, Elasticsearch monitors the available local disk space and if necessary throttles the indexing activity while it attempts to free up space by enforcing an upload to the object store rather than waiting for the periodic upload to take place. Note that this throttling in turn results in queueing of the incoming indexing requests.</p><p>These protection mechanisms allow an Elasticsearch cluster to temporarily reject requests and provide the client with a response that indicates that the cluster is overloaded while the cluster tries to scale up. This push-back signal from Elasticsearch provides the client with a chance to react by reducing the load if possible or retrying the request which should eventually succeed if retried when the cluster is scaled up.</p><h2>Metrics</h2><p>The two metrics that are used for ingest autoscaling in Elasticsearch are ingestion load and memory.</p><h3>Ingestion load</h3><p>Ingestion load represents the number of threads that is needed to cope with the current indexing load. The autoscaling metrics API exposes a list of ingestion load values, one for each indexing node. Note that as the write thread pools (which handle indexing requests) are sized based on the number of CPU cores on the node, this essentially determines the total number of cores that is needed in the cluster to handle the indexing workload.</p><p>The ingestion load on each indexing node consists of two components:</p><ul><li><p>Thread pool utilization: the average number of threads in the write thread pool processing indexing requests during that sampling period.</p></li><li><p>Queued ingestion load: the estimated number of threads needed to handle queued write requests.</p></li></ul><p>The ingestion load of each indexing node is calculated as the sum of these two values for <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-threadpool.html">all the three write thread pools</a>. The total ingestion load of the Elasticsearch cluster is the sum of the ingestion load of the individual nodes.</p><p></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4e0ba9f4e7ae59b9/6a17d71463baff6110741ab5/b1ab391f2639aaa4b7807a37a23fb9c5375f9690-1440x831.png" alt="Figure 2: ingestion load components" /><p><strong>Figure 2</strong>: ingestion load components</p><p></p><p>The thread pool utilization is an <a href="https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average">exponentially weighted moving average (EWMA)</a> of the number of busy threads in the thread pool, sampled every second. The EWMA of the sampled thread pool utilization values is configured such that the sampled values of the past 10 seconds have the most effect on the thread pool utilization component of the ingestion load and samples older than 60 seconds have very negligible impact.</p><p>To estimate the resources required to handle the queued indexing requests in the thread pool, we need to have an estimate for how long each queued task can take to execute. To achieve this, each thread pool also provides an EWMA of the request execution time. The request execution time for an indexing request is the (wall-clock) time taken for the request to finish once it is out of the queue and a worker thread starts executing it. As some queueing is acceptable and should be manageable by the thread pool, we try to estimate the resources needed to handle the excess queueing. We consider up to 30s worth of tasks in the queue manageable by the existing number of workers and account for an extra thread proportional to this value. For example, if the average task execution time is 200ms, we estimate that each thread is able to handle 150 indexing requests within 30s, and therefore account for one extra thread for each 150 queued items.</p><p>Note that since the indexing nodes rely on pushing indexed data into the object store periodically, we do not need to scale the indexing tier based on the total size of the indexed data. However, the disk IO requirements of the indexing workload needs to be considered for the autoscaling decisions. The ingestion load represents both CPU requirements of the indexing nodes as well as disk IO since both CPU and IO work is done by the write thread pool workers and we rely on the wall clock time to estimate the required time to handle the queued requests.</p><p>Each indexing node calculates its ingestion load and publishes this value to the master node periodically. The master node serves the per node ingestion load values via the autoscaling metrics API to the autoscaler.</p><h3>Memory</h3><p>The memory metrics exposed by the autoscaling metrics API are node memory and tier memory. The node memory represents the minimum memory requirement for each indexing node in the cluster. The tier memory metric represents the minimum total memory that should be available in the indexing tier. Note that these values only indicate the minimum to ensure that each node is able to handle the basic indexing workload and hold the cluster and indices metadata, while ensuring that the tier includes enough nodes to accommodate all index shards.</p><p>Node memory must have a minimum of 500MB <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/size-your-shards.html#_consider_additional_heap_overheads">to be able to handle indexing workloads</a>, as well as <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/size-your-shards.html#shard-count-recommendation">a fixed amount of memory per each index</a>. This ensures all nodes can hold metadata for the cluster, which includes metadata for every index. Tier memory is determined by accounting for the memory overhead of the field mappings of the indices and the amount of memory needed for each open shard allocated on a node in the cluster. Currently, the per-shard memory requirement uses a fixed estimate of 6MB. We plan to refine this value.</p><p>The estimate for the memory requirements for the mappings of each index is calculated by one of the data nodes that hosts a shard of the index. The calculated estimates are sent to the master node. Whenever there is a mapping change this estimate is updated and published to the master node again. The master node serves the node and total memory metrics based on these information via the autoscaling metrics API to the autoscaler.</p><h2>Scaling the cluster</h2><p>The autoscaler is responsible for monitoring the Elasticsearch cluster via the exposed metrics, calculating the desirable cluster size to adapt to the indexing workload, and updating the deployment accordingly. This is done by calculating the total required CPU and memory resources based on the ingestion load and memory metrics. The sum of all the ingestion load per node values determines the total number of CPU cores needed for the indexing tier.</p><p>The calculated CPU requirement and the provided minimum node and tier memory resources are mapped to a predetermined set of cluster sizes. Each cluster size determines the number of nodes and the CPU, memory and disk size of each node. All nodes within a certain cluster size have the same hardware specification. There is a fixed ratio between CPU, memory and disk, thus always scaling all 3 resources linearly. The existing cluster sizes for the indexing tier are based on node sizes starting from 4GB/2vCPU/100GB disk to 64GB/32vCPU/1600GB disk. Once the Elasticsearch cluster scales up to the largest node size (64GB memory), any further scale-up adds new 64GB nodes, allowing a cluster to scale up to 32 nodes of 64GB. Note that this is not a hard upper bound on the number of Elasticsearch nodes in the cluster and can be increased if necessary.</p><p>Every 5 seconds the autoscaler polls metrics from the master node, calculates the desirable cluster size and if it is different from the current cluster size, it updates the Elasticsearch Kubernetes Deployment accordingly. Note that the actual reconciliation of the deployment towards the desired cluster size and adding and removing the Elasticsearch nodes to achieve this is done by Kubernetes. In order to avoid very short-lived changes to the cluster size, we account for a 10% headroom when calculating the desired cluster size during a scale down and a scale down takes effect only if all desired cluster size calculations within the past 15 minute have indicated a scale-down.</p><p>Currently, the time that it takes for an increase in the metrics to lead to the first Elasticsearch node being added to the cluster and ready to process indexing load is under 1 minute.</p><h2>Conclusion</h2><p>In this blog post, we explained how ingest autoscaling works in Elasticsearch, the different components involved, and the metrics used to quantify the resources needed to handle the indexing workload. We believe that such an autoscaling mechanism is crucial to reduce the operational overhead of an Elasticsearch cluster for the users by automatically increasing the available resources in the cluster when necessary. Furthermore, it leads to cost reduction by scaling down the cluster when the available resources in the cluster are not required anymore.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-ingest-autoscaling</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-ingest-autoscaling</guid>
    <category><![CDATA[Elastic Cloud Serverless]]></category>
    <dc:creator><![CDATA[Pooya Salehi,Henning Andersen,Francisco Fernández Castaño]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb2cd04a86700d5c2/6a17d715e3179138882d567d/016f5f2a90974dd53416d7d12f8776e802a0eef8-1440x823.png" length="0" type="image/png"/>
    <pubDate>Mon, 29 Jul 2024 00:00:00 GMT</pubDate>
  </item>
  </channel>
</rss>