---
title: "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

```toml
# config.toml
[storage]
query_timeout_ms = 30000  # 30 seconds (recommended for production)
```

```bash
export HELIOSDB_JWT_SECRET="$(openssl rand -hex 32)"
heliosdb-lite start --data-dir ./mydb --config config.toml
```

The timeout applies to every query on the server. The default is 300000 ms (5 minutes);
set a larger value for long-running batch work. `0` does not mean "no limit": it times out
every scanning query at once.

### Handle Timeout Errors

A query that exceeds the limit fails with an error your client receives like any other
SQL error:

```
Query timeout: Query exceeded timeout limit of 5000ms (elapsed: 5124ms)
```

```python
import psycopg2

try:
    cur.execute("SELECT * FROM large_table")
except psycopg2.Error as e:
    if "Query timeout" in str(e):
        # fall back to a cheaper query, or retry later
        cur.connection.rollback()
    else:
        raise
```

## Recommended Timeout Values

| Environment | Timeout | Notes |
|------------|---------|-------|
| Development | 60000 or more | 60s or longer 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 (the default) |
| Admin Tools | 3600000 | One hour for maintenance operations |

Different environments use different configuration files, for example
`config.dev.toml` with a longer timeout and `config.prod.toml` with 30000.

## Key Features

- **On by default:** 300000 ms (5 minutes) when the setting is left out
- **Minimal overhead:** <0.1% performance impact
- **Thread-safe:** Works with parallel execution
- **Granular control:** Configurable per database instance

## Performance Impact

| Check Frequency | Overhead |
|----------------|----------|
| Every 1000 rows | <0.1% |

Figures from internal tests (HeliosDB Lite, timeout check every 1000 rows); reproduce on your own hardware.
The server checks the clock more often than in that test: every 100 rows for timeouts of 100 ms
or more, every 50 rows below 100 ms and every 10 rows below 10 ms.

## Limitations

1. **Granularity:** Checked every 100 rows (every 50 or 10 rows for timeouts under 100 ms or 10 ms), not every row
2. **DDL Operations:** Not protected (CREATE TABLE, etc.)
3. **Blocking I/O:** Timeout suspended during I/O operations

## Troubleshooting

### Query Always Timing Out

**Problem:** Legitimate queries are timing out

**Solution:**
1. Increase timeout: `query_timeout_ms = 60000` (60s)
2. Optimize query (add indexes, reduce data scanned)
3. Use LIMIT to reduce result set size

### No Timeout Protection

**Problem:** Long queries still running

**Solution:**
1. Check that `query_timeout_ms` is in the `[storage]` section
2. Check that the server was started with `--config` pointing at that file
3. Restart the server after changing the file

### Timeout Too Strict

**Problem:** Complex analytical queries failing

**Solution:**
1. Increase timeout for specific workloads
2. Use batch processing for large operations
3. Run maintenance on a separate instance with a larger timeout

## Security Best Practices

- **Enable timeout in production**
- **Set conservative limits for public APIs**
- **Monitor timeout frequency**
- **Log timeout events**

## Further Reading

- [Configuration Reference](/docs/lite/user-guide/configuration/)

## Summary

Query timeout protection provides:
- Protection against resource exhaustion
- Minimal performance overhead (<0.1%)
- Easy configuration (one line)
- A 5-minute default that you can raise or lower

**Recommended Action:** Lower the timeout to 30 seconds for production deployments.
