Custom patches for the Nextcloud Mail app to support 10,000+ account deployments.
Target: Nextcloud 30, Mail app 5.x (based on upstream v5.7.0-rc.1)
| # | Patch | Impact | Files |
|---|---|---|---|
| 1 | INSERT IGNORE deduplication | Eliminates PHP memory exhaustion during sync | MessageMapper.php |
| 2 | Deep-sync as QueuedJob | Prevents 80-190 min cron blockage | DeepSyncJob.php (new), SyncJob.php |
| 3 | Async on-demand sync | Non-blocking scroll for older messages | OnDemandSyncJob.php (new), MailSearch.php |
| 4 | PreviewEnhancer pre-fetch | First page load: 30s → 12ms | ImapToDbSynchronizer.php |
| 5 | IMAP connection guard | Prevents Exchange Online account lockouts | IMAPClientFactory.php, HordeImapClient.php |
| 6 | Search result backfill | Complete search results with sync window | BackfillSearchResultsJob.php (new), MailSearch.php |
| 7 | UNIQUE constraint migration | Enables INSERT IGNORE, prevents duplicates | Version5200Date20260309000000.php (new) |
| 8 | Sync window (max_sync_days) | DB reduction: 1B → 30-50M rows | AdminSettings.php, SettingsController.php, AdminSettings.vue, ImapToDbSynchronizer.php, SyncWindowCleanupJob.php (new) |
| 9 | OR-search fix | Fixes broken multi-term search | Provider.php |
Copy patched files over the upstream Mail app installation:
# On the Nextcloud server
MAIL_DIR=/var/www/nextcloud/apps/mail
# New files (background jobs + migration)
cp lib/BackgroundJob/DeepSyncJob.php $MAIL_DIR/lib/BackgroundJob/
cp lib/BackgroundJob/OnDemandSyncJob.php $MAIL_DIR/lib/BackgroundJob/
cp lib/BackgroundJob/BackfillSearchResultsJob.php $MAIL_DIR/lib/BackgroundJob/
cp lib/BackgroundJob/SyncWindowCleanupJob.php $MAIL_DIR/lib/BackgroundJob/
cp lib/Migration/Version5200Date20260309000000.php $MAIL_DIR/lib/Migration/
# Modified files
cp lib/Db/MessageMapper.php $MAIL_DIR/lib/Db/
cp lib/BackgroundJob/SyncJob.php $MAIL_DIR/lib/BackgroundJob/
cp lib/Service/Sync/ImapToDbSynchronizer.php $MAIL_DIR/lib/Service/Sync/
cp lib/Service/Search/MailSearch.php $MAIL_DIR/lib/Service/Search/
cp lib/IMAP/IMAPClientFactory.php $MAIL_DIR/lib/IMAP/
cp lib/IMAP/HordeImapClient.php $MAIL_DIR/lib/IMAP/
cp lib/IMAP/Search/Provider.php $MAIL_DIR/lib/IMAP/Search/
cp lib/Settings/AdminSettings.php $MAIL_DIR/lib/Settings/
cp lib/Controller/SettingsController.php $MAIL_DIR/lib/Controller/
cp src/components/settings/AdminSettings.vue $MAIL_DIR/src/components/settings/
cp appinfo/info.xml $MAIL_DIR/appinfo/
# Run migration for UNIQUE constraint
sudo -u www-data php /var/www/nextcloud/occ maintenance:mode --on
sudo -u www-data php /var/www/nextcloud/occ migrations:migrate mail
sudo -u www-data php /var/www/nextcloud/occ maintenance:mode --off# Set 90-day sync window (recommended for 10K+ accounts)
sudo -u www-data php /var/www/nextcloud/occ config:app:set mail max_sync_days --value=90
# Or via Admin Settings → Mail → Synchronization window# Check migration status
sudo -u www-data php /var/www/nextcloud/occ migrations:status mail
# Check config
sudo -u www-data php /var/www/nextcloud/occ config:app:get mail max_sync_days
# Test search
# Search for a term in Nextcloud Mail UI — should return results# Restore original files from upstream Mail app package
# Or reinstall: sudo -u www-data php occ app:update mail
# Remove sync window setting
sudo -u www-data php occ config:app:delete mail max_sync_days
# Remove registered background jobs
mysql -u ncuser -p nextcloud -e "
DELETE FROM oc_jobs WHERE class LIKE '%DeepSyncJob%';
DELETE FROM oc_jobs WHERE class LIKE '%OnDemandSyncJob%';
DELETE FROM oc_jobs WHERE class LIKE '%BackfillSearchResultsJob%';
DELETE FROM oc_jobs WHERE class LIKE '%SyncWindowCleanupJob%';
"- doc/developer.md — Technical deep-dive per patch
- doc/production-impact.md — Ops impact analysis
- doc/enterprise-portal-ticket.md — Nextcloud Enterprise Portal ticket
- doc/upstream-feature-request-max-sync-days.md — GitHub feature request
| Patch | Upstream strategy |
|---|---|
| #9 OR-search fix | Submit as bugfix PR |
| #7+#1 UNIQUE + INSERT IGNORE | Submit as optimization PR |
| #4 PreviewEnhancer | Submit as performance PR |
| #8 max_sync_days | Feature request via Enterprise Portal |
| #2,#3,#5,#6 | Depends on upstream interest |
Same as Nextcloud Mail: AGPL-3.0-or-later