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.
Two-phase search
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 RestBulkAction → TransportBulkAction → 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*Actioninserver/src/main/java/org/elasticsearch/rest/action/...parses HTTP and delegates to the node client. - A
Transport*Actioninserver/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 formlockall,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/andlibs/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.