How BitChat's Adaptive Battery Mode Optimizes BLE Power Consumption: 5 Proven Mechanisms

BitChat's adaptive battery mode reduces Bluetooth Low Energy power draw by dynamically throttling scans, advertisements, and relay traffic based on real-time network conditions and device state.

BitChat is an open-source messaging protocol that uses mesh networking over BLE to enable decentralized, censorship-resistant communication. The challenge with any BLE-based mesh is battery drain—constant scanning and broadcasting can deplete a smartphone in hours. BitChat solves this through a sophisticated adaptive battery mode that minimizes radio usage without breaking message delivery. Below, we examine the five core mechanisms implemented in BLEService.swift and how they work together.

Traffic-Aware Throttling Based on Recent Activity

The adaptive battery mode continuously monitors network load through a traffic timestamp history stored in recentTrafficTimestamps.

When the channel shows heavy activity, the service automatically reduces scan frequency and advertisement bursts. This prevents the radio from waking repeatedly for operations that would likely collide with existing traffic.

In BLEService.swift at line 5955, the implementation tracks these timestamps to classify channel state. The scan interval then adjusts:

  • Heavy traffic → Longer scan intervals (less frequent radio activation)
  • Light traffic → Normal short intervals for responsiveness

This single optimization eliminates power-wasted scan cycles during active mesh conversations.

High-Degree Relay Threshold and Probabilistic Forwarding

BitChat defines a configurable constant TransportConfig.bleHighDegreeThreshold (default: 6) in the transport configuration. This threshold identifies nodes with dense peer connectivity.

When a node's degree exceeds this threshold, the adaptive battery mode enables probabilistic relaying:

// Probabilistic relay when node degree is high
let relayProbability = (peerDegree > TransportConfig.bleHighDegreeThreshold) ? 0.3 : 1.0
if Double.random(in: 0...1) < relayProbability {
    forwardRelay(message)
}

Rather than forwarding every relay packet—which would saturate the local mesh and keep the radio saturated—high-degree nodes randomly drop 70% of potential relays. This preserves network coverage while dramatically reducing outgoing BLE transmissions.

Fragment-Train Pausing During Large Transfers

Large messages in BitChat are fragmented across multiple BLE packets. Continuous scanning during these fragmented sends would force the radio to interleave reception with transmission, increasing power consumption significantly.

The adaptive battery mode implements pauseScanningDuringLongFragmentTrains (see BLEService.swift at line 5531). When a fragment train is active:

  1. Scanning pauses completely
  2. The radio focuses exclusively on completing the current transmission
  3. Power-hungry scan operations are deferred until transmission finishes

Scanning is among the most energy-intensive BLE operations. By batching this pause during known-high-activity periods, BitChat avoids the multiplicative power cost of simultaneous TX/RX operations.

BitChat's BLE queue owns three critical buffers that naturally limit traffic burst rates:

  • pendingPeripheralWrites
  • pendingNotifications
  • pendingWriteBuffers

These buffers implement back-pressure at the link layer: data is only written when the BLE link reports writable capacity. The adaptive battery mode never forces writes that would trigger radio retries or NACK storms.

This design means the radio stays idle whenever the link cannot accept more data, rather than burning power on doomed retransmission attempts.

Adaptive TTL for Relay Messages

The same bleHighDegreeThreshold that triggers probabilistic relaying also drives adaptive time-to-live (TTL) calculation. Messages routed through high-degree nodes receive shorter TTL values.

Shorter TTLs cause messages to expire sooner, preventing indefinite circulation through dense mesh regions. This reduces overall network traffic volume—and consequently BLE radio activity—without affecting message reachability in well-connected areas.

Implementation Architecture

These five mechanisms coordinate through the BLEService class, with configuration centralized in TransportConfig.swift:

File Purpose
bitchat/Services/BLE/BLEService.swift Core implementation: traffic tracking, scan pausing, relay logic
bitchat/Services/TransportConfig.swift bleHighDegreeThreshold and other battery-mode constants
docs/BLE-ARCHITECTURE-V3.md Architectural documentation of battery optimization goals

The flood/battery controls and threshold definition appear at lines 200-202 of BLEService.swift, with inline comments documenting the trade-offs between reliability and power conservation.

Summary

  • Traffic-aware throttling reduces scan/advertise frequency during busy periods
  • High-degree probabilistic relaying cuts unnecessary forwarding from well-connected nodes
  • Fragment-train pausing eliminates power-costly scan/TX overlap
  • Link-layer back-pressure naturally limits burst rates without forced retries
  • Adaptive TTL prevents traffic accumulation that would sustain radio activity

BitChat's adaptive battery mode demonstrates that BLE mesh networking need not sacrifice battery life for decentralization. By observing actual network conditions and adjusting behavior at multiple protocol layers, the implementation keeps radio usage at the minimum necessary for reliable message delivery.

Frequently Asked Questions

Does adaptive battery mode affect message delivery reliability?

No. The optimizations are designed to preserve reliability through statistical guarantees. Probabilistic relaying maintains coverage probability across the mesh, while traffic throttling only reduces redundant operations. The system prioritizes message completion over aggressive power savings when critical traffic is detected.

What is the default value for bleHighDegreeThreshold and can it be changed?

The default value is 6, defined as a constant in TransportConfig.swift. Operators can modify this threshold to tune the trade-off between mesh density and battery life. Lower values trigger power-saving behaviors earlier; higher values maintain more aggressive relaying in dense networks.

How does BitChat detect "heavy traffic" conditions?

The BLEService maintains recentTrafficTimestamps, a short-term history of packet arrivals. When timestamps cluster within a defined window, the channel is classified as heavy. This detection happens inline with normal packet processing at line 5955 of BLEService.swift, without additional overhead.

Is scanning completely disabled during fragment trains?

Scanning is paused rather than disabled. The pause applies only for the duration of the current fragment train, after which normal scan intervals resume. This ensures the node remains discoverable and can receive high-priority packets between large transmissions.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →