perf(boards): batch the owner lookup in admin board listings - #9395
Merged
Conversation
`BoardService.get_many` / `get_all` ran one `users.get` per board to resolve the owner display name shown to admins — 50 boards meant 50 extra queries for what is usually a handful of distinct owners. Adds `UserService.get_many` (one `IN (...)` query, deduped and chunked under SQLite's bound-parameter limit) and folds the two duplicated DTO-building loops into a single `_to_dtos` helper that fetches media summaries and owner names once per page. Non-admin listings never show owner names, so they now skip the lookup entirely instead of relying on `is_admin` inside the loop. The other 4-queries-per-board half of this finding was already fixed in invoke-ai#9163 itself (`gallery.get_board_media_summaries` batches covers and counts into one windowed query); this is the residual. Deferred non-blocker from PR invoke-ai#9163. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
lstein
requested review from
JPPhoto,
Pfannkuchensack,
blessedcoolant and
dunkeroni
as code owners
July 28, 2026 01:49
lstein
enabled auto-merge (squash)
August 9, 2026 17:08
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.
Summary
Follow-on to #9163 (deferred non-merge-blocker).
The original finding was "board listing runs ~5 queries per board". Four of those five were already fixed inside #9163 —
gallery.get_board_media_summariesnow folds the cover-image, cover-video, image, asset and video-count queries into one windowed query for the whole page. This PR closes the residual: the per-board owner lookup.BoardService.get_many/get_allcalledusers.get(record.user_id)inside the DTO loop whenever the caller is an admin, so an admin listing 50 boards issued 50 extra single-row queries — for what is typically a handful of distinct owners.Changes
UserService.get_many(user_ids) -> dict[str, UserDTO]: oneIN (...)query, input deduped, chunked at 900 ids so a caller with many distinct owners can't exceed SQLite's bound-parameter limit (999 on builds predating 3.32). Unknown ids are simply absent from the result, so callers keep theNonehandling they already had.BoardService._to_dtos: the two identical DTO-building loops inget_many/get_allcollapse into one helper that fetches summaries and owner names once per page.is_adminper board.No API or schema change —
owner_usernameis populated exactly as before.Testing
test_admin_board_listing_batches_owner_lookup(20 boards / 3 distinct owners → oneget_many, zeroget),test_non_admin_board_listing_skips_owner_lookup, and threeUserService.get_manytests (dedup + unknown ids, empty input, chunking past the parameter limit).pytest tests/app/routers tests/app/services— 1212 passed, 3 skipped.🤖 Generated with Claude Code