perf: add indexes for card relation queries - #566
Merged
Conversation
Add FK-first indexes for card comments, attachments, checklists, checklist items, and activities to avoid repeated sequential scans in board and card relational queries.
bionicman
marked this pull request as ready for review
August 31, 2026 23:12
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Board and card relation loading repeatedly filters child tables by their foreign key and, for ordered relations, sorts by the relation's ordering column. These tables did not have matching indexes, so PostgreSQL performed repeated sequential scans as the dataset grew.
This adds indexes for:
The schema declarations and generated Drizzle migration are included in the same change.
The issue was reproduced on a real Trello import containing 38 boards and 14,524 cards. The indexed relation tables contained 53,032 comments, 17,384 attachments, 2,221 checklists, 12,613 checklist items, and 67,556 activity rows. The measured board contained 3,236 stored cards across 45 lists; its normal API response included 709 active cards and was approximately 692 KB.
On that dataset, the database portion of the large board query dropped from about 2.9 seconds to 17–29 ms. End-to-end board loading dropped from about 13.1 seconds to 0.35–0.81 seconds. PostgreSQL also selected all five new indexes during normal application traffic after migration.
Type of change
Checklist
Testing
git diff --check upstream/main...HEADpnpm --filter @kan/db typecheckLinked issue
Not applicable: this is a database performance bug fix and does not change product behavior.