I’ve been looking around for interesting data points to share with other app publishers and found some data in a place I didn’t really expect to find it. After logging into my Google Analytics account for an entirely different purpose, I was taken to the analytics data for my app which I replaced with Firebase about 18 months ago. I don’t check it very often, but to my surprise, there is still a fair amount of action going on.
To give some context to the graph:
- Version 2.1.1 – released November 2014
- Version 3.1.3 – released 11 June 2017 and replaced on 24 June 2017 (Google Analytics was deprecated at this time).
This is amazing user retention for you! I don’t like the fact that I have data in two different places and that these users are mostly forgotten about, but I also cannot complain about it, since this is now just pure passive income. I actually cannot do anything to improve or remove it. Of course, it will also continually decrease as people upgrade phones, they uninstall the app and so on.
Why no upgrade?
At the point where I moved from Google Analytics to Firebase, I had to change my minimum SDK version from 14 to 15. This put me under the assumption that these users are probably unable to upgrade since they are using an old version of Android (4.0.2 or below). So I decide to validate it and check.
In fact, what’s not shown in the pie chart above (as you might think it’s hidden in “other”), is that I had 0 (yes, zero) users who were unable to upgrade to a later version.
Checking my Firebase stats confirmed a similar trend, some users are just very slow in upgrading their apps.
Apk’s lazing about on the internet?
I’ve found my APK’s all over the internet before and then had a look to see whether this is some new app store which I wasn’t aware of distributing old versions of my app. This pointed me to a really interesting installation source: com.sec.android.easyMover. Most of my users with old versions of the app, had this as their installation source. This is Samsung’s tool to move all your data from an old phone to a new one. Of course, this doesn’t point me to where these users initially got the application from, but it just points again at users who do not update their apps. (This also reminded me that I have a very small number of people using my app on the Amazon app store and I decided to upgrade it – it might actually work better for them, since I don’t use Google maps any more).
Architecting the enduring app
I did an earlier post on my app’s version history, where I walked through all the versions of my app from 2013 onwards. I was slightly surprised when I installed version 1.0.0 and it was still working exactly as it did the day I built it. This was mostly by design, but also with a bit of luck.
The external API which my application uses, hasn’t changed since 2013. This is the bit of luck which I had, because if the API (which is not in my control), changed even just a bit, all my old versions would break.
On the other hand, some of the design was deliberate. I had two options when I was designing my app – I could either stick a server between the mobile device and the external API or I could just call the API directly from the mobile device. (Incidently, I had already written much of the server-side code, as I had already done a web-version of the app before even starting the mobile version). I decided to cut out the server, mostly to keep costs down and also for speed considerations – I did not want to create a bottleneck or have to pay when it becomes really popular.
Note that just because option 1 worked out for me, it doesn’t mean that it is necessarily the best option (in fact, in many instances it probably won’t be). There are pros and cons to both and you have to carefully consider them. Speed and cost were two important considerations for me. Not having to have a server in between means that I don’t have to pay for it when 10,000 devices all try to access data at once.
On the other hand, if the external API had to introduce a breaking change, my old versions of the app would all break irreparably and all the users who have been happily using my app for years now, would be really upset (this could be really damaging for my app at some unknown point in the future).
I had to take a bit of a gamble in terms of how to architect my app – as an independent developer, I simply didn’t have the resources to maintain a server and I ended up here out of necessity. Also, as an independent developer, I don’t necessarily want to maintain a server indefinitely just to keep my app running.
There are no right or wrong answers on what the perfect architecture looks like, but you have to keep in mind that people may continue to use your app for a long time after you intended them to do so. One version doesn’t simply replace another and as soon as you publish something, it’s going to be out there for a long time, so make sure that you plan for this. You wouldn’t want you users to give you bad reviews in 5 years time because of a decision you made today.
As a quick side-note, I have seen apps which force you in the app to upgrade to a later version when it becomes available. I don’t like this – in fact, I hate it as a user experience. A better idea might be to just let the user know every now and again that they might be using an out of date version and they should consider upgrading. Don’t force it, unless it is absolutely necessary.