Mobile radios do not turn on and off per packet. Sending anything promotes the radio from a low-power idle state into a high-power connected state (3GPP calls this RRC_DCH), and after the last byte the radio does not drop back to idle immediately — it lingers for a tail timer in case more data arrives, because re-promoting is itself expensive:
Energy(episode) ≈ E_promote + P_high · (t_send + T_tail)
Battery(t) = Battery(t-dt) − [ P_idle·dt (radio idle)
+ P_high·dt (radio active, incl. tail) ]
− E_promote (on each idle → active transition)
This simulator's numbers: idle draw P_idle = 0.02%/s, active draw P_high = 0.9%/s, one-time promotion cost E_promote = 0.15% per wake-up. They are illustrative, not a specific chipset's datasheet, but the ratios (idle ≪ active, and a wake costs roughly as much as ~150 ms of active time) match real LTE/5G power profiles.
- Event rate — how often the app generates a telemetry event (a metric, log line, or trace span).
- Batch flush threshold — how many queued events accumulate before the app actually calls the network. At 1, every single event triggers its own radio wake — the naive, worst case.
- Radio tail timer — how long the modem stays in the high-power state after the last upload before demoting to idle. Every new flush that arrives before the tail expires extends the tail instead of paying a fresh promotion cost — this is why bursty-but-frequent uploads are far worse than the same data sent in fewer, larger batches.
- Radio duty cycle — the fraction of elapsed time the radio has spent in the high-power state. This is the number that maps most directly onto battery drain.
Real-world relevance: this exact tradeoff is why production mobile SDKs (crash/analytics/APM telemetry) batch and debounce network calls instead of flushing on every event — a naive "send immediately" instrumentation can keep the radio pinned awake nearly continuously and measurably shorten battery life just from observing the app, not from anything the user is doing.