Repository navigation
fix: cancellation large sweep - #140
Conversation
|
We hit the same problem and ended up with nearly the same fix, so here is some extra data, plus one suggestion about the index predicate. Production impact: on a queue of ~140k tasks, this query was ~70% of our database's total query time. Reproduction (PostgreSQL 16, absurd 0.5.0 schema, 200k tasks: 50 pending, the rest completed, none with a cancellation policy): select absurd.create_queue('demo');
insert into absurd.t_demo (task_id, task_name, params, state, attempts, enqueue_at, first_started_at)
select gen_random_uuid(), 'demo-task', jsonb_build_object('payload', repeat('x', 800)),
case when g <= 50 then 'pending' else 'completed' end, 1,
now() - interval '1 hour', now() - interval '1 hour'
from generate_series(1, 200000) g;
vacuum analyze absurd.t_demo;
-- then EXPLAIN (ANALYZE, BUFFERS) the cancellation sweep, with now() in place of $1With a partial index on PlansBefore: After: Partitioned queues behave the same way: every partition is scanned (25k buffers, 40 ms for 200k tasks across weekly partitions). The same index on the parent brings it to 6 buffers and 0.27 ms, and partitions created later inherit it. Suggestion: drop create index if not exists ... on absurd.t_<queue> (task_id)
where cancellation is not null;Postgres can't make an update HOT if it changes any column an index uses, and columns in a partial index's The Analysis drafted with AI assistance; benchmarks run by me. |
|
@jboga added your suggestion. TIL, thanks! 😁 |
|
Thanks @cristinaponcela for the PR, and thanks Absurd team for the new release. |
See issue in super secret repo.
We have a worker health issue where we keep getting errors in Sentry (never wanted to stop getting an email more in my life!) bc
absurd.claim_task()does a cancellation sweep on every claim.Current
absurd.t_default:Breakdown:
So in current prod, 100% of rows have cancellation IS NULL.
That means changing the sweep to:
plus adding the partial index:
would make the cancellation sweep query an empty/tiny index instead of scanning ~1.55M rows.
This PR adds that :)