This piece was written by Fahim ul Haq, a former systems engineer at Microsoft & Facebook, and the CEO of Educative. Check out more from Fahim on fahim.dev
We live in a world where everything is dependent on devices that are always connected, around the clock. Our wristwatches, lighting systems, and smart refrigerators are connected to the cloud – and then sync to a mobile app on our phones. Just by reading this article, you're relying on the Internet through a WiFi or cellular network. All of these services that support us each day are possible because of distributed systems.
A distributed system is a system with components located on various networked devices. When designed well, a distributed system is scalable and can adapt to support more users and functionalities, while remaining reliable and available at all hours.
System Design is the art of designing distributed systems.
Today, nearly every application is entangled with a distributed system. With that, System Design is becoming a non-negotiable skill set for proficient developers.
I've conducted System Design Interviews for hundreds of candidates between my time at Educative, Microsoft, and Facebook. Today, you can rarely advance into a senior developer role without passing a System Design Interview. But in reality, every developer, regardless of their level, should learn System Design. And they shouldn't wait for the System Design Interview to learn it.
All of today's development roles rely on distributed systems. So, no matter what type of developer you are, learning System Design will improve the quality of your work. So, let's talk about how you can gain an edge by learning System Design.
I worked on distributed systems at Microsoft and Facebook for eight years, but my university program didn't prepare me to work with distributed systems. I mostly learned about distributed systems and their design on the job and by reading white papers.
Before 2010 - when most of today’s software engineering managers were just starting, and when most of today’s leaders and instructors were managers - distributed systems were rarely discussed outside of Amazon, Google, and Microsoft. At that time, most applications were desktop applications that were not talking to the cloud. But as we know, technology changes quickly, and now virtually every application is becoming increasingly dependent on distributed systems. As this trend continues into the future, we can expect even more applications to interact with distributed systems. With this in mind, a well-informed developer should know about distributed systems.
In the early days of distributed systems, engineers were navigating through the dark to build distributed systems from scratch.
As part of the pre-launch team for Microsoft Azure, I was lucky to be among this first generation of system engineers. We faced several challenges, failures, and unknowns in implementation in this uncharted territory. But because of the findings of this generation, we now have the discipline of System Design.
Through System Design, we can use design patterns and reusable components (or building blocks) to help us build massive scalable systems.
If you're a committed developer, there's no good reason to delay understanding the workings of the greater system to which you're contributing.
In an evergreen quote by the late Danny Thorpe, the importance of understanding the greater system is clear:
“Programming without an overall architecture or design in mind is like exploring a cave with only a flashlight: You don’t know where you’ve been, you don’t know where you’re going, and you don’t know quite where you are.” – Danny Thorpe
System Design is the overall architecture for distributed systems. And not knowing System Design as a programmer in a distributed world is analogous to the difference between a line cook and head chef of a restaurant. As a head chef, you understand the greater system. You know how each and every staff member operates and relies on one another. You know each of their expected duties, tools, and methods. You know who comes in as backup when one person can't fulfill a duty. And without this perspective, you're a line cook. While you may know your particular tasks and methods well, you lack the vision of the big picture to which you're contributing.
It's clear why you need to know System Design if you want to advance into senior or leadership roles. But even if advancing into a higher role isn't important to you, you should want to know about System Design, because you're a key player within its architecture.
Like most leaders, the main quality I look for in developers is a drive to learn and know about the world to which they're contributing.
If you want to be a great developer, you need to have a drive to fill your knowledge gaps. A great developer is curious to a fault.
As a developer, your job will eventually require you to build a distributed system. If not, your application will interact with and rely on distributed systems to build your intended experience.
For instance, if you're a mobile app developer, your application is going to rely on several distributed systems just to get started.
Consider the example of designing a rideshare service like Uber. If you're building Uber today, you're probably leveraging several different services at once, including but not limited to:
- Trillio to send text messages
- Stripe to process payments
- Google maps to get directions
- Yelp to locate users in proximity
Not only are you leveraging other systems, but you're building your own distributed system with your mobile application. Your rideshare app would also use several components of System Design, including:
- Load balancers to divvy out read/write requests among the app's services
- Databases to store metadata
- A cache to store commonly requested data
Distributed systems are also crucial to game development. Many of today's most popular titles are cloud-based games and rely on scalability to support thousands of users at once. This ranges from mobile-first gacha games like Fate Grand Order and social experiences like Pokémon Go, to AAA titles like League of Legends and Halo Multiplayer.
Distributed systems are crucial to upholding the speed and reliability that is required in gaming, and building a multiplayer game is one of the most difficult distributed systems problems. Here, latency (or speed) is critical – a latency or delay greater than 50ms/100ms will break immersion for your game player. Not only that, but your servers need to support an immense amount of users at once without sacrificing too much speed.
If you're a front-end developer, your work never happens in isolation. Even when you're rendering a web page, you're interacting with several different distributed systems through APIs.
Let's consider Google's home page. This is the simplest homepage to build. It's just a search box with a logo. But between the first character you type in a search box and the search results you get after hitting
Enter, the browser is interacting with hundreds of thousands of servers through distributed systems. In a matter of seconds, the following occurs:
- The user types into the search box, and each character is fed into a typeahead system through an API. With each added character, the typeahead changes its output to home in on the user's intention within milliseconds.
- The user presses
Enter, and a lot of different systems kick in. A search query goes to an index to find relevant web pages. Another search query goes to YouTube to look for relevant videos. If the search term matches the name of a movie, restaurant, or book, it renders an entirely different experience through more specialized systems. On top of this, there are ad services that render a few links above your search results, based on the term you searched.
As a front-end engineer, you should be curious enough to know how all the magic is working, and to know the different parts of the system you're interacting with to create the experience you're trying to build.
No matter what type of engineer you are, knowing System Design will make you more well-rounded, and get you more success in your career. If you know what's going on under the hood, you're more likely to build solutions that are better suited to the needs and limitations of your system.
That being said, the importance of knowing System Design is not exclusive to developers.
Anyone working with modern technical products should be familiar with System Design concepts in order to speak the same language with stakeholders and technical teams. This includes Support Engineers, Technical Product Managers, and of course, Engineering Managers.
From my experience as an interviewer, the biggest pitfall of candidates was a lack in their depth of knowledge. This isn't surprising considering the fact that many developers begin learning System Design specifically for the System Design Interview. There's nothing entirely wrong with this. However, merely learning how to beat the interview won't give you the deep knowledge to actually apply it in the real world. So, you should really start learning System Design on your own, far before the System Design Interview.
Don't learn the System Design Interview. Learn System Design.
You should start learning System Design as early as you can in your career – even before you start your first job. If you're a beginner developer or you're currently learning programming, knowing System Design will give you an edge.
If you're a mid-level engineer, don't delay learning System Design. If you don't know System Design and you're interviewing for senior roles, you could be offered lower positions than you'd applied for because of your knowledge gap.
To be well-rounded and understand how to work with other parts of systems, every developer can only benefit from learning System Design fundamentals.
Over the years, our courses have helped thousands of software engineers beat the System Design Interview. But as the industry has grown, Educative has had to grow with it. That's why we created a new System Design course.
We don't want you to just land the next job – we want you to truly master System Design.
Our course, Grokking Modern System Design for Software Engineers & Managers, covers the fundamentals of System Design for engineers at any level. You'll understand the fundamental concepts, then implement them through several System Design problems. This course also includes a fascinating reflection on the lessons we can learn from failures in System Design.
Before learning System Design, it helps to have some background in computing fundamentals, operating systems, and distributed systems. If you don't have familiarity with these topics yet, one of our courses can help you get up to speed:
- Grokking Computer Networking for Software Engineers
- Operating Systems: Virtualization, Concurrency & Persistence
- Distributed Systems for Practitioners
- Top 10 system design interview questions for software engineers
- How to Design a Web Application: Software Architecture 101
- How to prepare for the System Design Interview in 2022
Why do you personally want to learn System Design? Was this article helpful? Let us know in the comments below!