If You're Programming a Cell Phone Like a Server You're Doing it Wrong
Wednesday, September 18, 2013 at 8:55AM
Todd Hoff in Strategy, mobile

Power on a cell phone is like water in a desert. It’s the very stuff of life. If you take the same naive programming techniques you learned when programming on a server in a datacenter your cell phone will die of thirst.

This is dramatically shown by Reto Meier, Tech Lead for the Android Developer Relations Team, in a remarkable series of instructional videos:

Remarkable because these videos are short, to the point, and chocked full of useful ideas and techniques. Though Android is targeted specifically, most of content should be generally useful.

As an example of how server programming differs from mobile programming, on a server copying a file from one server to another server is usually a one or two liner. Read a block of data from a file descriptor and write it to another file descriptor. It's a synchronous process. You can mess with block sizes and other tricks, but that's the basics. Using this naive natural as nature “sipping” type logic on a cell phone is wrong, it's the Little Cookie approach we'll talk about later. The problem is it drains the phone battery. Why? The cell radio will be on continuously. Why? You’ll learn that a bit later, but what you need to do is minimize radio usage by batching and properly scheduling transfers. You are not in Kansas anymore. 

Which brings us to the...

Key idea: The cell radio is one of the biggest battery drains on a phone. Every time you send data, no matter how small, the radio is powered on for up for 20-30 seconds. Every decision you make should be based on minimizing the number of times the radio powers up. Battery life can be dramatically improved by changing the way your apps handle data transfers. Users want their data now, the trick is balancing user experience with transferring data and minimizing power usage. A balance is achieved by apps carefully bundling all repeating and intermittent transfers together and then aggressively prefetching the intermittent transfers.

How does a cell radio work?

To minimize radio usage and thus minimize power usage you must first understand how a cell radio works. The videos do a great job explaining all this, but here’s the gist:

It should be clear that if you send data naively on a cell phone you are screwed. Which brings us to the  two models of how to transfer data:

Who is the winner? Big Cookie. Little Cookie heavily fragments radio use. For every data transfer the radio stays on for 5 seconds at full power followed by 10-60 seconds at a lower power state before returning to Standby. Every time you transfer data you are powering the radio for at least 20 seconds. So sending small amounts of data frequently is the best way to drain a battery. Let’s say you send analytics data every 15 seconds and the the user clicks on a link intermittently. The result will be the radio is on continuously. So don’t do that.

What should your app do?

The upside of knowing about the cell state machine is that if you work with it you can balance application latency and power usage. The videos go into a number of techniques to bring about balance:

The videos go into all of this in more detail, especially on the SyncAdapter, and they were well worth watching.

These videos make clear what may have not been clear before: programming cell radio based mobile devices is a specialized domain that takes some specialized knowledge and techniques to do well. If you've always wondered why apps use so much power and your battery doesn't last as long as it should, it's easy to see why.

From the Comments

iOS7 Notes

Plorkyeran: iOS finally added background data fetching in iOS 7, but it's very heavily restricted (the OS chooses when apps get woken up to fetch, not the app, and in practice it can be as rare as once a day). Other than that, only a very limited number of categories of apps get to do stuff in the background (such as music players, voip apps, and location trackers), and they actually do reject apps which claim to qualify for the exemption but don't.

dzamir: In fact iOS7 uses the same strategy described in this post: it wake ups all the applications that require a background download at the same time to minimize the time the radio is on.

Isn't Worrying About Power Just a Case of Premature Optimization?

miratrix: The difference between DCH (the full-on high power state) and PCH (the lowest power, waiting-for-paging state) is about 2-orders of magnitude. Last time I measured, it was about ~100mA vs ~1mA (at ~3.7V) used by the radio. So, it's not couple of minutes of battery life, but rather _many_ hours of standby life instead. People usually aren't very happy when a fully charged phone dies overnight.

I've seen apps do some crazy things and it really has a significant effect in over-all battery life. A popular Android weather clock widget woke the phone up every minute to update the minute number on the graphics and updated the weather information every ~15 minutes (gps + radio!) which single handily crushed the standby battery life from multiple days to less than 8 hours.

