import ComparisonTable from ’../../components/ComparisonTable.astro’;
OpenSearch is AWS’s open-source fork of Elasticsearch, created after Elastic changed its license in 2021. Choosing between them involves licensing, cloud strategy, and feature requirements.
Quick Verdict
Choose Elasticsearch if: You’re not locked to AWS, want the most feature-complete search platform, and are comfortable with SSPL licensing.
Choose OpenSearch if: You’re AWS-native, want Apache 2.0 licensing for embedding in products, or use Amazon OpenSearch Service heavily.
Background: The Fork
In January 2021, Elastic changed Elasticsearch and Kibana from Apache 2.0 to SSPL (Server Side Public License) to prevent cloud providers (primarily AWS) from offering it as a managed service. AWS forked version 7.10.2 and created OpenSearch under Apache 2.0.
This matters: SSPL is not OSI-approved open source. If you embed a search engine in a commercial product, OpenSearch’s Apache 2.0 license is safer.
Feature Comparison
<ComparisonTable headers={[“Feature”, “Elasticsearch”, “OpenSearch”]} rows={[ [“License”, “SSPL (not OSI)”, “Apache 2.0”], [“Latest version”, “8.x”, “2.x”], [“ML features”, “Excellent (ELSER, semantic search)”, “Good (improving)”], [“Vector search”, “kNN, HNSW”, “kNN, HNSW”], [“Kibana/Dashboard”, “Kibana”, “OpenSearch Dashboards”], [“Security (built-in)”, “Yes (since 7.x)”, “Yes (Security plugin)”], [“AWS managed”, “AWS Elasticsearch Legacy”, “Amazon OpenSearch Service”], [“GCP/Azure managed”, “Elastic Cloud”, “Limited”], [“Community size”, “Larger”, “Growing”], [“Plugin ecosystem”, “Larger”, “Smaller”], ]} />
Core Usage
Both share the same REST API (forked from 7.10.2), so most basic operations are identical:
from elasticsearch import Elasticsearch
es = Elasticsearch(["http://localhost:9200"])
# Index a document
es.index(index="products", id=1, document={
"name": "Wireless Headphones",
"description": "Premium noise-cancelling Bluetooth headphones",
"price": 299.99,
"category": "electronics",
"tags": ["audio", "wireless", "bluetooth"]
})
# Full-text search
response = es.search(index="products", query={
"multi_match": {
"query": "wireless audio",
"fields": ["name^2", "description", "tags"]
}
})
# Filter + search
response = es.search(index="products", query={
"bool": {
"must": {"match": {"description": "noise cancelling"}},
"filter": {"range": {"price": {"lte": 500}}}
}
})
OpenSearch uses the same syntax with its own client:
from opensearchpy import OpenSearch
client = OpenSearch(hosts=[{"host": "localhost", "port": 9200}])
# Identical query syntax
Vector Search (Semantic Search)
Both support approximate nearest neighbor (ANN) search:
# Elasticsearch - semantic search with ELSER (Elastic Learned Sparse EncodeR)
es.indices.create(index="articles", mappings={
"properties": {
"content": {"type": "text"},
"content_embedding": {
"type": "sparse_vector" # Elasticsearch ELSER
}
}
})
# Dense vector search (both Elasticsearch and OpenSearch)
es.indices.create(index="semantic-articles", mappings={
"properties": {
"embedding": {
"type": "dense_vector",
"dims": 1536, # OpenAI embedding dimension
"index": True,
"similarity": "cosine"
}
}
})
# k-NN search
es.search(index="semantic-articles", knn={
"field": "embedding",
"query_vector": query_embedding,
"k": 10,
"num_candidates": 100
})
Elasticsearch has an edge with ELSER — a sparse encoder trained specifically for search relevance that outperforms dense embeddings for many text retrieval tasks without requiring an external embedding API.
ML and AI Features
Elasticsearch:
- ELSER — proprietary sparse encoder for semantic search
- Inference API — call external ML models (OpenAI, Azure, Cohere) from within queries
- Trained ML models (classification, NER, text embedding)
- Semantic text field type (auto-generates embeddings)
OpenSearch:
- ML Commons framework
- Semantic search with Cohere, OpenAI, Bedrock embeddings
- Conversational search
- Neural sparse search (similar to ELSER)
Elasticsearch’s ML features are more mature in 2026, but OpenSearch is catching up rapidly.
Amazon OpenSearch Service
If you’re AWS-native, Amazon OpenSearch Service is compelling:
# AWS CloudFormation
AmazonOpenSearchDomain:
Type: AWS::OpenSearch::Domain
Properties:
DomainName: my-search-domain
EngineVersion: OpenSearch_2.11
ClusterConfig:
InstanceType: r6g.large.search
InstanceCount: 3
DedicatedMasterEnabled: true
DedicatedMasterType: r6g.large.search
DedicatedMasterCount: 3
EBSOptions:
EBSEnabled: true
VolumeSize: 100
VolumeType: gp3
EncryptionAtRestOptions:
Enabled: true
NodeToNodeEncryptionOptions:
Enabled: true
- VPC integration, IAM auth, fine-grained access control
- Serverless option for variable workloads
- Deep integration with AWS services (Kinesis, Lambda, CloudWatch)
Licensing Decision Tree
| Use Case | Recommendation |
|---|---|
| SaaS product embedding search | OpenSearch (Apache 2.0) |
| Internal enterprise search | Either |
| AWS-native infrastructure | OpenSearch on AWS |
| Multi-cloud or GCP/Azure | Elasticsearch |
| Advanced ML/AI search | Elasticsearch |
| Cost-sensitive startup | Evaluate both managed options |
Migration Considerations
Since OpenSearch forked at 7.10.2, migration from Elasticsearch 7.x → OpenSearch is straightforward. Migration from Elasticsearch 8.x → OpenSearch loses features (8.x APIs are not backward compatible with OpenSearch 2.x).
Bottom Line
Elasticsearch for new projects on non-AWS infrastructure — the ML features, mature ecosystem, and Elastic Cloud managed service are compelling. OpenSearch for AWS-native deployments and for any use case where Apache 2.0 licensing matters (embedding in products). The core search functionality is equivalent; the differences are licensing, ML features, and cloud ecosystem fit.