perf(notes): reduce list response size and N+1 queries for faster Notes tab#21549
perf(notes): reduce list response size and N+1 queries for faster Notes tab#21549leandroyloli wants to merge 1 commit intoopen-webui:devfrom
Conversation
- Add get_grants_by_resources() for batch grant loading - Add _to_note_models_batch() and _strip_data_for_list() in notes model - List endpoints return only 200-char md preview; GET /notes/:id unchanged - Notes list: fetch full note via getNoteById before download (txt/md/pdf) - Reduces list payload from ~167MB to ~10KB for 60 notes, fixes slow Notes tab Co-authored-by: Cursor <cursoragent@cursor.com>
👋 Welcome and Thank You for Contributing!We appreciate you taking the time to submit a pull request to Open WebUI!
|
|
Testing Confirmation✅ I have personally tested ALL changes in this PR. How I testedThis fix originated from a real production scenario where the Notes tab was unusably slow with ~60 notes (many from meeting audio transcriptions), resulting in ~167 MB responses and ~27 second load times. Steps taken:
|
|
This PR is atomic — all changes serve a single unified purpose: make the Notes list endpoints lightweight for performance. The AI analysis incorrectly flagged the download handler change as a "secondary bug fix" and
All three pieces are required together for the optimization to work without regressions. Splitting them would either break functionality or leave the N+1 problem unsolved. |
|
Addressed in dev to apply to all workspace items, thanks! |
I am so happy! |
Pull Request Checklist
Note to first-time contributors: Please open a discussion post in Discussions to discuss your idea/fix with the community before creating a pull request, and describe your changes before submitting a pull request.
Before submitting, make sure you've checked the following:
devbranch. PRs targetingmainwill be immediately closed.devto ensure no unrelated commits (e.g. frommain) are included. Push updates to the existing PR branch instead of closing and reopening.Changelog Entry
Description
The Notes tab becomes very slow when users have many notes. The list/search endpoints (
get_notes,search_notes,get_notes_by_user_id) return the fulldatafield (markdown, HTML, JSON, files, versions) for every note. For ~60 notes per page this results in a ~167 MB response and ~27 second load time. Additionally, each note triggers a separate DB query for access grants (N+1 problem).This PR reduces list payload from ~167 MB to ~10 KB and eliminates the N+1 grant queries, making the Notes tab load in seconds instead of tens of seconds.
Added
get_grants_by_resources()inAccessGrantsTablefor batch grant loading (single query instead of N separate queries)_to_note_models_batch()inNoteTablefor batch note-to-model conversion using the batch grant loader_strip_data_for_list()inNoteTableto keep only a 200-character markdown preview in list/grid responsesChanged
get_notes(),search_notes(), andget_notes_by_user_id()now use batch conversion + data stripping for lightweight list responsesdownloadHandlerinNotes.sveltenow fetches the full note viagetNoteById()before generating TXT/MD/PDF files, since the list response no longer contains full contentDeprecated
Removed
Fixed
Security
Breaking Changes
GET /notes/:idstill returns fulldata; only list endpoints are affected, and the frontend download flow was updated to compensateAdditional Information
GET /notes/:idendpoint andupdate_note_by_idare not modified — they still return fulldatafor the note editorline-clamp-3)getNoteByIdalready existed insrc/lib/apis/notes/index.ts— only the import inNotes.sveltewas addedContributor License Agreement
By submitting this pull request, I confirm that I have read and fully agree to the Contributor License Agreement (CLA), and I am providing my contributions under its terms.
Note
Deleting the CLA section will lead to immediate closure of your PR and it will not be merged in.