Yes, I don't think _every_ decision should be based on minimizing the wake ups... but on the other hand, all developers should at least try to have as much understanding of the platforms that they're working on so that they know what trade-offs they're making with each feature they're adding.

kintamanimatt: Respecting known limitations and working within best practices is absolutely not premature optimization. If you know that using the mobile radio in a certain way is a source of excessive battery usage, it's silly to just disregard this information. It's not premature optimization if you know where the performance issues are from the outset, and these performance issues are so incredibly common that the Android team put out videos about them.

The mobile radio will eat your battery very quickly, and probably chews through as much power as your screen. If you want to see how expensive it actually is, disable fast dormancy†. A slightly less brutal demonstration can be had by opening an OpenVPN connection. The keep-alive packets will keep your mobile radio in a higher power state, pretty much in the same way some disrespectful apps do and you'll (quite unsurprisingly) see your battery drain faster.

A badly written app can drain hours of battery charge, not minutes.

kevin_nisbet:  I just want to add in from a network carrier perspective. I work for a mobile operator, and have had to work on several network issues related to poorly designed apps. I agree with kintamanimatt on this, it's not premature optimization, you need to know the cost of what you're doing. There is an incredible resource cost, to all the naive developers making apps these days, that treat the wireless interface as an always on connection.

1. Server polling every minute We actually sent one customer an invoice for over $100,000 because they had a particularly bad application that polled a server every minute. This was only an internal app used by a few hundred people, but they used it at their office, and it caused constant blocking on the cell site covering their office. This actually broke cellular coverage near their office, and caused issues for all the other customers in the same area. Ultimately, we said, we can help you fix you're app, you can pay the invoice to upgrade cell coverage to you're office, or get off our network. In this instance, we helped them fix their app, so it only interacted with the server when something needed to be changed (the server pushed changes), which was actually quite easy to do. This simply isn't the same thing, as writing an inner loop in assembly, to shave off a few microseconds in runtime, which would be premature optimization, and actually making robust software that works well wherever it is used.

2. Synchronized network access This one has been the bane of us on a few occasions. If you write a network access to be like a cron entry, that run's not only every 15 minutes, but does so at exactly the same time between all devices. We get to hunt you down, and scream, as our wireless network crumbles. When every device, wakes up at the same time, and asks for a higher power state, at exactly the same time, the network will only process so many. The funny thing is, you'll test this yourself and not see anything, but then when you release your app, you might find 30% of those checks are failing for some reason, and struggle to figure out why. For any one who is thinking, well the operator should add more capacity, the answer is we do, but ultimately the customer pays for the network build.

3. High usage apps What happens is, your device vendor, is in the interest of protecting it's customers as well. We once had an app on our network, that would treat all reject codes, as a cause to retry. This caused it, to every time it was run, begin uploading data, over and over again, leading to thousands of dollars in bills to the customers for excessive data usage. The device vendor, pulled the app from their stores.

Now, how do you feel, about having to plead the case why you should be allowed to continue to sell your product, not only to the device vendor, but the carrier who found the problem, prove that you fixed it, have our bureaucracy test that you actually fixed it, and maybe if we feel like it, let you sell again. It's not as simple as fix the bugs, you might actually lose you're ability to make money of you're software, for months while this get's sorted out.

What do you think you're store rating will be, when all your customers get sent a $5000 bill for using your app?

Now the question is, should there be a better way, and I'd like to see more from mobile vendors, in making it stupid easy to be smart about this. In the phone API's, if I need to do a background update, I should be able to register with the OS, and say, I have an update to do, within the next 15 minutes, let me know when you have an active radio connection. You're phone goes into a high powered radio connection, and bam, all you're background updates now go out together. Need to send notifications, here is our push API, only interact with the mobile when an update needs to be done. If the API's you're using, are designed for mobile, and take alot of this network stuff that you shouldn't need to know into account, it's a lot easier for the naive developers to do better by blind luck.

-- * my views in this post are my own, and do not reflect those of my employer.

Related Articles




Article originally appeared on (http://highscalability.com/).
See website for complete article licensing information.