feat(server): make the Postgres pool ceiling configurable - #2700
Conversation
The Postgres store hardcoded max_connections(10), which makes the pool the throughput limit under concurrent sandbox creation. Once all ten are checked out, callers queue on acquire and sqlx starts logging "time to acquire exceeded slow threshold"; sandbox creates then time out and get retried, which adds load rather than shedding it. The right ceiling is deployment-specific — it depends on how many gateway replicas share the server and what max_connections the server itself allows — so it cannot be a single number baked into the binary. OPENSHELL_DB_MAX_CONNECTIONS now sets it, defaulting to 10 so existing deployments are unchanged. Unset, unparseable and zero all fall back to the default: a typo should degrade to today's behaviour rather than crash-loop the gateway, and zero would deadlock every acquire. Refs: NVIDIA#2561 Signed-off-by: Bryce Wilkinson <bwilkinson@alpha-sense.com>
|
Thank you for your interest in contributing to OpenShell, @bjw123. This project uses a vouch system for first-time contributors. Before submitting a pull request, you need to be vouched by a maintainer. To get vouched:
See CONTRIBUTING.md for details. |
|
Thank you for your submission! We ask that you sign our Developer Certificate of Origin before we can accept your contribution. You can sign the DCO by adding a comment below using this text: I have read the DCO document and I hereby sign the DCO. You can retrigger this bot by commenting recheck in this Pull Request. Posted by the DCO Assistant Lite bot. |
|
Thanks for this @bjw123 — clean change and the field evidence is genuinely useful (the SQLite pool-5 vs Postgres-10 comparison makes the "removing a fixed ceiling, not fixing a wrong default" framing convincing). Heads up: I'm a contributor here, not a maintainer, so this isn't a merge review — the PR is auto-closed until you're vouched and #2561 is still What looks good
Two things a maintainer will likely raise
Neither is a correctness issue — the code itself is solid. Thanks again for contributing the patch and the load-test numbers. |
|
Superseded by #2828, now that I'm vouched (thanks @elezar). GitHub refused to reopen this one after the rebase, so the work moved to a fresh PR against current @letv1nnn — both of your points are addressed there: the knob is now a clap arg + One thing I changed my mind on from this PR, flagged in case you disagree: invalid values now fail fast instead of falling back to the default. Silently ignoring a typo would leave the operator on the very ceiling they were trying to lift, which is the failure mode the change exists to remove. Thanks again for the review — it's what the new PR is built on. |
Summary
PostgresStore::connecthardcodesmax_connections(10). This makes the pool the throughput ceiling under concurrent sandbox creation, and it cannot be tuned without rebuilding the gateway.OPENSHELL_DB_MAX_CONNECTIONSnow sets it, defaulting to 10 so existing deployments are unchanged.Related Issue
Refs #2561.
Changes
max_connections()readsOPENSHELL_DB_MAX_CONNECTIONS, falling back to the previous hardcoded 10.acquire.Matches the existing convention in this crate —
std::env::var("OPENSHELL_*")read directly, ascompute/driver_config.rsandcompute/lease.rsalready do. Threading a parameter throughStore::connectwas avoided because it has ~10 call sites, nearly all tests.Testing
cargo test -p openshell-server --lib max_connections_tests— 3 new tests: default when unset, override honoured (including surrounding whitespace), and each unusable input falling back rather than panicking.mise run pre-commitpasses.Field evidence
Measured on a 1,000-sandbox load test against a gateway on SQLite (pool 5), where the pool was unambiguously the constraint:
42 of 1,000 forwarders reached ready after 40 minutes, and the retries became load in their own right — 1,552 sandbox pods for 1,000 requested.
For balance: the same 1,000-sandbox test against Postgres at the stock ceiling of 10 produced exactly one slow-acquire (at startup), zero pool timeouts and 527m gateway CPU. So on Postgres the current default holds well at that scale — this change is about removing a fixed ceiling that cannot be tuned as fleets grow, not about a default that is wrong today.
Checklist
mise run pre-commitpasses