The HyperTrack SDK is active on thousands of devices through 100+ apps across the globe. Users represent all 6 inhabited continents, 2 major smartphone Operating Systems, several tracking use cases and markets, and a variety of network and GPS conditions. We implemented a way for the SDK to record overall battery consumption on the device during the time it was active. This is our first battery benchmarking exercise at a reasonable scale. This goes beyond small scale tests we had done with dozens of users in controlled setups. Turns out, we are able to deliver real-time location tracking with near-zero battery drain.
In this post we share the data that implies that HyperTrack delivers real-time location tracking with near-zero battery drain. We go on to list the battery optimization techniques we used in order to get there.
Scatter plot of hourly battery drain
This is a scatter plot of devices using the HyperTrack SDK. The X-axis represents the duration for which the SDK was active in hours. The Y-axis represents the overall battery drain of the device in % per hour. Please note that this is the overall device battery drain during that time and not just the SDK’s contribution to it. The trend line indicates that the overall battery drain ranges from 2% to 8% when HyperTrack SDK is active.
If you consider a typical smartphone that lasts a full day of use with full charge, 12 to 15 hours of use is equivalent to 6% to 8% battery drain per hour. This independent battery benchmark shows that leading Android phones drain 6% to 9% per hour. The scatter plot suggests that devices with the HyperTrack SDK report a similar battery drain range for a spectrum of real-world usage. This implies that using HyperTrack has near-zero impact on battery consumption.
This is what Delhivery’s Nikhil Vij has to say about the battery impact of HyperTrack in their delivery app used by hundreds of users.
Real-time location tracking features in apps drain a ton of battery in the first cut implementations by developers. Battery optimizations end up taking more development time than the feature itself. Collecting location data and transmitting it to server over the network radio are both battery consuming activities (although their consumption patterns scale differently).
Thanks to all the optimizations put together by our team, you will be able to go through a full day of smartphone usage without worrying about battery levels. Here are things that helped us reduce our battery footprint.
Use activity data to make your app/SDK smarter
Initial versions of the HyperTrack SDK were kept simple and robust. The logic to detect places and activity was in the cloud. The SDK would provide data to the server to make these decisions. While this sounds great in theory, by design it requires transmission of all the sensor and location data to the server at regular intervals. This leads to battery drain. Tweaking the interval results in a brute-force tradeoff between battery and latency. Any developer who has tried to build real-time location tracking is likely to relate to this.
We re-architected the interaction between the SDK and API in HyperTrack v3 released in March. This led to a paradigm shift in battery efficiency while upping the location accuracy. The SDK uses sensor and activity data to make decisions on the device about when to collect and transmit location to the server. E.g. our SDK uses activity data to detect when the user has stopped and when she is on the move. It does not collect or transmit locations when the user is at a stop and collects just enough data to accurately plot the path when user is on the move. It also uses geofences to know when the user has left a place. This context is used to be efficient about data collection. Simply putting the SDK into hibernate mode at a stop has had tremendous battery gains.
Variable Frequency (VF)
Battery cost of GPS data transmission is 5x to 10x that of collection. We use this to our advantage by deferring data transmission where possible. We do not collect and transmit GPS data at a single static frequency. Instead, we interpret the context and push corresponding notifications down from our server to the SDK with different frequencies to collect and transmit GPS data at different points in time. E.g. If no one is actively consuming the user’s location stream, we collect and store this data on the SDK but do not transmit it for long periods of time. We opportunistically find a time window when user is on WiFi or some other app has invoked the network radio. On the other hand, if the user is being tracked live, we send FCM/APNS notification to SDK to collect and transmit data in near real-time.
The VF model of location data collection and transmission overrides the fixed frequency paradigm, and provides significant battery gains as a result. We talked more extensively about this model in our earlier blog.
There is no worse battery drainer than waking up the radio transmitter multiple times through separate network calls. Do this only if you absolutely must. In general, it is a good idea to batch network calls in a single request instead of making multiple network calls. We redesigned our API that receives data from the SDK such that a diverse set of data types are received at a single endpoint with abstract type (sdk_event). This makes it straightforward for the SDK to send all kinds of data as a large compressed batch of sdk_events.
Smaller the payload, faster the transmission. In addition to batching, we gzip the request so we get the extra oomph from compression. We designed the payload to be minimal by only sending the diff instead of the entire message where possible (e.g. device health info). Overall, this has reduced the payload size by over 5x and contributed to battery savings.
Sluggish APIs cause longer network cycles resulting in higher battery consumption. We made sure that the API endpoints interacting with the SDK respond quickly and have low latency. We moved non essential processing to asynchronous tasks on Celery and retained the bare minimum in the API sync cycle to achieve low latency. The next step might be to have API servers available in multiple regions closer to the user.
Android introduced Doze mode starting from 6.0. Our SDK embraced the mode instead of working around it. We register for callbacks when the network radio is activated by another app, and tie our network calls to these callbacks. These callbacks typically happen in the maintenance window of Doze mode. It enables us to piggyback on network activity of some other app, reducing overall battery footprint.
That’s all folks. Plug our SDK in your app within a few minutes, make a trial run, and let us know your experience.