Skip to content

Auto Upload high CPU usage #17895

Open

Description

@JanisPlayer

⚠️ Before posting ⚠️

  • This is a bug, not a question or an enhancement.
  • I've searched for similar issues and didn't find a duplicate.
  • I've written a clear and descriptive title for this issue, not just "Bug" or "Crash".
  • I agree to follow Nextcloud's Code of Conduct.

Steps to reproduce

Steps to reproduce
The issue is not deterministic, but occurs frequently:

Enable Auto Upload for the camera folder(s), configured to upload only while charging.

Connect the phone to a charger so Auto Upload starts.

After a variable amount of time, the phone suddenly becomes very hot.

CPU usage rises sharply. In addition to the Nextcloud app, system_server shows high CPU usage; sometimes, surfaceflinger, kswapd0, Samsung vendor/system processes, and com.google.android.ext.services are also affected.

Some uploads fail with a connection error to the Nextcloud server.

Despite the reported failure, the affected files are often uploaded successfully the following day.

Force-stopping the Nextcloud app stops the high CPU load. If the app has been running overnight, a reboot may be required.

The problem started around early April 2026.

Expected behaviour

Auto Upload should upload new files with moderate CPU, network and battery usage. Temporary connection errors should be retried in a controlled way, without causing sustained high CPU load, overheating, or excessive system_server activity.

Actual behaviour

While charging, Auto Upload can enter a state with very high CPU usage and severe device heating. system_server is heavily loaded as well. Uploads sometimes fail with connection errors, but are later uploaded successfully, suggesting either an aggressive retry loop or an upload-state/bookkeeping problem.

Force-stopping the app immediately reduces the load. After the app has run overnight, only a reboot reliably restores normal behaviour.

Android version

Android version: Android 17 / One UI 9.0

Device brand and model

Samsung Galaxy S25

Stock or custom OS?

Stock

Nextcloud android app version

35.0.1

Nextcloud server version

35.0.2

Using a reverse proxy?

Yes

Android logs

Normal logcat did not show a clear app-level error. Samsung extended app debugging was not enabled during previous occurrences.
I can provide:
A logcat capture during an occurrence
A Samsung bug report after enabling extended debugging

Server error logs

There were no relevant logs on the server.

Additional information

Two changes coincided with the first occurrence:

The Nextcloud database was moved to an external server to reduce SSD wear. The web UI is usable but slower; database latency could contribute to upload timeouts or retry loops.

Around the same time, Google Play permission problems affected the Nextcloud Android app. I reset the app, but did not completely uninstall and reinstall it.

The fact that failed uploads are successfully uploaded the next day makes me suspect that the app may repeatedly retry or rescan files after a network failure, possibly interacting badly with Android/Samsung background-process management.

Questions:

Is this related to the known high battery/CPU usage reports for Auto Upload? Similar reports exist for high battery drain with auto upload, repeated background activity, and upload loops with large folders.

Could an upload failure trigger an excessive retry loop?

Should I test the F-Droid build for better logs, enable Samsung extended debugging, or completely uninstall/reinstall the app?

Could the external database latency or the WireGuard/Apache proxy path contribute to the connection failures?
IPv4 path: homeserver → WireGuard tunnel → Apache 2 reverse proxy. IPv6 should connect directly to the homeserver.

Screenshot:
Image

Independently of Auto Upload, when scrolling through the photo/media view, the server connection repeatedly drops after approximately 5 minutes. Initially, images load normally. Afterwards, only cached files can be accessed. This happens even when Auto Upload is not actively uploading.
It may indicate a network/request timeout, an IPv6/WireGuard/Apache proxy issue, or a problem in the app’s media browsing/request handling. The high CPU load may be a separate Auto Upload issue, but both started around the same time.

Update: I have not been able to reproduce the issue since then.
I later found that the connection-drop/timeout symptom was likely caused by an inactive/no-longer-valid redirect, which made the app prioritize IPv4.
For the CPU/overheating issue during Auto Upload, the very high latency of my Nextcloud instance may have been a contributing factor: the database was hosted externally without compression or optimization, with wait times of up to 8 seconds. This could have caused upload timeouts and repeated retries, but I cannot confirm it.
If it happens again, I will provide app logs, logcat, and a Samsung bug report.

