Open-Source Wikis

/

Elasticsearch

/

Elasticsearch

/

Architecture

elastic/elasticsearch

Architecture

Elasticsearch is a distributed system of Node processes that share state through a strongly-consistent cluster state document elected and replicated by a master node. Each node hosts shards (Lucene indices) of one or more user-facing indices and exposes a REST API that fans out to other nodes via a binary transport protocol.

This page sketches the runtime architecture from the outside in.

Process boundary

graph LR
  Client[REST client / language client] -->|HTTP| HTTP[Netty HTTP server]
  HTTP --> RC[RestController]
  RC -->|named action| AC[ActionModule / NodeClient]
  AC -->|transport action| TS[TransportService]
  TS -->|local| Action[Transport*Action]
  TS -->|Netty TCP| Remote[Remote node]
  Action --> CS[ClusterService cluster state]
  Action --> IS[IndicesService]
  IS --> Engine[IndexShard + Engine]
  Engine --> Lucene[Apache Lucene]

A single OS process runs an Elasticsearch Node. The HTTP server (server/src/main/java/org/elasticsearch/http) accepts REST requests; RestController (server/src/main/java/org/elasticsearch/rest/RestController.java) routes each request to a RestHandler, which converts it into a transport action and dispatches via the local NodeClient. The transport layer (server/src/main/java/org/elasticsearch/transport) decides whether to handle the action locally or send it to a peer over the binary transport protocol.

Node roles

Every node has one or more roles defined in DiscoveryNodeRole (server/src/main/java/org/elasticsearch/cluster/node/DiscoveryNodeRole.java):

  • master / master_eligible — participates in master election; can own cluster state.
  • data, data_hot, data_warm, data_cold, data_frozen, data_content — stores shards in different tiers.
  • ingest — runs ingest pipelines defined under server/src/main/java/org/elasticsearch/ingest.
  • ml — runs machine learning jobs (X-Pack ML).
  • transform — runs transform jobs (X-Pack transform).
  • remote_cluster_client — opens connections to remote clusters for cross-cluster search/replication.
  • voting_only — votes in master elections without becoming master.

Roles determine which services start in Node.start() and what work the node accepts.

Cluster coordination

The master is elected by the Coordinator (server/src/main/java/org/elasticsearch/cluster/coordination/Coordinator.java), which uses a Raft-inspired consensus algorithm with pre-voting and a configurable voting configuration. The master serializes all cluster state changes through MasterService (server/src/main/java/org/elasticsearch/cluster/service/MasterService.java). State is published in two phases (publish + commit) by PublicationTransportHandler. Followers apply state through ClusterApplierService.

The cluster state is an immutable ClusterState object (server/src/main/java/org/elasticsearch/cluster/ClusterState.java) holding:

  • Metadata — index metadata, mappings, settings, templates, aliases, system indices, ingest pipelines, ILM policies, transforms, etc.
  • RoutingTable — for each shard, which node holds the primary and which hold replicas.
  • DiscoveryNodes — set of nodes in the cluster with their roles.
  • ClusterBlocks — read/write/metadata blocks that gate operations.
graph TB
  subgraph Master node
    CO[Coordinator]
    MS[MasterService]
    AS[AllocationService]
  end
  subgraph Follower node
    CAS[ClusterApplierService]
    IS[IndicesClusterStateService]
  end
  CO -->|publish state| CAS
  MS -->|update via task| CO
  AS -->|reroute / desired balance| MS
  CAS -->|apply| IS
  IS -->|create/delete shards| Shard[(IndexShard)]

Indices and shards

An index is a logical collection that is split into one or more shards; each shard is a full Lucene index, optionally with replicas. IndicesService (server/src/main/java/org/elasticsearch/indices/IndicesService.java) owns IndexService instances per local index, which in turn own IndexShard (server/src/main/java/org/elasticsearch/index/shard/IndexShard.java).

IndexShard wraps an Engine (default InternalEngine) that drives a Lucene IndexWriter plus a translog for durability between flushes. Refreshes make recently-written documents searchable; flushes make them durable to disk; merges combine smaller Lucene segments into bigger ones.

