Skip to content

docs: performance investigations for importers pagination, oracle feed contention, metrics refresh, and GIN index - #1172

Merged
vjuliaife merged 4 commits into
vjuliaife:mainfrom
pre-cious-Igwealor:fix/tariffshield-perf-investigation-batch
Aug 28, 2026
Merged

docs: performance investigations for importers pagination, oracle feed contention, metrics refresh, and GIN index#1172
vjuliaife merged 4 commits into
vjuliaife:mainfrom
pre-cious-Igwealor:fix/tariffshield-perf-investigation-batch

Conversation

@pre-cious-Igwealor

Copy link
Copy Markdown
Contributor

Summary

Four performance investigations, each documented in docs/investigations/ with a code-level analysis and a concrete recommendation (and, where warranted, an applied fix):

Closes #1090
Closes #1092
Closes #1091
Closes #1093

Disclosure

No live Postgres instance was available in the environment these investigations were originally done in, so the acceptance criteria's benchmark/EXPLAIN ANALYZE/throughput measurements were not captured — each doc's "Reproducing / measuring" section discloses this explicitly and distinguishes code-level/schema-level deductions (verified) from measured results (not captured). Where a real, safe fix was identified independent of needing live numbers (the two missing indexes, the try/catch guard), it was implemented and verified via tsc --noEmit/eslint.

Test plan

  • npm run typecheck --workspace=apps/api — clean
  • npm run lint --workspace=apps/api — clean (eslint --max-warnings 0)
  • Migration file (0006_importers_and_events_perf_indexes.ts) reviewed for correctness against the existing migration runner's transaction-per-migration model (non-concurrent CREATE INDEX, since CONCURRENTLY can't run inside a transaction block)

Found idx_importers_created_at was never actually applied to any real
database (vjuliaife#257's closing PR added it only to a legacy, unexecuted
.sql migration file — grepped every real migration and db.ts for
zero hits). Adds it via a proper migration
(0006_importers_and_events_perf_indexes.ts), turning the surety_admin
listing query from Seq Scan + Sort into an Index Scan.

Cursor-based pagination is recommended but not implemented: the only
current caller renders the full list with no pagination UI, and a
correct keyset cursor needs a compound (created_at, id) key (id alone
is a random UUID with no relation to insertion order) — implementing
it speculatively ahead of a consuming UI change is out of scope for
this investigation.

No live Postgres was available to capture EXPLAIN ANALYZE at
1x/5x/10x volume; the Seq Scan -> Index Scan conclusion is a
schema-level deduction (no matching index existed; one now does), not
a measured result. See docs/investigations/importers-list-pagination-at-scale.md.

Closes vjuliaife#1090
Structural analysis (not live-benchmarked — no Postgres instance
available) of every read/write call site against oracle_price_feed:
it's insert-only with no UPDATE anywhere, uses a random UUID PK
(avoiding the rightmost-page contention pattern a SERIAL PK would
have), and dedups via an ON CONFLICT DO NOTHING unique index (an
index-level operation, not a table lock). Postgres MVCC means
concurrent SELECTs are never blocked by concurrent INSERTs at any
frequency. No index or schema change is warranted.

See docs/investigations/oracle-price-feed-write-contention.md.

Closes vjuliaife#1092
…eeds

The materialized view's REFRESH CONCURRENTLY (confirmed in use,
db.ts:953-959, so concurrent readers are never blocked) still has to
recompute the full aggregate across ALL importers/bonds/events on
every refresh, and refreshImporterMetricsView() is awaited
synchronously on every single tariff-CSV upload. Before this fix, a
slow/failed refresh (lock wait, pool exhaustion) would throw past the
point where the on-chain collateral update and tariff_uploads row had
already succeeded, turning a successful upload into a client-visible
500. Wrapped in its own try/catch, matching the adjacent
evaluateTariffAlerts pattern.

No live Postgres was available to benchmark actual refresh duration
at simulated 10x volume; the refresh-cost-scales-with-total-volume
conclusion follows from the view's own LEFT JOIN/aggregate
definition. See docs/investigations/importer-metrics-mv-refresh-cost.md.

Closes vjuliaife#1091
Two findings more fundamental than the scan-performance question this
issue asks: (1) idx_contract_events_raw_gin was never actually applied
to any real database, same unexecuted-legacy-migration situation as
vjuliaife#1090's idx_importers_created_at; (2) contract_events.raw is
functionally dead code — every INSERT omits it (checked all 4 call
sites) and no SELECT anywhere reads or filters on it (checked every
route file). Recommendation: do NOT add the GIN index — it would add
write overhead to the busiest, already-partitioned table in the
schema for zero query benefit, since nothing queries the column it
would index.

See docs/investigations/contract-events-gin-index-at-scale.md.

Closes vjuliaife#1093
@drips-wave

drips-wave Bot commented Aug 28, 2026

Copy link
Copy Markdown

@pre-cious-Igwealor Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@vercel

vercel Bot commented Aug 28, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
tariff-shield-web Error Error Aug 28, 2026 10:37am

@vjuliaife
vjuliaife merged commit f5ca470 into vjuliaife:main Aug 28, 2026
8 of 26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment