Repository navigation
fix(sync): send at most one page of new messages when the client knows none - #13823
Open
dillardblom wants to merge 1 commit into
Open
dillardblom wants to merge 1 commit into
dillardblom wants to merge 1 commit into
Conversation
…s none When the client syncs a list of which it shows no messages, it sends an empty list of known ids. The sync then treated every message of the mailbox as new and passed all of them through the preview enhancer in one request. This happens in the priority inbox: the client syncs each account's INBOX per section, and an account whose messages are all pushed off the combined page by other accounts sends no ids. With an INBOX of 33,000 messages, 33,000 of them not structure-analyzed yet, every sync request ran out of memory (1 GB) in the MIME parser, and the client retried on every sync round. Without known ids, return the first page (20, the page size of the frontend) in the requested sort order, like the first page the client would load. Also compare the sort order with IMailSearch::ORDER_OLDEST_FIRST: the controller passes 'ASC'/'DESC', so the comparison with 'oldest' never matched. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Dillard Blom <dillard.blom@ensembia.com>
dillardblom
requested review from
ChristophWurst,
GretaD and
kesselb
as code owners
October 8, 2026 13:35
This branch has not been deployed
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
POST /api/mailboxes/{id}/syncwith an emptyidslist treated every message of the mailbox as new.getDatabaseSyncChanges()calledfindAllIds(), applied the filter without a limit, and passed every result through thePreviewEnhancerin that single request.The client sends an empty list whenever it shows none of the messages of a list. In the priority inbox this happens all the time: the client syncs every account's INBOX once per section (
is:pi-important,is:pi-other), and an account whose messages are all pushed off the combined page by other accounts has no known ids.On an INBOX with 33,000 messages (33,000 of them never structure-analyzed), every one of these sync requests ran out of PHP memory (1 GB) in the MIME parser and charset converter. The client then retried it on every sync round, so the log filled with
Allowed memory size … exhaustederrors for as long as the priority inbox was open. The same mailbox syncs fine fromocc mail:account:sync(peak 79 MB), because that path does not run the database diff.Without known ids, the sync now returns at most one page (20, the frontend's
PAGE_SIZE) of new messages in the requested sort order, like the first page the client would load. Requests with known ids are unchanged.While here: the sort order was compared with
'oldest', butMailboxesController::sync()passesIMailSearch::ORDER_*('ASC'/'DESC'), so the comparison never matched. It now compares withIMailSearch::ORDER_OLDEST_FIRST. That matters for the limited query: with "oldest first", the page must be the oldest messages.Related to #13778: this removes one way a sync request can run out of memory. The locking and retry behaviour described there is unchanged.
Test plan
findIdsByQuerywith limit 20) and never callsfindAllIds/findNewIds. It fails without the change.tests/Unit/Service/Syncgreen, php-cs-fixer clean on the changed files.