So you've got an amazing idea. And you've got your friends from college who can help you start building your app. You are getting great feedback from your early adopters as well. So you do what anyone would. Launch your app!
The first few weeks everything is perfect. The experience is great. Your audience is sticking with you. And most importantly, your user base is growing exponentially.
But then something strange starts happening. User loyalty starts to drop. People are uninstalling your app. You're still growing rapidly, but the churn is too damn high! What's wrong?
You look at your analytics report and notice page load times are high. Requests are getting timed out. The app keeps crashing and the database is pretty much on fire. Not the getting lit you were hoping for.
But your tests were positive. You had planned everything. So what went wrong? Your app just couldn't scale!
Scalability (from a tech standpoint) is often ignored. And that is what starts causing problems like poor user experience, high maintenance costs and what not. So before I help you figure out how to make your apps more scalable, let me define what scalability really is.
What is scalability?
Scalability, in my humble opinion, is - maintaining great user experience - irrespective of the number of users - in a cost effective manner.
As you may have noticed, there are 3 parts to scalability. The most important one is maintaining great user experience. Well sure your app can scale to million of users. But if the experience isn't good enough. You might not even reach that scale. The entire point of scalability is to ensure that your user experience is intact. Cause at the end of the day, all that matters is that your users are happy with your app. Nobody cares about technology.
The second part establishes the context. Your app needs to maintain the user experience, irrespective of the number of active users. If this number is really high, it exerts a considerable load on your backend system. Your goal should be to make your system work independently of this number.
Finally it's something we care about the most. That is money! So let's assume you managed to maintain user experience irrespective of the number of active users. But at what cost? If your costs are rising more rapidly than your user base, your system cannot be called scalable. Ideally, you should be able to support more users with a marginal increase in costs.
Great! So now that we have the definition of scalability cleared up, let's dive into tips to make scalable apps.
Tips to make Scalable Apps
Traditionally scaling needs were handled by increasing the server's resources. This approach is called "scaling up". There are many limitations to this approach. In this post, I'll be focussing on "scaling out". That is, to add new servers and resources to accommodate the increase in load.
1] Choose the Right Technology
I'm pretty sure you saw this one coming. Scalability doesn't come as an afterthought. It needs to be included in the process from the very first design. And this starts from using the right technology.
Programming Language: The first choice you make is the programming language. Yes, the language you choose has a great impact on scalability.
For example, Elixir supports actor based concurrency out of the box. This means elixir processes can talk to each other even if on different physical machines. As a developer you do not need to worry about the underlying network or the protocol used for communication. How cool is that?
Confused on how to choose your next programming language? Here is an article which can help you out.
Database: The second choice is your database. Is the database you use designed with scalability in mind? There is a whole new breed of NoSQL databases whose sole purpose is scale.
They do come in with trade offs though. So you need to select the right database for the job. Probably even use different databases for different workloads.
Communication: With microservices becoming super popular, you need to make sure that the communication channel between your services is scalable as well. Just having them talk directly might not be a very scalable solution.
You'd probably have to use a messaging bus or something similar to make a loosely coupled system. This will help you scale your services independently.
2] Avoid Single Point of Failure
What does a single point of failure mean? Let me answer that by asking you a question. Would failure of a particular resource (eg. a server, network resource) crash your entire app? What would happen if the server running your database or backend code fails? Will your app still be available? If not, that's your single point of failure.
So how do you avoid this? Simple. Have multiple replicas of everything. Run your database on multiple servers. Many support replication out of the box. A great example is MongoDB. Run your backend code on multiple servers. Load balancers can really help you out here.
I understand it's easier said than done. And I have barely scratched the surface. But to sum it up. Scaling your resources horizontally is the key.
3] Push Logic to the Clients
Wait what? Wasn't it already that way? Not really. So the PHP, .Net or nodejs code you write at your backend is the actual logic. The problem with this approach is that your server has to do work everytime the client makes a request. And when multiple such clients start making requests together, we have a problem.
But there is another problem here. We cannot trust the client. What if a client is compromised and overrides the logic you had ported. Big problem right? So the trick here is to try and strike a balance. Only port the logic you can verify.
There are many tools which can help you out here. One of them is a Backend as a Service (BaaS) like Space Cloud. A BaaS will also help you simplify the security aspect. You can learn more about frontend, backend and BaaS in this post.
Pushing logic to the client side can help you reduce your server load. This in turn will help in making your app more scalable. Remember every CPU cycle counts.
4] Cache results
How do you execute your client requests? Do you hit your primary database every time the clients asks for something? This is not a very scalable design. Specially if there are certain sections of your data which are read very often.
Take Twitter for example. People go crazy when a celebrity tweets. The sheer amount of people viewing that tweet can crash your database. Here is where caching can help you.
There are specialized in-memory databases like Redis which can perform reads and writes at lightning speeds. So storing your "hot data" in stores like redis can help you maintain that scale even during peak loads.
But this doesn't mean you'll cache all your data. This is because RAM is more expensive than disk space. This would increase your costs. Cache only the results which are hot or those which require a lot of calculations. Remember, caching impacts freshness of your data.
5] Go Stateless
You need to keep your APIs stateless. In each request, the client should provide all the information which would be required to fulfill that request. That's the concept REST APIs are based on.
This might not be possible in all cases. Sometimes you might have to query your database and other services. That's alright!
What you can start with is removing any sessional data you might be storing on your servers. This is problematic because if a server fails, you'll lose that data and that client is orphaned.
People might recommend you to use Redis to store sessions but that too comes with scaling limits. The best choice is to use JWT tokens. This is by far the most scalable way of handling sessional data. Just make sure your tokens don't become too large. In that case, Redis is your best friend.
So we saw what scalability means and how it impacts your business. Hope the tips I provided here were helpful. If done right it can save you millions of dollars.
Do let me know if I missed out on something. There is only so much I can fit into an article.
Thanks for reading! : D
Did this article help you? How did you make sure your apps are scalable? Share your experiences below. And if you want help on architecting your apps, you can always reach out to Noorain on LinkedIn.