FP4 (Android 15): Background apps being killed more aggressively

Apologies.
Fact: not included.

General suggestion: if something major is not mentioned in the release notes, it is not there.

I understand most of your comments are aimed at Lotte, so will not be responding more unless you tag me;-) just please note that these are not usual working hours for company reps:)

4 Likes

While I understand somehow your try to force any answer from FP its going off topic and its repetition in circles

what FP said somewhere else

3 Likes

I tried to mitigate the issue and it seems I was to some extent successful tweaking the two system-level mechanism below. Here is my debugging session summary:

Details

Summary

After updating to Android 15, the Fairphone 4 aggressively kills background apps — even when sufficient RAM is available (~4.5 GB free out of 7.5 GB). Switching between two apps (e.g., browser to OTP authenticator and back) frequently causes the first app to be killed and restarted from scratch. Music players (Spotify, Tidal), password managers (KeePass), and browsers (Firefox, Brave) are particularly affected. Setting apps to “Unrestricted” battery optimization does not help. This is a regression from Android 13 where multitasking worked normally on the same device.

Device Information

  • Device: Fairphone 4 (FP4)
  • Build: FP4.SREL.15.14.4
  • Android Version: 15 (API 35)
  • Security Patch: 2026-01-05
  • Hardware: Qualcomm (ro.hardware=qcom)
  • RAM: 7,683 MB total (~7.5 GB)

Problem Description

Background apps are killed within minutes of switching away, despite ample free memory. This makes basic multitasking unreliable:

  • Copying an OTP token from an authenticator app causes the browser to lose the login page
  • Spotify/Tidal playback stops when the app is evicted from memory
  • KeePass is killed while switching to the app that needs the password
  • Twitch streams stop after briefly switching away

Severity

This is not a minor inconvenience — it fundamentally breaks Android’s multitasking model. A phone with 7.5 GB RAM should comfortably hold several apps in memory.

Root Cause Analysis

Using adb shell dumpsys activity exit-info, the kill reasons were examined for affected apps. Two system-level mechanisms are responsible:

1. LOW_MEMORY kills (LMKD) — despite sufficient free RAM

The Low Memory Killer Daemon (LMKD) is killing cached apps even when 4.5 GB of RAM is free. This suggests the LMKD thresholds are tuned far too aggressively for a device with 7.5 GB RAM.

2. TOO_MANY_EMPTY_PROCS — cached process cap too low

Android’s ActivityManager enforces a cap of 30 empty (cached) processes (CUR_MAX_EMPTY_PROCESSES=30). Event logs show every automated kill is logged as empty #31 — the instant a 31st cached process exists, the oldest is killed. With modern apps spawning multiple processes (WebView sandboxes, work managers, crash helpers), 30 slots fill up quickly.

3. App compaction is DISABLED

A critical finding: use_compaction=false in the activity_manager device config. App compaction (introduced in Android 10) compresses cached apps in RAM, significantly reducing their memory footprint. With compaction disabled, cached apps consume far more RAM than necessary, leading to more frequent LMKD kills. This appears to be a Fairphone configuration choice, as AOSP defaults to compaction being enabled.

4. Fairphone-customized cached process limit

The setting mCustomizedMaxCachedProcesses=32 shows Fairphone has applied a custom cached process limit lower than the AOSP default. While the effective CUR_MAX_CACHED_PROCESSES was 60, the customization to 32 may affect internal behavior in some code paths.

Evidence

Kill statistics (from dumpsys activity exit-info)

Over a ~24 hour period (2026-04-07 to 2026-04-08):

App LOW_MEMORY kills TOO_MANY_EMPTY kills Total system kills
KeePass2Android 10 6 16
Spotify 7 1 8 (+ additional user-initiated)
Firefox 6 4 10

Sample kill log (Firefox)

timestamp=2026-04-08 15:46:11.938  reason=3 (LOW_MEMORY)
timestamp=2026-04-08 15:24:58.846  reason=13 (OTHER KILLS BY SYSTEM) subreason=3 (TOO MANY EMPTY PROCS)
timestamp=2026-04-08 14:35:06.921  reason=3 (LOW_MEMORY)
timestamp=2026-04-08 14:02:39.758  reason=3 (LOW_MEMORY)

Firefox was killed 4 times in under 2 hours, despite ~4.5 GB RAM being free.

Sample kill log (KeePass)

timestamp=2026-04-08 10:44:34.114  reason=3 (LOW_MEMORY)    rss=156MB
timestamp=2026-04-08 09:01:47.724  reason=3 (LOW_MEMORY)    rss=106MB
timestamp=2026-04-08 01:19:11.301  reason=13 (TOO MANY EMPTY PROCS)  rss=160MB
timestamp=2026-04-08 01:03:54.747  reason=3 (LOW_MEMORY)
timestamp=2026-04-08 00:44:48.504  reason=3 (LOW_MEMORY)
timestamp=2026-04-07 23:59:15.097  reason=3 (LOW_MEMORY)
timestamp=2026-04-07 23:15:25.613  reason=13 (TOO MANY EMPTY PROCS)  rss=72MB
timestamp=2026-04-07 22:59:35.201  reason=13 (TOO MANY EMPTY PROCS)

KeePass — a lightweight app using only 72–160 MB RSS — was killed 8 times in ~12 hours.