Update:

The issue is caused by a conflict between Samsung's "Protect Battery" (80% charge limit) and Nextcloud's "Only upload when charging" option (once the battery hits 79-80% and stops charging while plugged in, Android and Nextcloud enter an endless start/cancel loop).

​Workaround for affected users until a patch is released: Simply disable Samsung's Battery Protection (80% limit) in your phone settings, OR uncheck "Only upload when charging" in the Nextcloud Auto Upload settings. (Full technical analysis in the comment below).

Activity

  1. daniele-verducci commented on Oct 28, 2026

    @daniele-verducci
    Contributor

    Hey @JanisPlayer , thanks for reporting.
    I'm not aware to noticeably high load to both server and phone during autoupload. Of course some load has to be expected, expecially server-side due to the thumbnails generation. In your case some overhead client-side is also added by the VPN.

    Can you elaborate on the Google Play permission problems part?

    The expert on autoupload is @alperozturk96 , so he's probably better suited to answer than me.

  2. added
    needs infoWaiting for info from user(s). Issues with this label will auto-stale.
    and removed on Oct 28, 2026
  3. alperozturk96 commented on Oct 29, 2026

    @alperozturk96
    Collaborator

    @JanisPlayer

    Thanks for the detailed report. We tested via 35.0.2 with Auto Upload set to "only when charging". CPU peaked at about 3% and system_server stayed under 2%.

    Could you attach a logcat or Samsung bug report captured while the phone is overheating, so we can look at what's specific to your device?

    Additionally could you please,

    Turn on Developer options: Settings → About phone → Software information → tap "Build number" 7 times. While you have the described issue, go to Developer options → "Take bug report" → "Full report", then share the zip.

    Then could you do the same for: Developer options → "System Tracing" → turn on "Show Quick Settings tile".
    When the issue starts, tap the tile to start recording. Stop it after 30–60 s and share the trace file.

  4. changed the title [-]Title: Auto Upload causes extreme CPU usage, overheating and system_server load while charging; uploads may fail with connection errors but succeed later[/-] [+]Auto Upload high CPU usage[/+] on Oct 29, 2026
  5. JanisPlayer commented on Nov 5, 2026

    @JanisPlayer
    Author

    In-depth Technical Investigation: Auto Upload High CPU / Infinite WorkManager Loop

    I caught the bug live on my device while it was actively occurring and performed a real-time debugging and logcat analysis via live ADB over Wi-Fi and codebase inspection using Google Antigravity with Gemini 3.8 Flash (High).

    Below are the exact technical findings, the underlying mechanism, and why this occurs.


    1. Environment & Device Status

    • Device: Samsung Galaxy on Android 16 (Build CP2A.260605.016, targetSdk 36)
    • App: Nextcloud Android Client v35.0.2 (versionCode=350000290)
    • Triggering Folder: Synced Folder ID 3 (/storage/emulated/0/Movies/Telegram), with:
      • Requires Charging: true
      • Wi-Fi only: true
    • Battery State: Samsung "Protect Battery" (80% charge cap) active (mProtectBatteryMode: 1, charge level ~80%, status: 4 / BATTERY_STATUS_NOT_CHARGING, AC powered: true).

    2. The Symptom

    • com.nextcloud.client (PID 9609) was pinned at 100% CPU (accumulated >53 minutes of CPU time).
    • system_server (PID 2805) was pinned at ~213% CPU (accumulated >130 minutes of CPU time).
    • The phone was overheating significantly (battery temperature climbed to 40.0°C) and draining battery while plugged into the AC charger.
    • The device's JobScheduler had accumulated over 7,489,000 scheduled jobs (#AutoUploadWorker#@androidx.work.systemjobscheduler).

    3. Root Cause Analysis: The ~10 ms Infinite Start-Cancel-Reschedule Loop

    The high CPU usage is caused by an unthrottled infinite loop running at ~60–80 Hz (every 10–15 ms) between Android's OS-level JobScheduler and Nextcloud's AutoUploadWorker:

    ┌────────────────────────────────────────────────────────────────────────┐
    │ 1. Android JobScheduler fires onStartJob (considers constraints MET)   │
    └───────────────────────────────────┬────────────────────────────────────┘
                                        ▼
    ┌────────────────────────────────────────────────────────────────────────┐
    │ 2. AutoUploadWorker.doWork() starts and calls trySetForeground()       │
    └───────────────────────────────────┬────────────────────────────────────┘
                                        ▼
    ┌────────────────────────────────────────────────────────────────────────┐
    │ 3. SystemForegroundDispatcher starts tracking constraints              │
    │    -> WorkManager's in-process trackers report CONSTRAINTS UNMET       │
    └───────────────────────────────────┬────────────────────────────────────┘
                                        ▼
    ┌────────────────────────────────────────────────────────────────────────┐
    │ 4. WorkManager cancels the worker via StopWorkRunnable (reschedule=true)│
    └───────────────────────────────────┬────────────────────────────────────┘
                                        ▼
    ┌────────────────────────────────────────────────────────────────────────┐
    │ 5. JobScheduler receives reschedule, re-evaluates OS constraints (MET) │
    │    and IMMEDIATELY triggers onStartJob again ~10 ms later! (Backoff=0) │
    └────────────────────────────────────────────────────────────────────────┘
    

    Why do constraints mismatch between JobScheduler and WorkManager?

    1. NetworkRequestConstraintController and setForeground():

      • Nextcloud builds a custom NetworkRequest via SupportedNetworkTransports.getConstraints(...) and applies it with setRequiredNetworkRequest(...).
      • When trySetForeground() is called right at the start of doWork(), SystemForegroundDispatcher activates NetworkRequestConstraintController.
      • On initial capability evaluation (NetworkRequestConstraintController send initial capabilities), it dispatches ConstraintsNotMet(STOP_REASON_CONSTRAINT_CONNECTIVITY) on the exact same thread at the exact same millisecond. This aligns with known Jetpack WorkManager issues regarding rapid foreground transitions with custom network requests (e.g., Google Issue Tracker #427115602 and #423403088).
    2. Samsung "Protect Battery" (80% Cap) vs BatteryChargingTracker:

      • When Samsung's 80% limit is reached, Android sets BatteryManager.EXTRA_STATUS = BATTERY_STATUS_NOT_CHARGING (value 4).
      • OS JobScheduler (BatteryController): Sees AC powered: true (mService.isPowerConnected()) and considers the charging constraint SATISFIED.
      • WorkManager in-process (BatteryChargingTracker.kt): Evaluates charging strictly as:
        status == BATTERY_STATUS_CHARGING || status == BATTERY_STATUS_FULL
        Because status == 4, WorkManager evaluates charging as FALSE!
      • This creates a permanent disagreement: the OS starts the job because the phone is plugged in, but WorkManager aborts it inside the app because the battery isn't actively rising.
    3. Zero Backoff / Immediate Rescheduling:

      • When AutoUploadWorker is canceled by SystemForegroundDispatcher, WorkManager signals reschedule = true to JobScheduler.
      • Because JobScheduler believes all conditions are satisfied right now, it does not delay execution, but immediately fires onStartJob again 10 ms later.
      • During the brief 5 ms lifetime of each worker cycle, FilesystemRepository repeatedly queries MediaStore (/storage/emulated/0/Movies/Telegram/), which also causes com.google.android.providers.media.module to spike CPU.

    4. Logcat Snippet (Showing a complete cycle in < 10 ms)

    11-05 11:53:44.334  9609 D WM-SystemJobService: onStartJob for WorkGenerationalId(5ec1b6dc-..., generation=0)
    11-05 11:53:44.337  9609 D WM-WorkerWrapper: Starting work for com.nextcloud.client.jobs.autoUpload.AutoUploadWorker
    11-05 11:53:44.337  9609 I WM-Processor: Moving WorkSpec (5ec1b6dc-...) to the foreground
    11-05 11:53:44.339  9609 I WM-SystemFgDispatcher: Started foreground service Intent
    11-05 11:53:44.339  9609 D WM-WorkConstraintsTrack: NetworkRequestConstraintController send initial capabilities
    11-05 11:53:44.339  9609 D WM-SystemFgDispatcher: Constraints unmet for WorkSpec 5ec1b6dc-1a57-4049-8413-77c2a818fa57
    11-05 11:53:44.341  9609 D WM-StopWorkRunnable: StopWorkRunnable for 5ec1b6dc-...; Processor.stopWork = true
    11-05 11:53:44.342  9609 I WM-WorkerWrapper: Work [ id=5ec1b6dc-... ] was cancelled (WorkerStoppedException)
    11-05 11:53:44.343  9609 D WM-Processor: Processor 5ec1b6dc-... executed; reschedule = true
    11-05 11:53:44.343  9609 D WM-SystemJobService: 5ec1b6dc-... executed on JobScheduler
    

    5. Suggested Fixes / Mitigations

    1. Enforce Minimum Backoff on Constraint Cancellation:
      • If AutoUploadWorker is canceled due to constraint mismatch or stopped via WorkerStoppedException, ensure that WorkManager does not instantly reschedule with 0 backoff. A minimum backoff / cooldown period (e.g., 30s) would prevent CPU starvation.
    2. Postpone trySetForeground():
      • Instead of calling trySetForeground() immediately upon worker start, evaluate if it can be deferred until an actual file transfer begins, or verify whether SupportedNetworkTransports.getConstraints() triggers the known WorkManager NetworkRequestConstraintController bug when bound to foreground services.
    3. Handle BATTERY_STATUS_NOT_CHARGING (80% Protection):
      • Be aware of the discrepancy between OEM battery protections (Samsung / Android 15/16 80% limits) and WorkManager's BatteryChargingTracker.

    6. Diagnostic Files & Secure Transfer

    I have collected the requested diagnostic files during this exact incident:

    • Perfetto trace: trace-sun-CP2A.260605.016-2026-11-05-11-30-21.perfetto-trace (~138 MB)
    • Bugreport zip: bugreport-pa1qxeea-CP2A.260605.016-2026-11-05-11-27-56.zip (~92 MB)

    Because these files contain full system traces and are quite large (~130 MB compressed / uncompressed), what is the preferred way to securely share them with the developers?

    • I can provide a password-protected Nextcloud public share link with an expiration date.
    • Or, if a developer has a private upload drop folder or wants to exchange them securely via email, please let me know!
  6. JanisPlayer commented on Nov 10, 2026

    @JanisPlayer
    Author

    @alperozturk96 I built and installed a local QA app with the patch from PR #17973 to test whether it resolves the issue and still functions properly. So far, everything looks good on my end!

    However, I would really appreciate it if experienced Kotlin / Android developers could review the proposed changes. While the AI-generated code honestly surprised me in a very positive way, I am rather a beginner when it comes to Kotlin/Android development and don't have the complete architectural overview of your app. Before I invest too much time testing an implementation you might want to approach differently, I'd love your feedback—or feel free to provide an official QA/test build if you prefer implementing it your own way.

    One important finding: Disabling Samsung's Battery Protection (the 80% cap) completely made the problem disappear on the regular release app! So Samsung reporting BATTERY_STATUS_NOT_CHARGING while plugged in was indeed the direct trigger that hit the WorkManager desync.

    Strictly speaking, this is an OEM/Android quirk that could be reported to Samsung or Google, but having a safeguard inside Nextcloud is much more practical: it protects users across various OEMs and fundamentally prevents the app from ever entering such an infinite, unthrottled job restart loop again.

    Best regards,
    Janis

  7. alperozturk96 commented on Nov 13, 2026

    @alperozturk96
    Collaborator

    @JanisPlayer Hey,

    Could you please try with this PR: #18049 ?

  8. JanisPlayer commented on Nov 13, 2026

    @JanisPlayer
    Author

    @alperozturk96 Thanks for the fix! This approach makes much more sense than removing the charging constraint.

    I’ll test this version with Samsung’s 80% battery protection enabled and let you know if I run into any issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugfeature: auto uploadneeds infoWaiting for info from user(s). Issues with this label will auto-stale.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions