Skip to content

chore(db): tune document autovacuum for connector sync churn - #7962

Merged
waleedlatif1 merged 2 commits into
stagingfrom
chore/document-autovacuum
Sep 18, 2026
Merged

waleedlatif1 merged 2 commits into
stagingfrom
chore/document-autovacuum

Conversation

@waleedlatif1

@waleedlatif1 waleedlatif1 commented Sep 18, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Sets per-table autovacuum scale factors on document so connector sync churn triggers cleanup well before the default 20% threshold would
  • Table-local storage parameters only: no row rewrite, no schema change, and no effect on existing readers or writers

Why

Connector syncs update this table in bursts large enough to outrun autovacuum at the default scale factor. Once dead rows accumulate, index-only scans can no longer trust the visibility map, so the knowledge base listing's token aggregate degrades into per-row heap fetches and the request can exceed its statement timeout.

Comparing the same query and the same data before and after autovacuum had caught up — with no change to the query, its indexes, or the schema — showed an order-of-magnitude difference in execution time, driven entirely by how many heap fetches the aggregate had to perform. The bloated case did not complete within the statement timeout.

Why these values, and not 0357's

0357 set more aggressive factors on outbox_event, a small queue table. This is one of the largest tables here and shares a small autovacuum worker pool with many other large tables, so triggering too eagerly would risk holding a worker continuously and starving its peers. These factors still trigger several times earlier than the defaults without monopolising the pool.

Per-table storage parameters are the documented mechanism for this. Cost limit and cost delay are deliberately left unset: PostgreSQL excludes tables carrying either from cross-worker I/O balancing, which is not a trade worth making on a table this busy.

What this does not fix

Even fully vacuumed, the listing aggregate scans the table's index entries for the knowledge base on every request and remains slow. That baseline is architectural rather than a maintenance problem and needs its own change.

Type of Change

  • Chore / maintenance

Testing

bun run check:migrations origin/staging passes (backward-compatible). Lint, check:audits (46 audits), docs-manifest:check, and type-check pass. Snapshot chain verified: 0362.prevId == 0361.id and the snapshot content is identical apart from the id pair, matching how 0357 recorded a settings-only migration.

Checklist

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

@vercel

vercel Bot commented Sep 18, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated
docs Ready Ready Preview Sep 18, 2026 5:55am 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.

No issues found across 3 files

Confidence score: 5/5

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

Tip: cubic can generate docs of your entire codebase and keep them up to date. Try it here.

Re-trigger cubic

Connector syncs update this table in bursts that outrun autovacuum at the
default 20% scale factor, which on a table of this size only triggers once dead
rows are already substantial. Sustained bloat stops index-only scans trusting
the visibility map, so the knowledge base listing's token aggregate degrades
into per-row heap fetches and can exceed its statement timeout.

The factors are less aggressive than 0357's on purpose. That one is a small
queue table, while this is one of the largest here and shares a small autovacuum
worker pool with many other large tables, so triggering too eagerly would risk
holding a worker continuously and starving its peers. Cost limit and cost delay
are left unset so the table stays inside cross-worker I/O balancing.
@greptile-apps

greptile-apps Bot commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

The PR appears safe to merge with no actionable correctness, security, or migration-chain issues identified.

Summary

Adds a storage-only PostgreSQL migration that tunes autovacuum for connector-driven churn on the document table.

  • Lowers the table-local vacuum scale factor to 0.05 and analyze scale factor to 0.02.
  • Preserves existing table storage parameters and makes no schema or row-format change.
  • Extends the Drizzle snapshot and journal chain without introducing schema drift.

Reviews (1) · Last reviewed commit: 9bffde0

Comments describing measured behaviour carried absolute production sizing —
index byte sizes, chunk and row totals — which the repo's publishing rules
exclude and which a public reader does not need. The measurements that justify
each decision stay; only the figures that size production are replaced.

The ship scrub missed these because its grep matched identities and IDs but
never numbers, and because code and migration comments do not feel like
publishing even though they are. It now states the distinction explicitly and
greps the diff for byte sizes, k/M-scale entity counts, and seven-figure totals,
while deliberately still allowing ordinary engineering numbers.
@waleedlatif1
waleedlatif1 merged commit bad0ce4 into staging Sep 18, 2026
23 of 24 checks passed
@waleedlatif1
waleedlatif1 deleted the chore/document-autovacuum branch September 18, 2026 05:54
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