Skip to content

perf: de-bloat apalis.jobs so the board queries are fast (supersedes #1162)#1163

Merged
frol merged 1 commit into
NEAR-DevHub:mainfrom
frol-ai:perf-apalis-jobs-bloat
Jul 21, 2026
Merged

perf: de-bloat apalis.jobs so the board queries are fast (supersedes #1162)#1163
frol merged 1 commit into
NEAR-DevHub:mainfrom
frol-ai:perf-apalis-jobs-bloat

Conversation

@frol-ai

@frol-ai frol-ai commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Follow-up to your point on #1162 — instead of hiding the slow-statement warning by raising the threshold, actually make the board queries fast.

Root cause: table bloat, not row count

Measured on testenv: TOTAL_JOBS70k live rows, but DB_SIZE371 MB — ~5 KB/row, i.e. the table is almost all dead tuples. The queues churn ~1M rows/day (insert → Running → Done → pruned), and Postgres's default autovacuum only kicks in at 20% dead (autovacuum_vacuum_scale_factor = 0.2), which can't keep up. So the board's full-table aggregates (SUM(CASE WHEN status …), COUNT(*)) scan hundreds of MB of mostly-dead pages → ~1.5s.

Fix (attack the bloat)

  • Aggressive autovacuum on apalis.jobs (tune_apalis_autovacuum, run in setup_apalis): vacuum_scale_factor = 0.05, autovacuum_vacuum_insert_scale_factor = 0.05 (the table is insert-heavy, so insert-triggered vacuums keep the visibility map fresh), lower thresholds, small cost delay. Keeps dead tuples low (compact heap) and the VM fresh (so the aggregates can use index-only scans over the narrow indexes already added, bypassing the heap entirely).
  • VACUUM (ANALYZE) apalis.jobs at the end of the hourly apalis_prune: reclaims the space the deletes leave + refreshes VM/stats. Plain VACUUM (not FULL) takes only a SHARE UPDATE EXCLUSIVE lock, so workers keep polling.

Relationship to the other PRs

Testing

cargo fmt --check, cargo clippy --lib -- -D warnings, cargo check: clean. Validated the ALTER TABLE … SET (autovacuum_*) and VACUUM (ANALYZE) statements against Postgres.

🤖 Generated with Claude Code

https://claude.ai/code/session_01FRWEKUFYCcmGGhwdDYd471

…just quiet)

The board's slow queries (`/api/v1/overview`, `/api/v1/queues` ~1.5s) aren't slow
because of row count — testenv had only ~70k live rows — but because the table
is **bloated**: ~370 MB of dead tuples behind that live set, so the full-table
aggregates scan hundreds of MB. The queues churn ~1M rows/day and Postgres's
default autovacuum (`scale_factor` 0.2) is far too lax to keep up.

Fix the bloat at the source instead of hiding the warning:
- `tune_apalis_autovacuum` (in `setup_apalis`): make autovacuum aggressive on
  `apalis.jobs` — `vacuum_scale_factor` 0.05, `insert_scale_factor` 0.05 (this
  table is insert-heavy), lower thresholds, small cost delay — so dead tuples
  are reclaimed promptly (heap stays compact) and the visibility map stays fresh
  (the aggregates can use index-only scans over the narrow indexes added
  earlier, bypassing the heap).
- `VACUUM (ANALYZE) apalis.jobs` at the end of `apalis_prune` (hourly): reclaim
  the space the deletes leave and refresh the VM + stats. Plain VACUUM takes
  only a SHARE UPDATE EXCLUSIVE lock, so workers keep polling.

This supersedes the slow-statement threshold bump (NEAR-DevHub#1162) for these queries —
it makes them genuinely fast rather than silencing the warning. One-time
`VACUUM FULL apalis.jobs` (ops, brief lock) reclaims the existing ~370 MB now;
going forward the settings above keep it from re-bloating.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FRWEKUFYCcmGGhwdDYd471
@frol
frol merged commit 869a24f into NEAR-DevHub:main Jul 21, 2026
2 checks passed
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.

2 participants