Battery Optimization for Continuous Biosignal Recording Apps

A 30-minute EEG meditation session drains 4 percent of your phone's battery. An 8-hour overnight sleep study drains 65 percent. The difference between those two numbers determines whether your biosignal recording app is viable as a product or a science experiment that requires users to keep their phone plugged in. Battery optimization for continuous recording is not about clever tricks. It is about understanding exactly where the energy goes and making deliberate tradeoffs at every layer of the stack.

This post breaks down the specific power consumers in a biosignal recording app on Android, with real battery benchmarks from our work on EEG and multi-modal recording apps at DEVSFLOW.

Where the Battery Actually Goes

We profiled a typical 8-channel EEG recording app using Android's Battery Historian and found the following power breakdown during screen-off recording on a Pixel 7:

The BLE radio and CPU wake time are the two biggest targets. Optimizing either one has a measurable impact on real-world battery life.

BLE Connection Interval: The Biggest Lever

The BLE connection interval determines how often the phone's radio wakes up to exchange data with the peripheral. At CONNECTION_PRIORITY_HIGH (7.5 ms interval), the radio wakes roughly 133 times per second. At CONNECTION_PRIORITY_BALANCED (30 ms), it wakes 33 times per second. At CONNECTION_PRIORITY_LOW_POWER (100 ms), it wakes 10 times per second.

The power difference is substantial. In our measurements, switching from HIGH to BALANCED priority on a Pixel 7 reduced BLE-related power consumption by approximately 40 percent during continuous EEG streaming. The question is whether your data rate can tolerate the longer interval.

For 8-channel, 250 Hz EEG with a 244-byte MTU, you need to deliver roughly 8 KB per second. At a 30 ms connection interval, you get about 33 connection events per second, each able to carry multiple notifications. With 244-byte payloads, you can deliver 4 to 6 notifications per connection event on most Android devices, giving you roughly 33 to 48 KB per second of throughput. This is more than enough for 8 KB per second of EEG data.

The practical approach: start with CONNECTION_PRIORITY_HIGH during the initial connection and MTU negotiation, then downgrade to CONNECTION_PRIORITY_BALANCED once streaming is stable. If you detect packet loss at BALANCED priority (via sequence number gaps), step back up to HIGH temporarily and retry the downgrade after 30 seconds.

Firmware-Side Connection Interval Preferences

The peripheral can express its preferred connection interval range in its GAP configuration. For battery-optimized recording, set the firmware's preferred interval to 15 to 30 ms rather than 7.5 to 15 ms. On nRF52-based devices using the SoftDevice, configure this via ble_gap_conn_params_t with min_conn_interval set to MSEC_TO_UNITS(15, UNIT_1_25_MS) and max_conn_interval set to MSEC_TO_UNITS(30, UNIT_1_25_MS). Both the phone and peripheral save power when using longer intervals.

CPU Wake Lock Strategy

During screen-off recording, your app needs to keep the CPU alive to process incoming BLE data. Android provides two mechanisms for this: wake locks and foreground services. You need both, but how you use them determines your power efficiency.

A PARTIAL_WAKE_LOCK keeps the CPU running but allows the screen and other hardware to sleep. Acquire this wake lock when recording starts and release it when recording stops. Do not use FULL_WAKE_LOCK or SCREEN_DIM_WAKE_LOCK during screen-off recording. There is no reason to keep the screen on if the user is not looking at it.

Combine the wake lock with a foreground service running in the FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE category (Android 14+). This tells the system that your app has a legitimate reason to maintain a BLE connection and should not be restricted.

The critical optimization: minimize what your CPU does while awake. During screen-off recording, disable all real-time signal processing, FFT computation, artifact detection, and UI updates. Your CPU's only job should be reading BLE notifications and writing raw data to a buffer. Every additional computation keeps the CPU in a higher power state and prevents it from clock-throttling.

Data Buffering to Reduce Write Frequency

Writing data to flash storage is expensive. Each write operation involves waking the storage controller, writing to the NAND cells, and updating the filesystem journal. For an 8-channel EEG stream at 250 Hz, writing every sample individually means roughly 250 write operations per second. That is terrible for both battery life and flash endurance.

Buffer samples in memory and write in bulk. We use a 4-second buffer (1,000 samples at 250 Hz), which reduces write frequency to one operation every 4 seconds. This single change reduced storage-related power consumption by roughly 85 percent in our benchmarks.

The buffer size is a tradeoff between power efficiency and data loss risk. If the app crashes or is killed during recording, you lose whatever is in the buffer. Four seconds is an acceptable loss for most applications. For clinical or research recordings where any data loss is unacceptable, reduce the buffer to 1 second and accept the higher power cost.

Write data using FileOutputStream with buffered I/O, not RandomAccessFile. Better yet, use memory-mapped files via MappedByteBuffer. Memory-mapped writes are handled by the kernel's page cache and flushed to disk asynchronously, which lets the storage controller batch operations and reduces the number of actual NAND write cycles.

Surviving Android Doze and App Standby

Android Doze mode activates when the device is stationary, unplugged, and the screen has been off for a period (typically 30 minutes, though this varies by manufacturer). In Doze, the system batches alarms, defers network access, and restricts background processing. BLE connections are maintained, but your app may not receive notifications promptly if it does not hold a wake lock.

A foreground service with an active wake lock exempts your app from most Doze restrictions. However, some manufacturers (Xiaomi, Huawei, Oppo, Vivo) implement additional proprietary battery optimization that can kill foreground services. These optimizations operate outside the standard Android framework and can terminate your recording without warning.

To handle manufacturer-specific battery optimization:

Screen-Off Recording Architecture

The ideal screen-off recording pipeline has three components running on two threads:

  1. BLE receive thread: The onCharacteristicChanged callback stamps packets with elapsedRealtimeNanos() and pushes them into a lock-free ring buffer. No processing, no allocation.
  2. Writer thread: Wakes every 4 seconds, drains the ring buffer, serializes the samples to your storage format (EDF+, BDF, or a custom binary format), and writes to the memory-mapped file. Goes back to sleep.
  3. Nothing else. No UI updates, no analytics, no network calls. These can all wait until the user brings the app back to the foreground.

This architecture keeps CPU utilization under 2 percent during screen-off recording on a Pixel 7, which translates to approximately 1.5 percent battery drain per hour for EEG-only recording.

Real Battery Benchmarks

We benchmarked our optimized recording pipeline on three devices during continuous 8-channel, 250 Hz EEG recording with screen off:

Before optimization, the same app on the same devices consumed 4.5 to 6.2 percent per hour. The biggest single improvement came from downgrading the BLE connection priority from HIGH to BALANCED, followed by the 4-second write buffer.

For comparison, enabling real-time FFT-based spectral display (even with the screen off, computing but not rendering) increased CPU power consumption by roughly 40 percent. Always gate computation on screen state. If no one is looking, do not compute.

iOS Comparison

On iOS, Core Bluetooth handles BLE power management more aggressively and with less developer control. You cannot directly set connection intervals from the central side. However, iOS is generally more power-efficient for BLE because the Bluetooth stack is tightly integrated with the hardware power management unit. Our equivalent iOS app achieves roughly 1.2 percent per hour on iPhone 14, without any connection interval tuning.

The tradeoff is flexibility. On Android, you can optimize aggressively if you understand the levers. On iOS, you get good defaults but limited ability to push further.

Building a biosignal recording app that lasts through an overnight sleep study without killing the battery is a real engineering challenge. If your team is building a neurotech or biometric product and needs this depth of mobile optimization, talk to DEVSFLOW Neuro. We build recording apps that run for hours, not minutes.