Perfectionism is always going to be your biggest enemy. We, as engineers, like to solve tough challenges, and sometimes we find ourselves trying to design the best possible system. If you’ve ever found yourself deep into a really complex design, you’re not alone.
But this generally hurts more than it helps. There have been many times I found myself designing how to scale a system to hundreds of millions of users before even having just one. The excitement to build a state-of-the-art system that’ll scale seamlessly is really charming. But most of the time, it is unnecessary.
Over engineering is a really common problem. This is why you need to get used to starting small. Always think about MVP(Minimum viable product) and what’s really needed to get the job done. Start from there and keep building as the need for it grows. If you find yourself solving problems that don’t exist yet, stop yourself and remember to focus on the MVP.
How does this translate to a real example?
Let’s say you’re trying to build a server for a chatting application. Now you need to decide;
- Which database to use?
- It needs to run on multiple servers to support hundreds of millions of users.
- It needs to have replication to not lose the data if one of the servers dies.
- It needs to have transaction support to make sure you can always return the latest messages.
- Do we need a queuing system to make sure all messages can be kept in a queue until they’re written to the database? Likely.
- Containerize your code to make it runnable on multiple servers.
- Implement a multi-threaded code to maximize CPU efficiency.
- Implement a live connection handler (For ex. web socket), so the clients can sync the changes without having to ask the server again and again.
- Pick or design a load balancer.
- Implement a notification service to notify recipients.
- This list goes on and on and on…
If you are working on a service that’s already used by millions of users, then you do need to consider all of these things. But how many of this you actually need to start with?
- Any database would be able to take a few thousand to a few millions of calls per second on one fast machine.
- You can setup a daily backup job.
- Write a simple one threaded application to handle everything that’ll live in the same machine as the database.
That’s it! The first messaging system I’ve described above has so many components and likely you need a few to a dozen engineers working on it for a few months to a year to build. The second one would take around a week or two to implement.
Let’s say you’ve invested all of this time into this project, and in the end, you realize only a thousand people signed up for your service. Can you imagine the amount of time you’ve wasted? Time is the most valuable currency in everyone’s life and especially as an engineer, you could have built the next million/billion dollar app in that time instead of making sure you have the best messaging platform in the world that no one uses.
What’s the best part? It’s never too late to update the system once it starts picking up user traffic. You can put your focus into the most important parts once needed. If you notice database is becoming a bottleneck, you can solve that. If it’s the latency between the client and the server, you can solve that. This will always keep you focused on what your customers actually care about. And it’s a lot easier to justify a bigger investment. If it’s your own company, you can hire many engineers to fix the problems that matter once you have the users. If you are working for someone else, now you can ask for more engineers to help you.
I know… Building complex systems is fun. And you get to feel like the creator of the future. But do you really want to build a future no one lives in it? Or would you rather get people there first and then make it amazing?
What’s my favorite setup for side projects after years and years of designing things to scale to billions of people? I simply setup a NodeJs server with Mysql on it. I try to avoid too many relational queries and treat Mysql as more like a No-Sql database. I put all my time into designing something users will love. Then if you need to, it’d take almost no time to compartmentalize and start extracting each piece to a service.
Be careful with perfectionism. Do not over engineer things. Always focus on MVP and get it out of the door. Then listen to your users/customers. They’ll tell you what they value the most.