Skip to content

fix(db): isolate billing and auth connection pools, release the redeploy-check transaction early, cache integration tool schemas - #9347

Merged
waleedlatif1 merged 6 commits into
stagingfrom
fix/pool-billing
Oct 23, 2026
Merged

waleedlatif1 merged 6 commits into
stagingfrom
fix/pool-billing

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • Billing writes and auth lookups get their own connection pools (dbFor('billing'), 4 connections; dbFor('auth'), 3). When slow work saturates a process's 10-connection pool, postgres.js pipelines new queries onto busy connections, so a billing transaction's BEGIN could wait behind a large result and be killed by its 4s transaction_timeout. Settlement transactions (recordCumulativeUsage, recordUsage fallback, threshold billing, the execution-logger usage reconcile, job spend) and the auth adapter, getAuthDatabase() fallback and API-key lookup now run on their own clients. App-wide billing reads stay on db so they don't crowd a small pool
  • isPrimaryPoolClient() in @sim/db replaces the executor === db checks that gate the auth policy caches and the reporting usage cache, so those caches still apply on a sub-pool client and never on a transaction or the replica
  • DATABASE_URL_BILLING / DATABASE_URL_AUTH are optional; unset, the pools fall back to the process URL, which already gives the client-side isolation
  • checkNeedsRedeployment keeps every read in its REPEATABLE READ snapshot but runs the state diff after commit, so the connection is no longer held idle in transaction during the comparison
  • Integration tool schemas are built once per process per surface/mode, frozen and shared, instead of per viewer with a 5s TTL (every call rebuilt ~5.3k schemas, stringified them to size the cache and deep-cloned them). Viewer gating and the plan-dependent email tagline still apply per request; output is byte-identical. BM25 term counts are memoized per shared schema

Type of Change

  • Bug fix

Testing

  • New lib/db/pool-isolation.integration.ts: fills every connection of the real db pool, then requires a cumulative usage write, an auth adapter session read and an API-key lookup to finish within 1.5s. Fails on the pre-fix code (all three stall), passes with the fix
  • Integration: pool-isolation, usage-log, reporting-usage-cache, get-organization-plan-seats (57 tests) against disposable Postgres
  • Unit: new deployment-status.test.ts (diff no longer runs while the transaction is open; red pre-fix), db.test.ts, auth cache-identity case in security-policy.test.ts (red with executor === db), payload tests (one build per process, cross-viewer isolation, tagline per viewer; red pre-fix), plus 54 neighbouring files (635 tests)
  • check:tool-registry-boundary, check:schema-mock, check:test-patterns, check:utils, check:comment-hygiene, check:unused-exports, check:file-names; generators in sync. Type-check and full audits run in CI

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing (new tests pass the test-audit authoring gate)
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

postgres.js pipelines new queries onto busy connections when none is idle,
so slow reads saturating the process pool made short usage-ledger
transactions wait seconds for BEGIN until Postgres killed them.

- Add `billing` (4) and `auth` (3) dbFor roles, with DATABASE_URL_BILLING
  and DATABASE_URL_AUTH overrides falling back to the process URL.
- Billing pool: recordCumulativeUsage, recordUsage without a caller tx,
  the execution logger's usage reconciliation, both threshold settlement
  transactions, and recordJobRunSpend. Each moved transaction only queries
  through its tx handle; readers stay on the process pool.
- Auth pool: getAuthPool() backs the Better Auth adapter, getAuthDatabase()
  outside a transaction, the OAuth adapter guard defaults, and the API-key
  hash lookup.
- isPrimaryPoolClient() in @sim/db replaces the `executor === db` checks in
  the security, session, and SSO policy caches, so reads through the auth
  pool keep hitting them instead of costing two queries per cached session.
- Integration test saturates the process pool and requires the billing
  write, an adapter session read, and an API-key lookup to finish anyway.
…ion commits

checkNeedsRedeployment ran the full workflow diff inside its REPEATABLE READ
transaction, holding a pooled connection idle in transaction during CPU work.
Reads (active version, normalized draft, variables, credential migrations)
stay in the snapshot; the pure diff now runs after commit.
…ead of per user every 5s

The integration catalog cached each viewer's full schema set for 5s, so nearly
every call rebuilt a user-tool schema for all ~5.3k exposed tools, sized the
~7.7MB result with JSON.stringify, structuredClone'd it, and re-tokenized
every tool for BM25 - all synchronously.

The schemas depend only on the registry and deployment config, so they are now
built once per (surface, personal mode), frozen, and shared; the build yields
between tools. Each request still applies the viewer's own block visibility and
permission policy, and the plan-dependent email tagline is read per user with
the same 5s TTL. Results are byte-identical. BM25 term counts are memoized per
shared schema object.
Assert each frozen-schema mutation throws, rank BM25 by query terms instead of
copying each tool's vocabulary, gate the reporting usage cache on
isPrimaryPoolClient like the auth caches, and trim comments.
@vercel

vercel Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated
docs Skipped Skipped Oct 23, 2026 9:08pm UTC

Request Review

@cubic-dev-ai cubic-dev-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.

All reported issues were addressed across 31 files

Heads up: you’re close to your flex budget. Increase your flex budget so reviews don’t pause.

Turn on auto-fix | Re-trigger cubic

Comment thread packages/testing/src/mocks/database.mock.ts
Comment thread apps/sim/lib/api-key/service.ts
@greptile-apps

greptile-apps Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 5/5

[High impact] The PR appears safe to merge; no blocking issues were found.

Summary

The PR separates billing and auth database pools, moves workflow comparisons outside the database transaction, and shares frozen integration tool schemas.

  • Billing and auth work use separate database pools.
  • Integration tool schemas are built once and shared across viewers.
  • Redeployment checks compare workflow states after the snapshot transaction commits.

Reviews (3) · Last reviewed commit: "test(db): close every pool the isolation..." · Reviewed by Greptile

Give the memory harness integration mock a dbFor so the billing pool resolves.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@waleedlatif1 I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-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.

All reported issues were addressed across 33 files

Heads up: you’re close to your flex budget. Increase your flex budget so reviews don’t pause.

Turn on auto-fix | Re-trigger cubic

Comment thread apps/sim/lib/db/pool-isolation.integration.ts Outdated
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@waleedlatif1 I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-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.

No issues found across 33 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Heads up: you’re close to your flex budget. Increase your flex budget so reviews don’t pause.

Turn on auto-fix | Re-trigger cubic

@waleedlatif1
waleedlatif1 merged commit 42f3409 into staging Oct 23, 2026
67 checks passed
@waleedlatif1
waleedlatif1 deleted the fix/pool-billing branch October 23, 2026 21:19

This branch was previously deployed

1 inactive deployment
Preview — a25160c0 Deployed Oct 23, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant