Unlike EC2 instances that can be stopped when not in use, AWS Elasticsearch Service operates on a continuous billing model. Many developers discover this the hard way when they see unexpected charges for test environments that were only needed temporarily. The service is designed to maintain persistent clusters rather than offering start/stop functionality.
Elasticsearch clusters require persistent storage and maintain complex internal states. AWS engineering teams have explained that pausing these clusters would:
- Require snapshotting all shard data and node states
- Need to preserve exact cluster topology and configurations
- Maintain security settings and IAM roles during the "stopped" period
Here are three approaches we've used successfully:
// Alternative 1: Scheduled Scaling with AWS Lambda
const AWS = require('aws-sdk');
const es = new AWS.ES();
exports.handler = async (event) => {
const params = {
DomainName: 'your-test-cluster',
ElasticsearchClusterConfig: {
InstanceType: 't2.small.elasticsearch', // Downgrade when not testing
InstanceCount: 1 // Minimum nodes
}
};
return es.updateElasticsearchDomainConfig(params).promise();
};
Create a CloudWatch Event that triggers during non-working hours:
Resources:
ScaleDownElasticsearch:
Type: AWS::Events::Rule
Properties:
ScheduleExpression: "cron(0 18 ? * MON-FRI *)"
Targets:
- Arn: !GetAtt ScaleDownLambda.Arn
Id: "ScaleDownTarget"
For truly temporary testing environments, consider automating the creation and deletion process:
#!/bin/bash
# Create test environment
aws es create-elasticsearch-domain --domain-name temp-test-env \
--elasticsearch-version 7.9 \
--elasticsearch-cluster-config InstanceType=t3.medium.elasticsearch,InstanceCount=1
# Your testing commands here...
# Cleanup when done
aws es delete-elasticsearch-domain --domain-name temp-test-env
When working with AWS OpenSearch Service (formerly Amazon Elasticsearch Service), many developers discover that unlike EC2 instances which can be stopped when not in use, OpenSearch domains continue running 24/7 - and billing accordingly. This becomes particularly painful for:
- Development and testing environments
- Proof-of-concept implementations
- Projects with intermittent search requirements
While AWS doesn't provide a simple "stop" button, here are practical approaches:
1. Scaling Down to Minimum Configuration
You can minimize costs by reducing your cluster to the smallest possible configuration:
aws opensearch update-domain-config --domain-name your-domain \
--cluster-config InstanceType=t3.small.search,InstanceCount=1 \
--ebs-options EBSEnabled=true,VolumeType=gp2,VolumeSize=10
This reduces costs to about $0.036/hour (for t3.small in us-east-1).
2. Scheduled Scaling with Lambda
For predictable usage patterns, implement automated scaling:
import boto3
def lambda_handler(event, context):
client = boto3.client('opensearch')
# Scale down at night
response = client.update_domain_config(
DomainName='dev-search',
ClusterConfig={
'InstanceType': 't3.small.search',
'InstanceCount': 1
}
)
return response
3. Snapshot and Delete (Most Cost-Effective)
For long periods of inactivity:
- Create manual snapshot to S3
- Delete the domain
- Restore from snapshot when needed
Option | Cost Savings | Recovery Time |
---|---|---|
Scaling Down | ~80% | Instant |
Snapshot & Delete | 100% | 15-30 minutes |
For development environments, consider:
- Local Docker containers running OpenSearch
- EC2 instances with self-managed OpenSearch (can be stopped)
- Serverless solutions like AWS Lambda with DynamoDB for simple search needs