Skip to content

⚡️ perf(database): add optional statement_timeout to server DB connections#15445

Merged
arvinxx merged 1 commit into
canaryfrom
feat/db-statement-timeout
Jun 4, 2026
Merged

⚡️ perf(database): add optional statement_timeout to server DB connections#15445
arvinxx merged 1 commit into
canaryfrom
feat/db-statement-timeout

Conversation

@arvinxx

@arvinxx arvinxx commented Jun 3, 2026

Copy link
Copy Markdown
Member

💻 Change Type

  • ⚡️ perf

🔗 Related Issue

🔀 Description of Change

Long-running queries (an insert observed stuck for 700s under lock contention) could block indefinitely, because Postgres' statement_timeout defaults to 0 (no limit) and neither the node (pg) nor the neon (@neondatabase/serverless) pool configured any timeout.

This adds an optional DATABASE_STATEMENT_TIMEOUT env (in milliseconds, no default — unset keeps the previous behavior), applied to both NodePool and NeonPool:

  • statement_timeout — Postgres aborts any single statement exceeding the limit on the server side, actually freeing the backend (not just a client-side reject).
  • idle_in_transaction_session_timeout — kills a transaction left idle past the limit, so a stuck transaction can't keep holding row locks.

Both drivers natively support these keys in their pool config (verified against their type defs / pg client implementation). When the env is unset, the timeout keys are omitted entirely, preserving Postgres defaults.

.env.example documents the new variable (suggested 300000 = 300s).

🧪 How to Test

  • Tested locally
  • Added/updated tests
  • No tests needed

Set DATABASE_STATEMENT_TIMEOUT=5000, run a query that exceeds 5s (e.g. SELECT pg_sleep(10)), and confirm Postgres aborts it with canceling statement due to statement timeout. With the env unset, behavior is unchanged.

📝 Additional Information

statement_timeout is server-side termination (the robust knob for "kill blocking queries"); a client-side query_timeout was intentionally not added, since it only rejects the JS promise while the statement can keep running on the server.

🤖 Generated with Claude Code

…tions

Long-running queries (e.g. an insert stuck for 700s on lock contention)
could block indefinitely because Postgres' statement_timeout defaults to
0 (no limit) and neither the node nor neon pool configured one.

Add an optional DATABASE_STATEMENT_TIMEOUT env (milliseconds, no default)
applied to both NodePool and NeonPool as statement_timeout and
idle_in_transaction_session_timeout, so Postgres aborts a stuck statement
or idle transaction on the server side. Unset keeps the previous behavior.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@dosubot dosubot Bot added the size:S This PR changes 10-29 lines, ignoring generated files. label Jun 3, 2026
@vercel

vercel Bot commented Jun 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
lobehub Ready Ready Preview, Comment Jun 3, 2026 6:02pm

Request Review

@dosubot dosubot Bot added the ⚡️ Performance Performance issue label Jun 3, 2026

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've reviewed this pull request using the Sourcery rules engine

@codecov

codecov Bot commented Jun 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 70.88%. Comparing base (a3a08c2) to head (4732a2e).
⚠️ Report is 1 commits behind head on canary.

Additional details and impacted files
@@             Coverage Diff             @@
##           canary   #15445       +/-   ##
===========================================
- Coverage   89.70%   70.88%   -18.82%     
===========================================
  Files         862     3223     +2361     
  Lines      105731   319682   +213951     
  Branches    10246    34782    +24536     
===========================================
+ Hits        94841   226593   +131752     
- Misses      10714    92913    +82199     
  Partials      176      176               
Flag Coverage Δ
app 61.58% <100.00%> (?)
database 92.49% <ø> (ø)
packages/agent-runtime 80.48% <ø> (ø)
packages/builtin-tool-lobe-agent 18.52% <ø> (ø)
packages/context-engine 84.17% <ø> (ø)
packages/conversation-flow 91.29% <ø> (ø)
packages/file-loaders 87.89% <ø> (ø)
packages/memory-user-memory 74.99% <ø> (ø)
packages/model-bank 99.99% <ø> (ø)
packages/model-runtime 84.51% <ø> (ø)
packages/prompts 72.49% <ø> (ø)
packages/python-interpreter 92.90% <ø> (ø)
packages/ssrf-safe-fetch 0.00% <ø> (ø)
packages/types 35.36% <ø> (ø)
packages/utils 88.77% <ø> (ø)
packages/web-crawler 88.08% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
Store 68.48% <ø> (∅)
Services 54.58% <ø> (∅)
Server 71.89% <ø> (∅)
Libs 57.01% <ø> (∅)
Utils 81.44% <ø> (-18.56%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@arvinxx arvinxx merged commit 951561f into canary Jun 4, 2026
48 checks passed
@arvinxx arvinxx deleted the feat/db-statement-timeout branch June 4, 2026 04:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

⚡️ Performance Performance issue size:S This PR changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant