Query Timeout Protection - Quick Reference
Query Timeout Protection - Quick Reference
What is it?
Query timeout protection prevents resource exhaustion by automatically terminating queries that run longer than a configured time limit.
Quick Start
Enable Timeout
use heliosdb_nano::{EmbeddedDatabase, Config};
let mut config = Config::default();config.storage.query_timeout_ms = Some(30000); // 30 seconds
let db = EmbeddedDatabase::new_with_config(config)?;Handle Timeout Errors
use heliosdb_nano::Error;
match db.query("SELECT * FROM large_table") { Err(Error::QueryTimeout(msg)) => { println!("Query timed out: {}", msg); // Handle timeout } Ok(results) => { println!("Success: {} rows", results.len()); } Err(e) => { println!("Error: {}", e); }}Configuration
Via Config File (TOML)
[storage]query_timeout_ms = 30000 # 30 seconds (recommended for production)Via Code
// Set timeoutconfig.storage.query_timeout_ms = Some(5000); // 5 seconds
// Disable timeoutconfig.storage.query_timeout_ms = None; // Unlimited (default)Recommended Timeout Values
| Environment | Timeout | Notes |
|---|---|---|
| Development | None or 60000 | Unlimited or 60s for debugging |
| Production | 30000 | 30 seconds is a good default |
| Public API | 10000 | 10 seconds for user-facing queries |
| Background Jobs | 300000 | 5 minutes for batch processing |
| Admin Tools | None | Unlimited for maintenance operations |
Error Message Format
Query timeout: Query exceeded timeout limit of 5000ms (elapsed: 5124ms)Key Features
- Zero-config compatibility: Disabled by default
- Minimal overhead: <0.1% performance impact
- Thread-safe: Works with parallel execution
- Granular control: Configurable per database instance
Performance Impact
| Check Frequency | Overhead | Current Setting |
|---|---|---|
| Every 1000 rows | <0.1% | ✓ Default |
Limitations
- Granularity: Checked every 1000 rows, not every row
- DDL Operations: Not protected (CREATE TABLE, etc.)
- Blocking I/O: Timeout suspended during I/O operations
Common Use Cases
Prevent Runaway Queries
// Prevent expensive queries from running foreverconfig.storage.query_timeout_ms = Some(30000);Different Timeouts for Different Environments
let timeout = if cfg!(debug_assertions) { None // Unlimited in development} else { Some(30000) // 30 seconds in production};
config.storage.query_timeout_ms = timeout;Graceful Degradation
match db.query(complex_query) { Err(Error::QueryTimeout(_)) => { // Fall back to simpler query db.query(simple_query)? } result => result,}Troubleshooting
Query Always Timing Out
Problem: Legitimate queries are timing out
Solution:
- Increase timeout:
query_timeout_ms = Some(60000)(60s) - Optimize query (add indexes, reduce data scanned)
- Use LIMIT to reduce result set size
No Timeout Protection
Problem: Long queries still running
Solution:
- Verify configuration:
config.storage.query_timeout_ms.is_some() - Check error handling catches
Error::QueryTimeout - Ensure database created with updated config
Timeout Too Strict
Problem: Complex analytical queries failing
Solution:
- Increase timeout for specific workloads
- Use batch processing for large operations
- Consider disabling timeout for admin operations
Migration from v1.x
No breaking changes!
Timeout is disabled by default. To enable:
// Before (v1.x)let db = EmbeddedDatabase::new()?;
// After (v2.x with timeout)let mut config = Config::default();config.storage.query_timeout_ms = Some(30000);let db = EmbeddedDatabase::new_with_config(config)?;Security Best Practices
✓ Enable timeout in production ✓ Set conservative limits for public APIs ✓ Monitor timeout frequency ✓ Log timeout events
Further Reading
Summary
Query timeout protection provides:
- Protection against resource exhaustion
- Minimal performance overhead (<0.1%)
- Easy configuration (one line)
- Backward compatible (disabled by default)
- Production-ready security enhancement
Recommended Action: Enable with 30 second timeout for all production deployments.