System design introduction
Ever built a sandcastle? You start simple, maybe a tower and a moat. It's quick and fun, perfect for a solo project. But what if you want to build something bigger, like a grand castle with intricate bridges and hidden chambers? That's where planning comes in, like drawing blueprints and figuring out how everything connects.
Software development is similar. At small startups, features get tossed around in team meetings, and engineers dive right in, building things fast to test with customers. Speed is king, and million-user scalability isn't a day-one concern.
But imagine building a software castle for millions. Every new feature becomes a potential drawbridge – impacting performance, cost, and even the whole system's stability. That's where system design steps in, the blueprint for your software masterpiece.
Think of it as taking a moment before grabbing the shovel. We analyze, plan, and architect the best way to build a robust, scalable system that can weather the storm of millions of users, just like those sturdy castle walls.
This series will unravel the mysteries of system design, making it clear even for engineers building sandcastles. We'll explore different design approaches, tools, and best practices to ensure your software stands strong, no matter how many visitors come knocking.
What's the usual way of making software?
If your company is just starting and has only a few engineers, you might simply have a team meeting to decide on a feature or product to develop. The engineer then starts working on it. For early startups, speed is crucial because they want to release products quickly and get feedback from customers. They don't have to create software that can handle millions of users on day one.
On the other hand, if you work for a well-established company with millions of customers or a website with millions of visitors, each time you add a new feature, you, as an engineer, must carefully analyze its impact. This involves checking how it affects the existing system, the cost, time, and other factors. This careful analysis is called designing a system.
If you're a Software Development Engineer (SDE-1) in a team, you'll likely handle well-defined projects or straightforward tasks. As you move up to SDE-2 and beyond, the projects become less detailed and more complex and ambiguous. The higher your seniority, the fewer details you receive, and the more challenging the assignments become.
In mid to large size companies, the development process typically follows these steps:
1. Getting the Assignment:
- The software engineer receives the project assignment, outlining the task at hand.
2. Gathering Information:
- They meet with stakeholders to fully understand the system's needs and goals.
3. Mapping the Blueprint:
- The engineer creates a design document, acting as a detailed plan for the project's structure and functionality.
4. Gathering Feedback:
- The design document is shared with the team for review and feedback.
- It might undergo revisions based on suggestions to ensure it's aligned with overall goals.
5. Writing the Code:
- Once the design is approved, the engineer starts translating it into code.
6. Reviewing the Code:
- The code is then sent for review by other engineers, who can easily understand it thanks to their involvement in the design review.
7. Final Approval and Deployment:
- After the code passes review, it's ready for deployment. This involves making it available to users.
System Design Document
Design Document Structure: There are different ways to structure a design document based on the project's complexity. Here I'm presenting some of the sections of a typical design document.
- Requirement Gathering and Clarifications
- Constraints
- Functional and Non-functional Requirements
- Not in Scope
- Back-of-the-Envelope Calculations
- Scale Estimations
- High-Level Design
- Low-Level Design (LLD)
- API
- Data Model
- Proposed Design
- Deep Dive (Trade-offs and Failures)
- Core Concept
- Data Structure or Algorithm
- Storage or Data Model
- Non-Functional Justifications
- Monitoring and Alerting
- Open Questions
- Conclusions
This serves as a brief overview of system design. Stay tuned for more in-depth discussions on each of these sections in our upcoming articles.