Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions apps/realtime/src/database/operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,13 @@ import { env } from '@/env'
const logger = createLogger('SocketDatabase')

const connectionString = env.DATABASE_URL
/**
* Server-side safety net for runaway queries and abandoned transactions.
* See `packages/db/index.ts` for rationale.
*/
const socketDb = drizzle(
postgres(connectionString, {
prepare: false,
idle_timeout: 10,
connect_timeout: 20,
max: 30,
onnotice: () => {},
connection: {
options: '-c statement_timeout=90000 -c idle_in_transaction_session_timeout=90000',
},
}),
{ schema }
)
Expand Down
15 changes: 0 additions & 15 deletions packages/db/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,12 @@ if (!connectionString) {
throw new Error('Missing DATABASE_URL environment variable')
}

/**
* Server-side safety net for runaway queries and abandoned transactions:
* - `statement_timeout=90000` kills any single statement still running
* after 90s. Protects against pathological queries.
* - `idle_in_transaction_session_timeout=90000` kills a session that has
* opened a transaction and gone idle for 90s. Protects against
* transactions that hold row locks while waiting on external I/O.
*
* These are last-resort caps — application code should never approach
* them. Migrations or admin scripts that legitimately need longer limits
* must construct their own client with overrides.
*/
const postgresClient = postgres(connectionString, {
prepare: false,
idle_timeout: 20,
connect_timeout: 30,
max: 30,
onnotice: () => {},
connection: {
options: '-c statement_timeout=90000 -c idle_in_transaction_session_timeout=90000',
},
})
Comment on lines 13 to 19
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.

P2 Runaway query protection now absent at the application layer

With statement_timeout and idle_in_transaction_session_timeout removed, there is no longer a backstop against hung queries or transactions that hold row locks indefinitely. Under connection exhaustion (e.g., a blocked query monopolising all 30 slots), the pool can stall completely. The pooler-incompatibility issue is real and worth fixing, but consider re-applying the same limits at the database role level so they apply regardless of how the client connects:

ALTER ROLE <app_user> SET statement_timeout = '90s';
ALTER ROLE <app_user> SET idle_in_transaction_session_timeout = '90s';

This survives connection poolers and requires no client-side configuration.


export const db = drizzle(postgresClient, { schema })
Loading