Deployment and operations
Operations and capacity planning
Understand AskTable's default database connection capacity and troubleshoot DATABASE_BUSY.
The default configuration suits typical single-server deployments. If DATABASE_BUSY is not recurring and you have not added Web or Worker processes, there is no need to change the connection pools.
Default connection capacity
| Item | Default |
|---|---|
| Web processes | 1 |
| Main database connection limit per Web process | 20 (pool 10 + overflow 10) |
| Worker processes | 1 |
| Main database connection limit per Worker process | 10 (pool 5 + overflow 5) |
| Workbook connection limit per process | 10 |
Built-in PostgreSQL max_connections | 100 |
With Workbook enabled by default, the application's conservative peak is 51 connections:
Web 20 + Worker 10 + Workbook 20 + LISTEN/NOTIFY 1 = 51Under the default process configuration above, PostgreSQL's limit of 100 leaves headroom. Recalculate when adding processes or sharing the instance with other applications. POOL_SIZE is the number of connections retained by the pool, not its connection limit; add MAX_OVERFLOW to obtain the limit.
When DATABASE_BUSY occurs
DATABASE_BUSY means AskTable temporarily could not obtain a database connection, or PostgreSQL has reached its connection limit. The page retries automatically; you can retry manually if it has not recovered.
If the error recurs:
- Check logs to determine whether it comes from Web requests or background refreshes.
- When background refreshes are busy, lower
AT_WORKER_MAX_JOBSfirst. - If PostgreSQL reports exhausted connections, do not keep increasing the connection pool.
- Increase the corresponding Web or Worker pool only after confirming that PostgreSQL still has headroom and the local pool is timing out while waiting.
When adding processes
Each additional Web process adds one Web main database pool, at most one Workbook pool, and one LISTEN/NOTIFY connection. Each additional Worker process adds one Worker main database pool and at most one Workbook pool.
The recommended adjustment order is: shorten transactions, lower background concurrency, adjust the corresponding role's connection pool, and only then increase the PostgreSQL limit. Always reserve at least 10 connections for migrations and manual troubleshooting.
Complete configuration reference
All settings are static environment variables; restart the corresponding processes after making changes.
| Setting | Default | Description |
|---|---|---|
AT_SERVER_WORKERS | 1 | Number of Web processes; the command-line --workers option takes precedence |
AT_WEB_DB_POOL_SIZE | 10 | Main database connections retained per Web process |
AT_WEB_DB_MAX_OVERFLOW | 10 | Additional temporary connections when the Web pool is full |
AT_WORKER_NUM_PROCS | 1 | Number of Worker processes |
AT_WORKER_MAX_JOBS | 10 | Maximum concurrent jobs per Worker |
AT_WORKER_DB_POOL_SIZE | 5 | Main database connections retained per Worker process |
AT_WORKER_DB_MAX_OVERFLOW | 5 | Additional temporary connections when the Worker pool is full |
AT_DB_POOL_TIMEOUT | 30 | Maximum seconds to wait for a main database connection |
AT_DB_POOL_RECYCLE | 300 | Main database connection recycling interval in seconds |
WORKBOOK_PG_DSN | A separate database in the local main database instance | A non-empty value enables it; explicitly set an empty value to disable it |
AT_WORKBOOK_POOL_MIN | 1 | Minimum Workbook connections retained per process |
AT_WORKBOOK_POOL_MAX | 10 | Maximum Workbook connections used per process |
Web and Worker pool capacities are configured separately; both process types share timeout and recycling intervals. All pool parameters must be non-negative, and Workbook requires 0 <= MIN <= MAX.
Calculate the exact connection limit
B is AT_WORKBOOK_POOL_MAX when Workbook is enabled, or 0 otherwise.
Application connection limit =
AT_SERVER_WORKERS
× (AT_WEB_DB_POOL_SIZE + AT_WEB_DB_MAX_OVERFLOW + B + 1)
+ AT_WORKER_NUM_PROCS
× (AT_WORKER_DB_POOL_SIZE + AT_WORKER_DB_MAX_OVERFLOW + B)The application connection limit plus at least 10 operations connections must be less than PostgreSQL's available connections for ordinary users. That number is max_connections minus reserved_connections and superuser_reserved_connections.
Inspect connection usage
Check PostgreSQL limits:
SHOW max_connections;
SHOW reserved_connections;
SHOW superuser_reserved_connections;Check connection sources and long transactions:
SELECT application_name, state, count(*) AS connections,
max(now() - xact_start) AS longest_transaction
FROM pg_stat_activity
WHERE datname IN ('asktable', 'asktable_workbook')
GROUP BY application_name, state
ORDER BY connections DESC;Check container logs:
docker compose logs --since=30m asktable | grep -E 'DATABASE_BUSY|creating postgresql pool|refresh_table_task'
docker compose logs --since=30m asktable-pgWhen using external PostgreSQL, use the actual connection limit provided by the database provider. AskTable does not change it automatically.
See Private deployment (Docker) and Version upgrades and migration for deployment and upgrade procedures.