Skip to content

bug: notification bell scans the whole table every second - #422

Merged
lukepolo merged 1 commit into
mainfrom
perf/notifications-inbox-index
Sep 19, 2026
Merged

lukepolo merged 1 commit into
mainfrom
perf/notifications-inbox-index

Conversation

@lukepolo

@lukepolo lukepolo commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

The bell subscription asks for "unread, or read but newer than X". Hasura sends both is_read values as query parameters, so the existing partial index on is_read = false can never be matched — the planner can't prove the predicate holds for a parameter inside an OR — and every evaluation falls back to a sequential scan.

Prod state before: 3,693,139 sequential scans reading 56,000,904,973 tuples from a 28,396-row table. The subscription is 5.5% of top-level DB CPU at 14,100 buffers per call to return ~15 rows.

Verified on a synthetic table of the same shape and distribution on PG 17.11, forcing a generic plan so the parameters behave as they do in the subscription:

plan buffers time
before Seq Scan, 28,394 rows filtered 465 1.153 ms
after Index Scan 5 0.124 ms

The index also covers the steam_id IS NULL branch, and is 56 kB. Migration is idempotent and tested up, down, and re-applied.

Keeps notifications_unread_steam_id_idx: the unread badge count constrains is_read as a literal and is better served by the narrower partial index.

Hasura sends is_read as a query parameter, so the partial index on
is_read = false cannot be matched and every evaluation falls back to a
sequential scan. The table had taken 3.7 million seq scans reading 56
billion tuples to return roughly 34 rows at a time.

Indexes the columns the query constrains with literals instead.
@lukepolo
lukepolo merged commit db36f56 into main Sep 19, 2026
2 checks passed
@lukepolo
lukepolo deleted the perf/notifications-inbox-index branch September 19, 2026 20:01
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