sequenceDiagram
  participant C as Coordinator
  participant S1 as Shard 1
  participant S2 as Shard 2
  C->>S1: Query phase (top-N doc IDs)
  C->>S2: Query phase (top-N doc IDs)
  S1-->>C: doc IDs + sort values
  S2-->>C: doc IDs + sort values
  C->>C: merge, pick global top-N
  C->>S1: Fetch phase (selected docs)
  C->>S2: Fetch phase (selected docs)
  S1-->>C: source + highlights + fields
  S2-->>C: source + highlights + fields
  C-->>Client: SearchResponse

The query phase (server/src/main/java/org/elasticsearch/search/SearchService.java + query/) runs the Query against each shard's IndexSearcher and returns the top doc IDs and sort keys. The fetch phase (server/src/main/java/org/elasticsearch/search/fetch) loads _source, computes highlights, evaluates fields, and assembles SearchHit objects. See Search for the full pipeline.

Indexing path

Bulk and single-document writes flow from RestBulkActionTransportBulkAction → primary shard (IndexShard.applyIndexOperationOnPrimary) → translog + Lucene → replicas via the ReplicationOperation framework. Backpressure is enforced by IndexingPressure (server/src/main/java/org/elasticsearch/index/IndexingPressure.java). See Indexing.

REST and transport actions

Almost every public-facing operation has a pair:

  • A Rest*Action in server/src/main/java/org/elasticsearch/rest/action/... parses HTTP and delegates to the node client.
  • A Transport*Action in server/src/main/java/org/elasticsearch/action/... does the work, possibly dispatching to other nodes.

ActionModule (server/src/main/java/org/elasticsearch/action/ActionModule.java) registers the full catalog at boot and wires plugin-contributed actions and REST handlers. See Action layer.

Plugin architecture

Plugins implement one or more interfaces defined in server/src/main/java/org/elasticsearch/plugins/ (e.g. ActionPlugin, SearchPlugin, MapperPlugin, EnginePlugin, RepositoryPlugin, IngestPlugin, AnalysisPlugin, ClusterPlugin, DiscoveryPlugin, NetworkPlugin, ScriptPlugin). Plugins are loaded from modules/ (always-on, packaged with the distribution), plugins/ (optional, installable), or X-Pack (x-pack/plugin/). See Plugin system.

Multi-language and native components

While the source is primarily Java, several components reach outside the JVM:

  • libs/native/ — JNA + JDK 22+ Foreign Function API bindings for mlockall, madvise, file flushing, and the Vector API path.
  • libs/simdvec/ — SIMD-accelerated vector dot product / Manhattan / Hamming kernels (Java Vector API plus optional native fallback).
  • libs/gpu-codec/ — optional GPU codec for vector search.
  • x-pack/plugin/esql-datasource-parquet/ and libs/parquet-rs/ — Rust-based Parquet reader for ES|QL.
  • modules/lang-painless/ — Painless scripting language compiler (Java) with bytecode generation.

Statistics and monitoring

Each major service exposes counters, gauges, and timers via the org.elasticsearch.telemetry API (server/src/main/java/org/elasticsearch/telemetry). The default APM module (modules/apm) ships traces and metrics over OTLP. Node, indices, cluster, and thread pool stats are exposed via REST _nodes/stats, _cluster/stats, and _cat/... endpoints.

Storage layout on disk

NodeEnvironment (server/src/main/java/org/elasticsearch/env/NodeEnvironment.java) creates a per-node data directory containing:

  • _state/ — persisted cluster state (PersistedClusterStateService).
  • indices/<UUID>/<shard>/ — per-shard Lucene index, translog, and metadata.
  • snapshot_cache/ — cached blobs for searchable snapshots.
  • node.lock — exclusive lock for the data directory.

Snapshots are stored in pluggable repositories (server/src/main/java/org/elasticsearch/repositories plus modules/repository-* and plugins/repository-*) using a custom blob format (BlobStoreRepository).

Stateless mode

x-pack/plugin/stateless/ runs Elasticsearch in a "stateless" topology where the durable copy of an index lives in object storage; nodes act as caches that can be replaced without rebuilding from peers. Look at StatelessPlugin for the entry point — it's one of the most actively-changed files in the repo.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Architecture – Elasticsearch wiki | Factory