Skip to content

perf: reduce board payload with compact card summaries - #572

Open
bionicman wants to merge 1 commit into
kanbn:mainfrom
habralab:perf/compact-board-query
Open

perf: reduce board payload with compact card summaries#572
bionicman wants to merge 1 commit into
kanbn:mainfrom
habralab:perf/compact-board-query

Conversation

@bionicman

Copy link
Copy Markdown
Contributor

Title

perf: reduce board payload with compact card summaries

Description

The authenticated board view only renders a small set of card indicators, but
board.byId currently loads and serializes full descriptions, comments,
attachments, checklists, and checklist items for every card. This becomes
expensive on large imported boards even after the relation lookups themselves
are indexed.

This adds an opt-in cardView: "summary" read model and uses it for the board
UI. Each card receives only the aggregate values needed for its description,
comment, attachment, and checklist indicators. The existing "full" mode
remains the default, preserving the response contract for existing API
consumers and the public board view.

The change also removes redundant board requests from the new-card and
duplicate-card flows. A proposed 30-second board query staleTime was removed
after E2E testing showed that it could hide labels created from the card view.

The issue was reproduced on imported self-hosted data containing 38 boards and
14,524 cards. Representative active boards contained 1,203, 1,587, 1,890, and
2,511 cards.

For two large boards, the compressed board.byId response dropped from
approximately 510–954 KB to 98–216 KB. End-to-end requests through the reverse
proxy dropped from roughly 2.15–3.24 seconds to 1.29–1.60 seconds.

EXPLAIN (ANALYZE, BUFFERS) on the 1,890-card board confirmed index scans for
card attachments, comments, checklists, and checklist items. Consolidating the
two checklist counters into one aggregate reduced the representative summary
query from 75.6 to 67.4 ms and from 19,872 to 15,521 shared buffer hits.

Type of change

  • Bug fix
  • Feature (requires an approved issue — see below)
  • Refactor / chore
  • Documentation

Checklist

  • I have linked the related issue below
  • My code follows the existing style and conventions
  • I have tested my changes locally
  • I have included screenshots for any UI changes

Testing

  • git diff --check upstream/main...HEAD
  • pnpm --filter @kan/api typecheck
  • pnpm --filter @kan/db typecheck
  • pnpm --filter @kan/e2e typecheck
  • pnpm --filter @kan/web test — 8 tests passed
  • pnpm --filter @kan/api test -- board-summary.integration.test.ts
  • production build completed successfully
  • focused self-hosted Playwright coverage passed for compact card details,
    board filters, card move/delete, and card duplication
  • PostgreSQL execution plans verified on a 1,890-card board

No screenshots are included because the change does not intentionally alter
the rendered UI.

Linked issue

Not applicable: this is a board loading performance bug fix and does not change
product behavior.

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