Skip to content

Reduce recurring query spills and database work - #73

Merged
abhi1693 merged 2 commits into
masterfrom
fix/recurring-database-queries
Oct 4, 2026
Merged

abhi1693 merged 2 commits into
masterfrom
fix/recurring-database-queries

Conversation

@abhi1693

@abhi1693 abhi1693 commented Oct 4, 2026 •

Copy link
Copy Markdown
Owner

What changes and why?

Recurring tag reconciliation hashes hundreds of thousands of assignments, while admin publication reporting sorts full review automation JSON. The production audit measured tag counting at 577 ms and publication reporting at 1.98 seconds, with substantial temporary writes.

Count distinct visible tag UUIDs before the final count. For publication reporting, project each eligible review to its article UUID and automatic/manual booleans before grouping; an OFFSET 0 boundary prevents PostgreSQL from pulling the full JSON back into the sort. Exact publication, review and approved-origin visibility checks, manual-intervention rules, publication-time cutoffs and median calculations are preserved. Both paths reuse existing indexes.

Add semantic regressions and a production-scale plan comparison, plus profiling guidance and a user-facing changelog entry.

Validation

Updated against master after #69, #71 and #72. The changelog conflict retains every fix. Current commit: 8b83f32ac4efbb4607ec40d0484910384e571e7d.

  • After the branch update, 46 PostgreSQL 18/Redis regressions passed, including exact result semantics and the production-scale query-plan comparison. Two unit cases were excluded from that integration-only command. Markdown formatting, whitespace checks and commit hooks passed.

  • Current-head CI, attempt 2: 2,620 backend unit tests, 1,132 integration tests, 785 web tests and 647 admin tests passed, with no skips. Populated migration upgrades, web/Chrome/Edge browser parity, admin and authenticated API journeys, all ARM64 image builds/scans/smoke checks and all three CodeQL analyses passed. CI required and both Sonar checks passed.

  • Sonar MCP confirms the quality gate is OK, with 100% new-code coverage, 0% new duplication, and zero new bugs, vulnerabilities or code smells.

  • The first performance attempt reported latest-feed p95 99 → 120 ms and topic-feed 61 → 90 ms, with zero request failures. Neither route imports or calls the changed reconciliation/reporting queries; the measured public API files are identical to the base. A full repeat on the same commit passed with zero failures and eight inconclusive route comparisons. Runner variation prevents a latency claim from that comparison; no code or regression threshold was changed to obtain the repeat result.

  • Earlier targeted PostgreSQL 17 checks also passed all 12 new regressions and 62 surrounding integration cases. Full frontend/browser and integration validation of the updated commit is supplied by hosted CI rather than a complete local rerun.

  • GitHub's separate managed AI findings scan remains unavailable because the monthly quota is exhausted (HTTP 402). Standard CodeQL completed successfully; no paid service was enabled.

  • The fixture contains 60,340 articles, 34,074 tags, 603,400 tag assignments and 153,680 reviews. It is entirely synthetic and runs only against explicitly configured disposable databases and Redis database 15.

  • Driver-ready application SQL is compared with the previous production queries at work_mem=4MB. Results match exactly. Regression budgets require zero tag-count temporary writes and reporting spills below 8 MiB and below 15% of the previous broad-window spills. Timing is diagnostic, not a CI threshold.

Paired local PostgreSQL 17 medians (three repetitions per query, same data and connection):

Query Before → after (ms) Before → after temporary writes (MiB/call)
Tag count 164.9 → 113.5 15.00 → 0.00
Publication report, 1 day 35.1 → 34.6 0.00 → 0.00
Publication report, 7 days 66.7 → 65.0 0.00 → 0.00
Publication report, 30 days 345.1 → 198.3 52.64 → 2.23
Publication report, 90 days 429.9 → 333.2 52.64 → 2.23

The tag count is about 31% faster; the default 30-day report is about 43% faster. Reporting temporary writes fall about 96%. PostgreSQL 18 also passes the plan budgets, with zero reporting spills on this fixture. Small reporting windows remain similar in latency.

Read-only production correlation (PostgreSQL 17.10, ARM64, work_mem=4MB):

  • Prometheus reported approximately 26.3 GB of DevFeed database temporary writes over 24 hours (sum(increase(cnpg_pg_stat_database_temp_bytes{datname="devfeed"}[24h]))). This is a database-wide total, not attribution to these two queries.
  • A fresh 2026-10-03 23:32:08–23:47:11 UTC pg_stat_statements window recorded 14 existing tag-count calls averaging 374.0 ms, writing 225.5 MB of temporary data. No existing publication-report calls occurred in that window; its 1.98-second finding comes from the earlier audit interval.
  • Bounded production EXPLAIN (ANALYZE, BUFFERS) diagnostics showed tag deduplication with zero temporary writes, and the proposed 30-day publication query with 2.23 MiB, versus 50.83 MiB for the previous query. These diagnostic executions do not change the deployed application.

