Elasticsearch Query Performance Optimization Guide
System-Level Optimizations
Garbage Collection (GC) Tuning
Elasticsearch relies heavily on the JVM, making GC performance critical for query response times. Poor GC configuration can lead to query timeouts and cluster instability.
Production Best Practices:
- Use G1GC for heaps larger than 6GB:
-XX:+UseG1GC
- Set heap size to 50% of available RAM, but never exceed 32GB
- Configure GC logging for monitoring:
-Xloggc:gc.log -XX:+PrintGCDetails
1 | # Optimal JVM settings for production |
Interview Insight: “Why is 32GB the heap size limit?” - Beyond 32GB, the JVM loses compressed OOPs (Ordinary Object Pointers), effectively doubling pointer sizes and reducing cache efficiency.
Memory Management and Swappiness
Swapping to disk can destroy Elasticsearch performance, turning millisecond operations into second-long delays.
Configuration Steps:
- Disable swap entirely:
sudo swapoff -a
- Configure swappiness:
vm.swappiness=1
- Enable memory locking in Elasticsearch:
1 | # elasticsearch.yml |
Production Example:
1 | # /etc/sysctl.conf |
File Descriptors Optimization
Elasticsearch requires numerous file descriptors for index files, network connections, and internal operations.
1 | # /etc/security/limits.conf |
Monitoring Script:
1 |
|
Query Optimization Strategies
Pagination Performance
Deep pagination is one of the most common performance bottlenecks in Elasticsearch applications.
Problem with Traditional Pagination
graph
A[Client Request: from=10000, size=10] --> B[Elasticsearch Coordinator]
B --> C[Shard 1: Fetch 10010 docs]
B --> D[Shard 2: Fetch 10010 docs]
B --> E[Shard 3: Fetch 10010 docs]
C --> F[Coordinator: Sort 30030 docs]
D --> F
E --> F
F --> G[Return 10 docs to client]
Solution 1: Scroll API
Best for processing large datasets sequentially:
1 | # Initial scroll request |
Production Use Case: Log processing pipeline handling millions of documents daily.
Solution 2: Search After API
Ideal for real-time pagination with live data:
1 | # First request |
Interview Insight: “When would you choose search_after over scroll?” - Search_after is stateless and handles live data changes better, while scroll is more efficient for complete dataset processing.
Bulk Operations Optimization
The _bulk
API significantly reduces network overhead and improves indexing performance.
Bulk API Best Practices
1 | POST /_bulk |
Production Implementation:
1 | from elasticsearch import Elasticsearch |
Performance Tuning:
- Optimal batch size: 1000-5000 documents or 5-15MB
- Use multiple threads for parallel bulk requests
- Monitor queue sizes and adjust accordingly
Index-Level Optimizations
Refresh Frequency Optimization
The refresh operation makes documents searchable but consumes significant resources.
1 | # elasticsearch.yml - Global setting |
Use Case Example:
1 | # High-volume logging scenario |
Field Optimization Strategies
Disable unnecessary features to reduce index size and improve query performance.
Source Field Optimization
1 | # Disable _source for analytics-only indices |
Doc Values Optimization
1 | # Disable doc_values for fields that don't need aggregations/sorting |
Interview Insight: “What are doc_values and when should you disable them?” - Doc_values enable aggregations, sorting, and scripting but consume disk space. Disable for fields used only in queries, not aggregations.
Data Lifecycle Management
Separate hot and cold data for optimal resource utilization.
graph
A[Hot Data<br/>SSD Storage<br/>Frequent Access] --> B[Warm Data<br/>HDD Storage<br/>Occasional Access]
B --> C[Cold Data<br/>Archive Storage<br/>Rare Access]
A --> D[High Resources<br/>More Replicas]
B --> E[Medium Resources<br/>Fewer Replicas]
C --> F[Minimal Resources<br/>Compressed Storage]
ILM Policy Example:
1 | PUT _ilm/policy/logs_policy |
Memory and Storage Optimization
Off-Heap Memory Optimization
Elasticsearch uses off-heap memory for various caches and operations.
Circuit Breaker Configuration:
1 | # elasticsearch.yml |
Field Data Cache Management:
1 | # Monitor field data usage |
Production Monitoring Script:
1 |
|
Shard Optimization
Proper shard sizing is crucial for performance and cluster stability.
Shard Count and Size Guidelines
graph
A[Determine Shard Strategy] --> B{Index Size}
B -->|< 1GB| C[1 Primary Shard]
B -->|1-50GB| D[1-5 Primary Shards]
B -->|> 50GB| E[Calculate: Size/50GB]
C --> F[Small Index Strategy]
D --> G[Medium Index Strategy]
E --> H[Large Index Strategy]
F --> I[Minimize Overhead]
G --> J[Balance Performance]
H --> K[Distribute Load]
Shard Calculation Formula:
1 | def calculate_optimal_shards(index_size_gb, node_count): |
Production Shard Settings:
1 | PUT /optimized_index |
Query Performance Patterns
Efficient Query Patterns
1 | # Use filter context for exact matches (cacheable) |
Aggregation Optimization
1 | # Use composite aggregations for large cardinality |
Monitoring and Troubleshooting
Performance Metrics
1 | # Key performance APIs |
Slow Query Analysis:
1 | # Enable slow query logging |
Common Performance Anti-Patterns
Interview Questions & Solutions:
“Why are my deep pagination queries slow?”
- Use scroll API for sequential processing
- Use search_after for real-time pagination
- Implement caching for frequently accessed pages
“How do you handle high cardinality aggregations?”
- Use composite aggregations with pagination
- Implement pre-aggregated indices for common queries
- Consider using terms aggregation with execution_hint
“What causes high memory usage in Elasticsearch?”
- Large field data caches from aggregations
- Too many shards causing overhead
- Inefficient query patterns causing cache thrashing
Advanced Optimization Techniques
Index Templates and Aliases
1 | # Optimized index template |
Machine Learning and Anomaly Detection
1 | # Use ML for capacity planning |
Conclusion
Elasticsearch query performance optimization requires a holistic approach combining system-level tuning, query optimization, and proper index design. The key is to:
- Monitor continuously - Use built-in monitoring and custom metrics
- Test systematically - Benchmark changes in isolated environments
- Scale progressively - Start with simple optimizations before complex ones
- Plan for growth - Design with future data volumes in mind
Critical Interview Insight: “Performance optimization is not a one-time task but an ongoing process that requires understanding your data patterns, query characteristics, and growth projections.”