View All Development Resources

Reducing Data Transfer in an 'always-connected' mobile application

Ah, mobile phones and their data. When it comes down to it, developers have many key decisions to make in the mobile world that can be the win/lose of their application.

In an ideal world, mobile devices would have unlimited internet allowance at all times, and your application would be the only one running thus it having full bandwidth! But alas, that is not the case (at all), and as such we need to work around that as best possible without hindering the user experience.

No matter what your application, you should never aim for more than a 7.5KB/s generally available connection speed on a mobile device. Yes, you read that correctly, and you're possibly wondering why so low, with the popularisation of HSPA/HSDPA/etc connections.. Well it's simple, mobile signals fluctuate a lot, which means one minute you could be running on full speed HSDPA (3G), and the next you could be right down to GPRS (2-2.5G), which is exactly where the 7.5KB/s figure comes from. The baseline/average GPRS connection rate (downstream) is roughly 60kbps, which translates to 7.5KB/s.

For most applications this is fine, for example you just do a download of 100KB data periodically, but in this case you probably wouldn't be using raw sockets for this download anyway, and would use something more robust and (hopefully!) built in to the operating system for the download, such as a HTTP GET request.

But what about when it comes to "always-connected" applications, such as an instant messenger, or online game? When it comes to this, you really have to factor in all options. Perhaps you, as a high-end user, have a full 1GB data allowance on your device, but what about everyone else? At last check, the most commonly given data allowance was around 250MB/Month, and I'm sure that the user is not expecting your single application to use it all up!

So what's the best way to get around this? You have quite a few options, including:

  • Cache on the client side (device memory)
  • Manual refreshing
  • Polling the server for data
  • Only sending stripped down data (for example a mobile/desktop version of your app)

So which is best? Well there isn't a single option that will work for everyone, but how about something that combines all 3? An application that caches it's initial results, so that each time your application is loaded it doesn't need to do the same thing, allows the user to manually refresh all data, and constantly polls the server to see if anything's new, at which point it will receive stripped down data. If you've designed your protocol correctly (or perhaps you're designing it now!) then this is all possible..

What follows is the theory of what I'm getting at, I'll follow this up with some code soon..

First load of your application

First, you should check if you have anything cached? If you do, proceed to load your app and do absolutely nothing on the network side (we'll get to this later). If you don't have anything cached, you should request from the server the very bare essentials you need for your application to run, perhaps this is a logged in user's display name.

Manual Refresh

Your user should always have full control of your application. If they want to request every little bit of data to be refreshed whenever they want, then let them. It's on their head this way. Simply provide a little refresh button (even hide it away in settings if you want), maybe spin it off as a "Delete Cache" button, that way it may only be used by more "tech-savvy" users. Let's face it, if you implement my theory correctly, users will never need to manually refresh all data.

Polling for updates on your static data

Most applications have static data in them, in this example it will be a contact list.

On first load of your application (ever), all you will have retrieved is the basics to get the application running, in this instance, the logged in users' display name. Now what you need is the rest of your data. You should be hashing this, or perhaps get a timestamp of when it last changed.

You would initiate a checking or polling 'session' like this:
     [c] HAVE 0
          [s] HAVE 12345
     [c] GET DATA
          [s] OK 12345
server proceeds to send data.. client updates timestamp to 12345..

Now that you've got the data with the hash/stamp of 12345, any subsequent requests will result in matching HAVE responses from the client/server, so nothing needs to be requested. If they differ, the data should be synced between the 2 parties again. If you do this implementation very well, they will only sync the changed data.. Of course, this would only really work if you had timestamps, as then you can send down only the data that has changed since the timestamp sent over.

General Notes

There was one more step to my idea in that you should only send down stripped data. This is completely dependant on what your protocol allows.

Perhaps initially, when you were developing a desktop application, the best transfer format was XML, as it was easy to parse on both the server + client sides. But when it comes to saving data and enhancing speed, XML is a bulky format. Why not switch this down to JSON? Even better, why not develop a custom protocol just for mobile devices.. Consider the following:

Desktop Application Transfer
<contact><id>1</id><name>Rudi Visser</name><address>Manchester, United Kingdom</address><born>Kingston Upon Hull</born><is_single>0</is_single><is_awesome>1</is_awesome></contact> (177 bytes)

Mobile Transfer (JSON)
{"contact":{"id":"1","name":"Rudi Visser","address":"Manchester, United Kingdom","born":"Kingston Upon Hull","is_single":"0","is_awesome":"1"}} (143 bytes)

Custom Transfer (Protocol based on ordered parameters
CONTACT 1|Rudi Visser|Manchester, United Kingdom|Kingston upon Hull|0|1 (71 bytes)

These examples may not appear to have much difference, but imagine doing this for 100 contacts and I am sure you will see the difference that could be made.. Just by changing your protocol to expect things in a certain order based on a separator, you've over halved the amount of data you need to transfer.

Conclusion

This article covers just a few simple concepts of reducing data transfer, and what you need to consider, and I assure you that there is a lot more to think about, but hopefully these will get you thinking on the right track.