Post-deployment latency and daily temporary-write reductions still need measurement.

Rollout notes

  • Independent branch based on master; scoped to these two query paths, their regression coverage and documentation.
  • No migration, index change, configuration change or data backfill is required. Existing response contracts and exact counts are retained.
  • Production was inspected read-only; no application deployment or production tuning was performed.
  • After deployment, compare execution-time and temporary-block deltas per call for the new queries, then compare the database-wide 24-hour temporary-write total under comparable traffic. Other workloads also contribute to the daily total.

Ready for review

  • The description explains the change and the validation results, including gaps.
  • Relevant documentation and regression tests are updated.

@github-actions

github-actions Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

PR reader API performance

Result: INCONCLUSIVE

8 inconclusive. Zero request failures across all six runs.

Base 94ca922d94e6237ea011efbf781c8dba94a67fff → PR 8b83f32ac4efbb4607ec40d0484910384e571e7d

Three independent runs per revision, each on a fresh GitHub-hosted ARM64 runner. 16 users, 60 seconds/run, 1,000 synthetic articles, cache off, five PgBouncer slots.

Latency comparison

All latency values are in milliseconds; lower is better. Values are medians of three runs.

Route Base p95 PR p95 Change Result
All requests 88 94 +6 (+6.8%) Inconclusive
Latest feed 120 120 +0 (+0.0%) Inconclusive
Feed pagination 78 85 +7 (+9.0%) Inconclusive
Article detail 67 67 +0 (+0.0%) Inconclusive
Source feed 79 84 +5 (+6.3%) Inconclusive
Topic feed 60 90 +30 (+50.0%) Inconclusive
Feed filters 56 75 +19 (+33.9%) Inconclusive
Sources 35 29 -6 (-17.1%) Inconclusive
Topics 35 38 +3 (+8.6%) Inconclusive
Additional latency and throughput metrics

Each cell shows base → PR. Latencies are in milliseconds.

Endpoint p50 p99 Requests/s
Aggregated 26 → 25 140 → 140 30.16 → 30.49
/v1/feed [latest] 41 → 40 170 → 150 8.61 → 8.43
/v1/feed [page] 25 → 24 97 → 140 3.96 → 3.73
/v1/articles/[id] 17 → 16 93 → 110 6.00 → 6.28
/v1/feed [source] 26 → 26 150 → 120 2.06 → 2.02
/v1/feed [topic] 25 → 24 100 → 120 1.89 → 1.89
/v1/feed/options 20 → 20 83 → 120 2.59 → 2.53
/v1/sources 12 → 10 68 → 64 2.59 → 2.53
/v1/topics 13 → 11 50 → 53 2.59 → 2.53
Individual runs
Run Requests Failures Exit code
Base 1 1784 0 0
Base 2 1661 0 0
Base 3 1699 0 0
PR 1 1660 0 0
PR 2 1710 0 0
PR 3 1710 0 0
How to interpret this report

Regressed / Improved: a p95 regression needs >20% and >20 ms increase in the medians and at least two head samples versus the base median. Improvements use the inverse threshold. Within threshold means the change did not meet both thresholds.

Inconclusive: a within-revision p95 range >35% of its median and >20 ms is too noisy for a confident latency verdict.

Inconclusive latency comparisons are non-blocking: the check passes without claiming an improvement. Confirmed regressions and test/report errors fail the PR gate. Throughput is descriptive: paced users do not measure maximum capacity. This uncached public API test does not establish production health, browser performance or worker capacity. Separate runners can differ in hardware or host load; repetitions and noise checks reduce but cannot eliminate that uncertainty.

Full HTML/CSV reports and logs · attempt 2

@gitar-bot

gitar-bot Bot commented Oct 4, 2026 •

Copy link
Copy Markdown
Code Review ✅ Approved

🟡 Medium risk · Two recurring database queries change execution plans while preserving reported counts.

Reduces tag reconciliation query time by ~31% and 30-day publication reporting by ~43% through early deduplication and projection-before-grouping to minimize temporary writes. Comprehensive regression tests, performance validation across PostgreSQL 17–18, and production diagnostics confirm exact result preservation with zero tag-count spills and ~96% reduction in reporting temporary writes. No issues found.

Review coverage

📋 Rules No rules evaluated

🧪 Functional validation Not enabled · Set up

Options

Auto-apply is off → Gitar will not commit updates to this branch.
Display: compact → Counting what did not apply, without listing it.

Comment with these commands to change the behavior for this request:

Auto-apply Compact
gitar auto-apply:on         
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

@sonarqubecloud

sonarqubecloud Bot commented Oct 4, 2026

Copy link
Copy Markdown

@abhi1693
abhi1693 merged commit df25ae0 into master Oct 4, 2026
109 of 111 checks passed
@abhi1693
abhi1693 deleted the fix/recurring-database-queries branch October 4, 2026 11:44
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