OpenSearch vs. Elasticsearch Today
If you learned this engine as Elasticsearch, most of your mental model still
works: Lucene segments, shards and replicas, the inverted index, BM25, the
cluster-state model, the query DSL. OpenSearch began as a fork of that
codebase, so the bones are shared. This page is for porting that mental model
forward — it catalogs where OpenSearch has evolved or diverged since the fork,
so you stop being surprised by cluster_manager, segment replication, and the
_plugins/_* surface.
Discipline: This page describes what OpenSearch has, with the divergence point named. It does not claim what Elasticsearch's current internals look like — those are a separate, independently-evolving codebase, and overclaiming there would be wrong as often as right. Read every row as "OpenSearch has X (since version Y)," not "Elasticsearch lacks X."
The fork point
| Fact | Detail |
|---|---|
| Forked from | Elasticsearch 7.10.2 (and Kibana 7.10.2 → OpenSearch Dashboards) |
| When | Announced 2021; OpenSearch 1.0 GA July 2021 |
| Why | Elastic relicensed Elasticsearch/Kibana away from Apache-2.0; AWS and partners forked the last Apache-2.0 release to keep an open-source distribution |
| License (OpenSearch) | Apache License 2.0 |
| License (post-7.10 Elasticsearch) | dual SSPL + Elastic License (Elastic later also added an AGPL-3 option for Elasticsearch in 2024); these are not OSI "open source" in the SSPL/Elastic-License form OpenSearch forked away from |
| Governance (now) | the OpenSearch Software Foundation, a directed fund of the Linux Foundation (moved from AWS sole stewardship to the LF in 2024) |
Because the divergence point is a single known commit (7.10.2), you can often read
OpenSearch internals as "7.10-era Lucene/ES architecture plus everything in
the tables below." The package names changed from org.elasticsearch.* to
org.opensearch.* in a mechanical rename early in the fork; almost every class
you'll grep for keeps its short name.
What OpenSearch has built since the fork
Each of these is an OpenSearch capability with a chapter in this book. Frame them as additions/divergences from the 7.10.2 baseline.
| OpenSearch feature | What it is | Since | Read |
|---|---|---|---|
| cluster_manager terminology | the elected coordinating node and its APIs/settings renamed from "master" → "cluster_manager" (old names kept as deprecated aliases) | 2.0 | discovery-coordination.md |
| Segment replication | replicas copy finished segment files from the primary instead of re-indexing each doc (document replication); much cheaper write path, near-real-time copy | 2.x (GA 2.x) | replication.md |
| Remote-backed storage | translog + segments durably backed to a remote store (e.g. S3); enables cheaper durability and faster recovery/restore | 2.x | remote-store-and-durability.md |
| Concurrent segment search | a single shard's segments searched in parallel across slices via CollectorManager (slice → reduce); default-on in 3.0 | GA 2.x, default 3.0 | concurrent-segment-search/index.md |
| Star-tree index | a precomputed multi-field aggregation tree that answers eligible aggregations without scanning docs | 2.x (experimental → GA) | star-tree-aggregations.md |
| Tiered caching | a pluggable, multi-tier request cache (on-heap + disk via a spillover store) to keep more results cached than heap allows | 2.x | tiered-caching.md |
| Built-in Security (free) | TLS, authn/authz, RBAC, DLS/FLS/field-masking, audit — shipped and free in the default distribution, not a paid tier | 1.0 | security/index.md |
| k-NN / vector search | native HNSW (Lucene engine) + faiss/nmslib engines via JNI, quantization (SQ/PQ/BQ), warmup, disk-ANN | 1.0+ | knn/index.md, vector-internals/index.md |
| neural-search | neural / hybrid / neural_sparse query clauses; semantic + lexical retrieval with score normalization | 2.x | vectorization-embeddings/index.md |
| ml-commons | in-cluster model registration/deployment/inference; the substrate neural-search and agents call | 1.x+ | vectorization-embeddings/index.md |
| Reader/writer separation & search replicas | separate the indexing (writer) role from search-only (reader) replicas so search scales independently of indexing | 2.x → ongoing | replication.md, sharding-and-scaling.md |
| protobuf / gRPC transport | an effort to add a protobuf-defined gRPC transport alongside the classic 9300 binary transport, for cross-language clients and efficiency | ongoing (3.x) | transport-layer.md |
Note: Several of these (segment replication, remote store, reader/writer separation) are facets of one larger arc: decoupling durability and search from the local indexing path, so storage and search scale independently. If you internalize that arc, the individual features stop looking like a grab-bag.
RFCs and tracking issues
Cited by full URL so you can read the design rationale firsthand:
| Topic | Issue / RFC |
|---|---|
| Reader/writer separation (search replicas) | https://github.com/opensearch-project/OpenSearch/issues/15306 |
| k-NN GPU index build | https://github.com/opensearch-project/k-NN/issues/2293 |
| k-NN remote index build | https://github.com/opensearch-project/k-NN/issues/2294 |
For anything else, search the relevant repo's issues with a RFC/[META] label
filter rather than trusting a memorized number:
gh issue list --repo opensearch-project/OpenSearch --search "RFC segment replication in:title"
gh issue list --repo opensearch-project/OpenSearch --search "label:RFC"
gh issue list --repo opensearch-project/k-NN --search "RFC in:title"
Naming / terminology differences
The single most common source of "wait, that's not what I typed" when moving from an Elasticsearch mental model. Old names are generally retained as deprecated aliases, so both work, but new code, settings, and docs use the right column.
| Older / Elasticsearch-era term | OpenSearch term | Where it shows up |
|---|---|---|
| master (node, role) | cluster_manager node / role | node.roles: [cluster_manager], discovery-coordination.md |
_cat/master | _cat/cluster_manager | REST endpoint map |
cluster.initial_master_nodes | cluster.initial_cluster_manager_nodes | bootstrap settings |
master_timeout (param) | cluster_manager_timeout (old still accepted) | cluster/index admin requests |
discovery.zen.* (legacy) | modern cluster.* coordination settings | discovery-coordination.md |
org.elasticsearch.* | org.opensearch.* | every Java package |
elasticsearch.yml | opensearch.yml | node config file |
x-pack security/features | built-in Security plugin + _plugins/_* | security/index.md |
ELASTIC_PASSWORD, elastic user | OPENSEARCH_INITIAL_ADMIN_PASSWORD, admin user | bootstrap / demo config |
| Kibana | OpenSearch Dashboards | UI |
| Elastic Common Schema tie-ins | vendor-neutral; Data Prepper / OpenTelemetry ingest | observability |
Warning: "Deprecated alias" means works now, warns, may be removed. When you contribute, use the
cluster_managerspelling in new code, settings, tests, and docs — reviewers will ask you to. When you operate a cluster, prefer the new names so you don't carry deprecation debt.
Where the architecture is genuinely the same
So you don't over-rotate: the load-bearing core is shared lineage and behaves the way your Elasticsearch instinct expects.
| Still the same shape | Notes |
|---|---|
| Lucene as the storage/search engine | same segments, codecs, file formats — segments-and-codecs.md, Lucene file formats |
Shards + replicas, routing by _routing/_id | sharding-and-scaling.md |
| Cluster-state model, two-phase publish, quorum-based coordination | cluster-state.md, cluster-state-publishing.md |
| The REST → action → transport request path | rest-layer.md, action-framework.md, transport-layer.md |
Query DSL, QueryBuilder → Lucene Query, BM25 scoring | query-dsl-querybuilders.md, query-engine/index.md |
Aggregation framework (Aggregator, reduce on the coordinator) | aggregations.md |
| Refresh / flush / merge, translog durability | refresh-flush-merge.md, translog.md |
| Circuit breakers, thread pools, plugin SPI | circuit-breakers-memory.md, threadpools-concurrency.md, plugin-architecture.md |
The shared baseline is 7.10.2-era. Anything that landed in Elasticsearch after the fork is not in OpenSearch (and vice-versa) unless independently re-implemented; the two codebases have diverged for years now.
If you're coming from Elasticsearch, read these chapters
A directed reading path that maps "the thing you already know" to "where OpenSearch differs or has grown."
| You know / you're looking for | Start here | Then |
|---|---|---|
| how leader election / "master" works | discovery-coordination.md | distributed-consensus/index.md — and re-train your tongue to say cluster_manager |
| replicas re-index every doc (document replication) | replication.md | remote-store-and-durability.md — segment replication + remote store |
| paid security tier | security/index.md | security/lab-01-authn-tls.md, security/lab-02-authz-dls-fls.md |
| vector search / dense retrieval | knn/index.md | vector-internals/index.md, hnsw-vector-search.md |
| semantic / hybrid search | vectorization-embeddings/index.md | the neural/hybrid rows in the REST endpoint map |
| search felt single-threaded per shard | concurrent-segment-search/index.md | note it's default-on in 3.0 |
| expensive aggregations | star-tree-aggregations.md | aggregations/index.md, tiered-caching.md |
| where are the endpoints / handlers | REST endpoint map | rest-layer.md |
| on-disk file zoo | Lucene file formats | segments-and-codecs.md |
| how do I even contribute | contributor-mindset | issue-roadmap, release-governance |
Practical migration notes
Small things that bite when you point Elasticsearch habits at OpenSearch:
- Config file & env vars:
opensearch.yml, notelasticsearch.yml; setOPENSEARCH_INITIAL_ADMIN_PASSWORDfor the demo security config. - Settings names: prefer
cluster_manager/cluster.initial_cluster_manager_nodes;cluster_manager_timeoutovermaster_timeout. Old names warn. - Security is on by default in the standard distribution — your first
curlneeds-u admin:... -k(TLS + basic auth). security/lab-01-authn-tls.md explains thesecurityadmin.sh+ YAML config flow. - Clients: use the OpenSearch language clients (
opensearch-py,opensearch-java, ...). Some Elasticsearch clients added version checks that reject non-Elasticsearch servers; OpenSearch clients don't. - Replication strategy is a choice: document replication (classic) vs segment replication is an index setting — pick deliberately based on write-heaviness.
- Version math is independent: OpenSearch major/minor numbers do not line up with Elasticsearch's. "Which Lucene?" is the better cross-reference — grep the build for the Lucene version both sides happen to be on.
Note: Be respectful and precise when you write or talk about the two projects — many contributors work across the ecosystem, and the histories are entangled. State facts (license, fork point, what each has) and cite RFCs; avoid editorializing about motives. This book's job is to make you effective in the OpenSearch codebase.
First contact: the same requests, the OpenSearch way
The fastest way to recalibrate is to run the requests you already know and watch for the differences.
# Security is on by default in the standard distribution: TLS + basic auth.
# (-k accepts the demo self-signed cert; never -k against production.)
curl -sk -u admin:"$OPENSEARCH_INITIAL_ADMIN_PASSWORD" 'https://localhost:9200'
# Who is the elected coordinator? Note the path: cluster_manager, not master.
curl -sk -u admin:"$PW" 'https://localhost:9200/_cat/cluster_manager?v'
# Is this index using segment replication? Look for the replication.type setting.
curl -sk -u admin:"$PW" \
'https://localhost:9200/my-index/_settings?filter_path=**.replication' | python3 -m json.tool
# Segment-replication lag (empty unless replication.type=SEGMENT):
curl -sk -u admin:"$PW" 'https://localhost:9200/_cat/segment_replication?v'
# Concurrent segment search status (default-on in 3.0):
curl -sk -u admin:"$PW" \
'https://localhost:9200/_cluster/settings?include_defaults&filter_path=**.concurrent_segment_search'
# Who am I, per the security plugin's authc/authz chain?
curl -sk -u admin:"$PW" 'https://localhost:9200/_plugins/_security/authinfo?pretty'
# Which plugins are installed? (k-NN, security, neural-search, ml-commons, ...)
curl -sk -u admin:"$PW" 'https://localhost:9200/_cat/plugins?v'
| Surprise vs an Elasticsearch habit | Why |
|---|---|
curl localhost:9200 hangs / refuses without -k -u | security is on by default; it's HTTPS + basic auth, not plaintext |
_cat/master warns about deprecation | renamed to _cat/cluster_manager |
_cat/segment_replication returns no rows | the index uses document replication, not segment replication |
_plugins/_knn/*, _plugins/_security/* exist | these are first-party plugins in the default distribution, not a paid add-on |
| your ES client throws a "not Elasticsearch" / version error | use the OpenSearch clients (opensearch-py, opensearch-java) instead |
One layer deeper on the headline divergences
| Divergence | The one thing to internalize | Where it changes contributor work |
|---|---|---|
| document → segment replication | replicas copy finished segment files, not re-run indexing — write amplification drops, but replicas need the primary's segments shipped to them | recovery, the engine, remote store |
| local → remote-backed durability | the translog and segments can live in object storage; durability decouples from the local disk | remote-store-and-durability.md, translog.md |
| serial → concurrent segment search | a shard's segments are sliced and searched in parallel; collectors must be slice-safe via CollectorManager | every new aggregation/collector you write — concurrent-segment-search/index.md |
| scan → star-tree aggregations | eligible aggregations read a precomputed tree instead of scanning docs | star-tree-aggregations.md |
| coupled reader+writer → separation | search-only replicas scale search independently of indexing (RFC 15306) | replication.md, sharding-and-scaling.md |
Related references
- REST Endpoint Map — every
_cat/cluster_manager,_cat/segment_replication,_plugins/_*surface this page mentions. - Lucene File Formats Cheat-Sheet — the shared storage substrate.
- Segment replication, remote-backed storage, concurrent segment search, star-tree, tiered caching, security — the divergences, in depth.