Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Background inbox sync re-sends and re-renders every loaded message every 30 s, freezing the tab with several accounts

Open
#13,809 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
56/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
javascript, php

Research direction

Start with lib/Service/Sync/SyncService.php around the findChanged TODO and src/store/mainStore/actions.js around updateEnvelopeMutation; also inspect src/App.vue where syncInboxes() runs. Check existing sync tests and run the relevant server and client tests. Done means unchanged messages are not repeatedly returned or trigger list re-renders, while real flag or tag changes still update correctly.

Written by the indexing model from the issue text.

Description

0. to triage
Steps to reproduce
  1. Add several IMAP accounts to one user (I have 7, all on the same Dovecot server).
  2. Open Mail in the browser and leave it open (worse on "All inboxes" or after scrolling back through a list).
  3. Watch the tab every 30 seconds while the background inbox sync runs.
Expected behavior

When nothing changed on the server, the periodic background sync should send back (almost) nothing, and the UI should not re-render the message list.

Actual behavior

Every 30 s the tab freezes for a moment (the browser's loading indicator shows) and becomes responsive again as soon as the sync finishes.

The server side is fast. I logged the requests at the reverse proxy: every 30 s there is one POST /apps/mail/api/mailboxes/{id}/sync per account inbox, all fired at once, each answered in 0.2–0.6 s. However, every response for a given inbox has the same size on every poll (1.6–4.7 KB gzipped), even when nothing changed.

The cause seems to be in the code:

  1. Server: every known message is always returned as "changed".
    lib/Service/Sync/SyncService.php L146–L150

    // TODO: $changed = $this->messageMapper->findChanged($account, $mailbox, $uids);
    ...
    $changedIds = $knownIds;
    

    So changedMessages contains every envelope the client already has loaded, on every sync.

  2. Client: each "changed" envelope gets new flags / tags objects, even when they are identical.
    src/store/mainStore/actions.js L955 and L2111

    updateEnvelopeMutation({ envelope }) {
        ...
        Vue.set(existing, 'flags', envelope.flags)
        Vue.set(existing, 'tags', envelope.tags)
    }
    

    Because these are always new objects, Vue sends change notifications for every loaded envelope and re-renders the list.

  3. This runs for every account inbox every 30 s (src/App.vue L98, syncInboxes()). So the work grows with (number of accounts × loaded envelopes), and with several accounts the main thread blocks noticeably on every poll.

Suggested fix
  • Server: implement the findChanged TODO (e.g. use the CONDSTORE/flag-change UIDs the IMAP sync already gets) so only messages that really changed are returned.
  • Client (cheap, independent): in updateEnvelopeMutation, skip the Vue.set calls when flags / tags are unchanged. Comparing them first (e.g. JSON.stringify(old) !== JSON.stringify(new), since tags are already normalized to ID arrays) avoids re-rendering envelopes that did not change.

Possibly related: #13692 (memory blow-up on initial load). This report is about the steady-state 30 s poll after the app has loaded.

Mail app version

5.12.3

Nextcloud version

35.0.0 (Nextcloud All-in-One)

Mailserver or service

Dovecot 2.3.21 (mailcow)

Operating system

Linux (Debian 13)

PHP engine version

PHP 8.x (AIO image)

Web server

Apache (AIO) behind Caddy

Database

PostgreSQL

Additional info

The freezes stop as soon as each sync round finishes. Fewer accounts makes them shorter.

Dominant language
JavaScript
Stars
1k
Forks
363
Avg merge
1d 18h
Merged PRs (30d)
81

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from nextcloud/mail

All issues in nextcloud/mail

Similar issues

More JavaScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.