ActivityManager event log (logcat -b events)

Every automated kill shows the same pattern — process killed as empty #31:

am_kill: [0,22034,org.mozilla.firefox,995,empty #31,188776]
am_kill: [0,21543,com.werner.spotprisen,985,empty #31,76904]
am_kill: [0,22547,com.google.android.apps.messaging,985,empty #31,175556]
am_kill: [0,20520,ch.protonmail.android,985,empty #31,90028]
am_kill: [0,22898,com.textra,905,empty #31,128544]

Note: even system apps like Google Messages and Proton Mail are being killed.

Problematic configuration values

use_compaction=false                    # App compaction DISABLED
mCustomizedMaxCachedProcesses=32        # Fairphone custom limit (AOSP default is higher)
CUR_MAX_EMPTY_PROCESSES=30              # Hard cap on empty processes
CUR_TRIM_EMPTY_PROCESSES=15             # During memory trim, keep only 15
CUR_TRIM_CACHED_PROCESSES=10            # During memory trim, keep only 10

Memory state at time of investigation

MemTotal:     7,683,924 kB  (~7.5 GB)
MemAvailable: 4,491,668 kB  (~4.3 GB free)

4.3 GB of RAM was free while apps were being killed. This strongly indicates the LMKD thresholds are misconfigured.

Attempted Workarounds That Did NOT Help

Workaround Result
Set apps to “Unrestricted” battery optimization No effect — kills are from LMKD/process cap, not Doze
Allow background usage for affected apps No effect — same reason
Clear app caches Temporary, apps killed again within minutes

ADB Workarounds That DO Help (but require reapplication after reboot)

The following adb commands mitigate the issue, confirming the root cause is in system configuration:

# Enable app compaction (compress cached apps in RAM)
adb shell device_config put activity_manager use_compaction true

# Increase cached process limits
adb shell device_config put activity_manager max_cached_processes 64

# Increase max empty process time
adb shell device_config put activity_manager max_empty_time_millis 7200000000

# Disable app standby bucket enforcement
adb shell settings put global app_standby_enabled 0

# Disable phantom process killing
adb shell settings put global settings_enable_monitor_phantom_procs false

These settings do not persist across reboots and may be overwritten by Google Play Services config sync.

Suggested Fix for Fairphone

  1. Enable app compaction (use_compaction=true) — This is the single most impactful change. AOSP enables this by default. Fairphone’s decision to disable it causes cached apps to consume significantly more RAM, leading to premature LMKD kills on a device with plenty of memory.

  2. Review LMKD thresholds — The low memory killer is triggering with 4+ GB free RAM. The minfree thresholds should be reviewed for a 7.5 GB device.

  3. Increase or remove mCustomizedMaxCachedProcesses=32 — This Fairphone-specific customization limits cached processes below AOSP defaults. On a device with 7.5 GB RAM, this is unnecessarily restrictive.

  4. Increase CUR_MAX_EMPTY_PROCESSES — The limit of 30 is being hit constantly. Modern apps (especially those using WebView) spawn multiple processes, filling the 30 slots quickly.

Regression Information

  • Working: Android 13 on the same Fairphone 4 — multitasking worked normally
  • Broken: Android 15 (FP4.SREL.15.14.4) — background apps killed aggressively
  • Same apps, same usage pattern — the only change was the OS update

How to Reproduce

  1. Use Fairphone 4 with Android 15 (FP4.SREL.15.14.4)
  2. Open 5–6 apps (browser, email, messaging, music player, etc.)
  3. Use the browser to start a login flow that requires 2FA
  4. Switch to an authenticator/OTP app to copy the code
  5. Switch back to the browser — observe it has been killed and the login page must reload
  6. Run adb shell dumpsys activity exit-info <package> to confirm LOW_MEMORY or TOO_MANY_EMPTY_PROCS kill reason

How to Verify the Fix

After applying the ADB workarounds above:

adb shell dumpsys activity settings | grep -E "use_compaction|CUR_MAX"

Expected output:

use_compaction=true
CUR_MAX_CACHED_PROCESSES=64
CUR_MAX_EMPTY_PROCESSES=32

Then repeat the reproduction steps — apps should remain in memory during normal multitasking.

Impact

  • All Fairphone 4 users on Android 15 are likely affected
  • Basic multitasking (switching between 2–3 apps) is unreliable
  • Music/audio playback interrupted when app process is killed
  • Password managers killed mid-workflow, requiring re-authentication
  • Authentication flows broken when browser is killed during 2FA
  • No UI-accessible workaround exists — requires ADB

Related

  • AOSP CachedAppOptimizer source (compaction enabled by default):
    frameworks/base/services/core/java/com/android/server/am/CachedAppOptimizer.java
10 Likes

I recently (a few hours ago) got an update to FP4.QREL.15.16.1

The patchnotes told me, that the bug with the launcher got fixed. since the update the problems with the restarting launcher are gone.

The issue with the killed background apps is still there… At least FP5 got a working patch, so maybe we’ll get one too soon…

1 Like

Just upgrade to lineage OS. Fixes the problem - although like all mods, nfc payments will cease to work due to Google not recognising the new OS. However the OS is still secure and receives more regular security patches than the official one.

Hope someone in development reads your message :folded_hands: