nextcloud / nextcloud/server

[Bug]: Nextcloud 33 cron.php uses a lot of CPU / postgres activity

Open
#59,036 54 comments 46 reactions 1 assignee View on GitHub

@CarlSchwan is already working on this.

Since Apr 9, 2026.

0. Needs triage 33-feedback bug
Dominant language
PHP
Stars
36.9k
Forks
5.2k
Avg merge
2d 3h
Merged PRs (30d)
713

Description

[!NOTE]

How to help with this issue
  • Use the 👍 reaction to show you are affected by this as well
  • Avoid commenting unless you have relevant information to add; unnecessary comments create noise for subscribers.
  • Subscribe to receive notifications about status changes and new comments.

Original report by @z3ntu

Since upgrading Nextcloud to 33.0.0 (from 32.0.5), once per day the cron.php process maxes out the CPU (granted, it's a slow 1 CPU core DigitalOcean server) for about an hour before returning to normal. I can't find anything in the logs that would suggest what cron is actually doing or why it's taking up so much resources.

Image
⚠️ This issue respects the following points: ⚠️
Bug description

Since upgrading Nextcloud to 33.0.0 (from 32.0.5), once per day the cron.php process maxes out the CPU (granted, it's a slow 1 CPU core DigitalOcean server) for about an hour before returning to normal. I can't find anything in the logs that would suggest what cron is actually doing or why it's taking up so much resources.

Image
Steps to reproduce
  1. Run cron.php on a Nextcloud 33 installation on a 1-core VM?
Expected behavior

cron.php shouldn't cause so much CPU usage

Nextcloud Server version

33

Operating system

Other

PHP engine version

PHP 8.3

Web server

Apache (supported)

Database engine version

PostgreSQL

Is this bug present after an update or on a fresh install?

Upgraded to a MAJOR version (ex. 31 to 32)

Are you using the Nextcloud Server Encryption module?

Encryption is Disabled

What user-backends are you using?
  • Default user-backend (database)
  • LDAP/ Active Directory
  • SSO - SAML
  • Other
Configuration report
{
    "system": {
        "instanceid": "***REMOVED SENSITIVE VALUE***",
        "passwordsalt": "***REMOVED SENSITIVE VALUE***",
        "secret": "***REMOVED SENSITIVE VALUE***",
        "trusted_domains": [
            "cloud.lucaweiss.eu"
        ],
        "datadirectory": "***REMOVED SENSITIVE VALUE***",
        "dbtype": "pgsql",
        "version": "33.0.0.16",
        "logtimezone": "UTC",
        "installed": true,
        "theme": "",
        "loglevel": 2,
        "logfile": "\/var\/log\/nextcloud\/nextcloud.log",
        "default_phone_region": "AT",
        "maintenance": false,
        "htaccess.RewriteBase": "\/",
        "overwrite.cli.url": "https:\/\/cloud.lucaweiss.eu",
        "mail_smtpmode": "smtp",
        "mail_smtpauthtype": "PLAIN",
        "mail_from_address": "***REMOVED SENSITIVE VALUE***",
        "mail_domain": "***REMOVED SENSITIVE VALUE***",
        "mail_smtpauth": 1,
        "mail_smtpname": "***REMOVED SENSITIVE VALUE***",
        "mail_smtppassword": "***REMOVED SENSITIVE VALUE***",
        "mail_smtphost": "***REMOVED SENSITIVE VALUE***",
        "mail_smtpport": "587",
        "dbname": "***REMOVED SENSITIVE VALUE***",
        "dbhost": "***REMOVED SENSITIVE VALUE***",
        "dbuser": "***REMOVED SENSITIVE VALUE***",
        "dbpassword": "***REMOVED SENSITIVE VALUE***",
        "apps_paths": [
            {
                "path": "\/usr\/share\/webapps\/nextcloud\/apps",
                "url": "\/apps",
                "writable": false
            },
            {
                "path": "\/var\/lib\/nextcloud\/apps",
                "url": "\/wapps",
                "writable": true
            }
        ],
        "app_install_overwrite": [
            "bruteforcesettings",
            "news"
        ],
        "mail_sendmailmode": "smtp",
        "updater.release.channel": "stable"
    }
}
List of activated Apps
Enabled:
  - bookmarks: 16.1.3
  - bruteforcesettings: 6.0.0-dev.0
  - calendar: 6.2.1
  - cloud_federation_api: 1.17.0
  - comments: 1.23.0
  - contacts: 8.4.0
  - contactsinteraction: 1.14.1
  - cookbook: 0.11.6
  - dav: 1.36.0
  - dav_push: 1.0.1
  - federatedfilesharing: 1.23.0
  - federation: 1.23.0
  - files: 2.5.0
  - files_downloadlimit: 5.1.0-dev.0
  - files_pdfviewer: 6.0.0-dev.0
  - files_reminders: 1.6.0
  - files_sharing: 1.25.2
  - files_trashbin: 1.23.0
  - files_versions: 1.26.0
  - firstrunwizard: 6.0.0-dev.0
  - logreader: 6.0.0
  - lookup_server_connector: 1.21.0
  - news: 27.2.0
  - nextcloud_announcements: 5.0.0
  - notes: 4.13.0
  - notifications: 6.0.0
  - oauth2: 1.21.0
  - privacy: 5.0.0-dev.0
  - profile: 1.2.0
  - provisioning_api: 1.23.0
  - related_resources: 4.0.0-dev.0
  - serverinfo: 5.0.0-dev.0
  - settings: 1.16.0
  - survey_client: 5.0.0-dev.0
  - text: 7.0.0-dev.3
  - theming: 2.8.0
  - twofactor_backupcodes: 1.22.0
  - twofactor_totp: 15.0.0-dev.0
  - twofactor_webauthn: 2.6.0
  - updatenotification: 1.23.0
  - user_status: 1.13.0
  - viewer: 6.0.0-dev.0
  - webhook_listeners: 1.5.0
  - workflowengine: 2.15.0
Disabled:
  - activity: 6.0.0-dev.0 (installed 2.13.1)
  - admin_audit: 1.23.0
  - app_api: 33.0.0 (installed 32.0.0)
  - circles: 33.0.0 (installed 22.1.0)
  - dashboard: 7.13.0 (installed 7.0.0)
  - encryption: 2.21.0
  - files_external: 1.25.1 (installed 1.23.0)
  - password_policy: 5.0.0-dev.0 (installed 1.12.0)
  - photos: 6.0.0-dev.0 (installed 1.2.0)
  - recommendations: 6.0.0-dev.0 (installed 0.8.0)
  - sharebymail: 1.23.0 (installed 1.11.0)
  - support: 5.0.0 (installed 1.2.1)
  - suspicious_login: 11.0.0-dev.0
  - systemtags: 1.23.0 (installed 1.9.0)
  - twofactor_nextcloud_notification: 7.0.0
  - user_ldap: 1.24.0
  - weather_status: 1.13.0 (installed 1.0.0)
Nextcloud Signing status
Technical information
=====================
The following list covers which files have failed the integrity check. Please read
the previous linked documentation to learn more about the errors and how to fix
them.

Results
=======
- core
	- INVALID_HASH
		- .htaccess

Raw output
==========
Array
(
    [core] => Array
        (
            [INVALID_HASH] => Array
                (
                    [.htaccess] => Array
                        (
                            [expected] => 418f0babf39f82e537d12028229189633a7941160c27c3410032af498008a65637b8d1ee64abc63a6321c3d1ef8cde31fe58cee00d8b32821480501111977c34
                            [current] => 11fa1c20bce060406cf3f1dadc2f352fc3366fc1e8f4869c63f14312b14f35637e7823072295f810355527cce160b90463de9108ee9167d439b72a140a858b18
                        )

                )

        )

)
Nextcloud Logs

Additional info

No response


More details by @UltimateByte

Steps to reproduce
  1. Have a Nextcloud instance with a large number of preview entries in oc_filecache (~462k in our case)
  2. Upgrade to Nextcloud 33.0.0
  3. The preview files on disk may have been cleaned up previously (e.g. via preview:cleanup or manual cleanup), but the corresponding oc_filecache entries remain
  4. Wait for the PreviewMigrationJob background job to trigger
Expected behavior

The PreviewMigrationJob should handle the case where oc_filecache entries exist but the actual preview files are missing on disk. It should either clean up the orphaned entries or skip them and move on.

Actual behavior

The job enters an infinite while(true) loop consuming ~55% CPU for exactly 1 hour (the hardcoded timeout), then restarts on the next cron cycle. Zero previews are ever migrated to the new oc_previews table.

Root cause in core/BackgroundJobs/PreviewMigrationJob.php:

  1. The while(true) loop SELECTs 100 paths from oc_filecache
  2. For each batch, migrateFileId() is called in PreviewMigrationService.php
  3. migrateFileId() calls $this->appData->getFolder($internalPath)
  4. Since the files don't exist on disk, this throws NotFoundException
  5. The catch block returns [] without deleting the orphaned oc_filecache entry
  6. The next iteration SELECTs the same 100 rows → infinite loop

The previewMovedDone flag is never set because the loop never breaks (there are always rows to SELECT).

Proposed fix

In PreviewMigrationService::migrateFileId(), when NotFoundException is caught, the orphaned oc_filecache entries for that preview folder should be cleaned up before returning:

} catch (NotFoundException) {
    // Clean up orphaned filecache entries for this preview folder
    $this->deleteFolder($internalPath);
    return [];
}

This way the while(true) loop in the job will eventually exhaust all entries and set the previewMovedDone flag.

Workaround
-- Remove orphaned preview entries from filecache
DELETE FROM oc_filecache WHERE path LIKE 'appdata_<instanceid>/preview/%';

Then either wait for the job to set the flag itself (it will find 0 rows and complete), or set it manually:

occ config:app:set core previewMovedDone --value=1 --type=boolean
Server configuration

Operating system: Debian 13 (trixie)

Web server: Apache 2.4.66

PHP version: 8.4.19

Nextcloud version: 33.0.0.16

Updated from: 32.x (major upgrade)

Database: MariaDB

Signing status:

No errors have been found.
System configuration
{
    "system": {
        "trusted_domains": [
            "localhost",
            "cloud.lrob.fr"
        ],
        "dbtype": "mysql",
        "version": "33.0.0.16",
        "mysql.utf8mb4": true,
        "memcache.local": "\\OC\\Memcache\\Redis",
        "memcache.distributed": "\\OC\\Memcache\\Redis",
        "filelocking.enabled": true,
        "memcache.locking": "\\OC\\Memcache\\Redis"
    }
}

Contributor guide

Open the contributing guide

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.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.