Skip to content

fix(registry): stop egressing scan reports on hot read paths#121

Merged
mgoldsborough merged 1 commit into
mainfrom
fix/registry-db-egress
Jun 4, 2026
Merged

fix(registry): stop egressing scan reports on hot read paths#121
mgoldsborough merged 1 commit into
mainfrom
fix/registry-db-egress

Conversation

@mgoldsborough

Copy link
Copy Markdown
Contributor

Problem

Supabase reported ~14 GB of database egress for a 26 MB database. Empirically traced (read-only, against production) to a single column.

The MCP registry listing (/servers, /servers/search), /v1/bundles list + detail, and the package server-lookup endpoints eager-load entire security_scans rows — including the full report JSON — when the only fields consumed are the four MTF certification scalars (certificationLevel, controlsPassed/Failed/Total).

Measurements (production)

Metric Value
Total DB size 26 MB
report on disk (TOAST-compressed) ~16 KB avg
report over the wire (decompressed JSON) ~120 KB avg, ~700 KB max
security_scans rows fetched since 2025-12-08 ~190k (index)
Est. egress from report alone ~22 GB

pg_column_size reports the compressed on-disk size; Postgres ships the column decompressed (7.5× expansion), which is why the egress number dwarfs the dataset. Everything else in the schema combined is ~1–2 GB.

Changes

  • Add SCAN_CERT_SELECT and project the securityScans relation to the four cert fields in findPackageForServerLookup, findPackagesForServerListing, and findVersionWithLatestScan. The full report is still served by the dedicated scan endpoints (separate queries, untouched).
  • Narrow getVersions to { version, publishedAt, downloadCount } — the bundle detail page was fetching every version's manifest/readme/serverJson/provenance to emit three small fields per version.
  • Add Cache-Control: public, max-age=60, s-maxage=300 to the crawled JSON listing/detail endpoints so a shared cache absorbs repeat hits.

Read paths only; no schema or write changes.

Verification

pnpm typecheck, pnpm lint, and pnpm --filter @nimblebrain/mpak-registry test (134 tests) all pass.

Follow-up (not in this PR)

The version-level readme/serverJson/sourceIndex columns are still eager-loaded on the server-lookup paths (the secondary ~1 GB contributor). Worth a projection pass if egress doesn't drop far enough, but it requires a wider type refactor of PackageForServerLookup.

The MCP registry listing (`/servers`, `/servers/search`), the
`/v1/bundles` list/detail, and the package server-lookup endpoints
eager-loaded entire `security_scans` rows — including the full `report`
JSON — when the only fields consumed are the four MTF certification
scalars (`certificationLevel`, `controlsPassed/Failed/Total`).

`report` averages ~16 KB TOAST-compressed on disk but ~120 KB
uncompressed over the wire (max ~700 KB). With the scan row fetched
~190k+ times since early December, this single column accounted for an
estimated ~22 GB of Supabase database egress against a 26 MB database —
the rest of the schema combined is ~1–2 GB.

Changes:
- Add `SCAN_CERT_SELECT` and project the `securityScans` relation to the
  four cert fields in `findPackageForServerLookup`,
  `findPackagesForServerListing`, and `findVersionWithLatestScan`. The
  full report is still served by the dedicated scan endpoints, which run
  their own queries.
- Narrow `getVersions` to `{ version, publishedAt, downloadCount }` — the
  bundle detail page fetched every version's `manifest`/`readme`/
  `serverJson`/`provenance` to emit three small fields per version.
- Add `Cache-Control: public, max-age=60, s-maxage=300` to the crawled
  JSON listing/detail endpoints so a shared cache absorbs repeat hits.

Read paths only; no schema or write changes.
@mgoldsborough mgoldsborough added the qa-reviewed QA review completed with no critical issues label May 29, 2026
@mgoldsborough
mgoldsborough merged commit c62ef58 into main Jun 4, 2026
2 checks passed
@mgoldsborough
mgoldsborough deleted the fix/registry-db-egress branch June 8, 2026 01:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

qa-reviewed QA review completed with no critical issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant