Recently I analysed logs of some of my mobile apps, mostly enterprise with backend web services. And some thoughts that result from it are well worth sharing. That mainly concerns architects and developers of corporate apps, rather than game or standalone apps – network-related problems are harder to solve, as you don’t control the environment.
Main problem of online mobile app, which is the mobile app that consumes some web services to provide user with data (from weather and currency conversion to schedules and rosters) or accept user input (from notes to photos), is network transfer. It’s fluctuating – because of network provider, because of operating system that switches network interface off and back for one reason or another, because user is moving and his IP address changes, or simply because the throughput fluctuates or connection drops.
Whenever network connection requires a conversation between client and server, i.e. more than one exchange of request-response pair, problems accumulate. We can say that problem potential is proportional to the length of conversation.
HTTP / HTTPS
When you are retrieving file from web server, be it HTML page, CSV file or anything else, you are having numerous conversations.
1. Your application retrieves the IP address from DNS server. If the URL starts with domain name, not with IP address, then application contacts DNS server and sends request for the IP address. This is where many failures occur if your DNS server isn’t quick to reply (e.g. free DNS service by domain hosting company) or if domain name is not frequently requested from this DNS server. Each DNS “A” record has “Time to Live” value, or TTL, which states for how long both device and DNS servers should keep that record in cache. If TTL is default 1 hour, but application requests it twice a day, then each time it will be requested from higher level domain server, hence increasing the latency of requests. Quite often it will end in “domain name not found” error for the app.
2. If you are using SSL, then additional problem arises. Web server has physical limitation on how many secure connections it may serve, and how many new SSL connections it may initiate per second. Surprisingly, Windows is doing better than Linux in this regard since Windows Server 2008 R2, but still it’s around 60 per second. And SSL session has initialization stage, a handshake, that requires client and server to exchange encryption keys, verify certificate and so on. If your mobile app is running on a physically moving device, then either connection will be reset due to timeout, or there will be security issue – there is a bunch of errors that may happen due to different factors – time synchronization between devices, incompatibilities, IP address change and whatever else.
So, if you are retrieving data from web server using secure link, then first you’ll have the DNS challenge, and then – SSL.
Solution: when possible, don’t use SSL. Often you don’t actually need it, as the data is not sensitive. Ensure you are using fast DNS server, preferably paid service, or if your IP address is static and reserved (e.g. it won’t change if your cloud server is turned off and restarted) – you will gain performance and stability by not using the URL, but IP address and port combination.
A hybrid solution would be “IP first” – first you try to connect to IP address, but if it doesn’t work – try to resolve it from DNS and see if it changed (or server is actually down). If IP is different – save it for later.
If you are transferring lots of compressible data (i.e. NOT jpeg / mpeg) – compress it before sending. It will be quicker and safer to decompress it on server, than hoping that connection will endure the whole transaction.
If you want to send compressed data and it might contain sensitive information – rather encrypt compressed data on the phone and send using faster insecure channel, than use SSL. That’s more complex, because you will have to solve problems like secure key exchange, but if you can do it – it will worth it.
If your application is writing logs, and each application should have some sort of logging for the purpose of debugging, then compress them all before sending to server, preferably all files in one archive.