I will be continuously updating this and adding sections over the next month
1. Scope of Designing Systems
3 layers
- Architectural: how are macro components are designed
- Logical: business logic, abstractions, algorithmic design, extensibility
- Physical: storage, IOPS, RAM, CPU, backups/restore, scaling policies
2. Mindset
2.1. Extensibility
About making it easy to create changes in your system. Is your low level implementation abstracted enough that the time to migrate to a new system is short? Payment gateway (e.g. Stripe) that your company is using is a good example. If your business pivots to a new area, how hard would it be to change layers in your software to accomodate it? How easy would it be to change your database from SQL to NoSQL? Are your services functioning like an independent business logic/domain like a microservice? How easy is it to break components in your codebase?
2.2. Business reality > engineering
Business prioritizes execution. You wont always have the time to do fancy optimization things to make the best software system like writing mutexes and playing with lock free algorithms, and its absolutely fine to write some spaghetti code when you donthave the luxury of time. Your job exists because of the business.
2.3. Cloud Architecture
Think about input and output, interfaces, storage (how would you store it), configure IOPS/how high. Over provisioned infra costs money and under provisioned could have a bad performance for the user. Capacity planning, how many servers to run, define autoscaling policies. Make design decisions based on response time, incoming traffic and expected response.
2.4. What to define
things that need to be defined
- Scope
- Functional Requirements
- Non-functional requirements
- Critical Questions
- Clarifications
- Bottom up or incremental build?
Think about the most important.
This is basically about the features for the user
The engineering side of things, its basically how the sytem shoukld be implemented, like how should it scale and security.
By critical I am not talking about questions like "why X?" but questions that shape the direction of the project, such as challenging the product design
Because theres lots of ambiguity like technology choices, e.g. noSQL vs SQL
Bottom up is building a set of components together, typically common in larger companies where there is a need for scale immediately. Incremental meanwhile is building an MVP then keep incrementing to improve it.
3. Start small
- What are the building blocks
- Their relationships
- Like if the auth
- Communication layer
- What are their botlenecks
Like does it have an auth service
Like do the services communicate via HTTP or a shared DB
Like do I need to switch to NoSQL for X purpose
4. Analysing Systems
Each of these dimensions defines how a system performs and scales, thusthey become important to analyze
- Database
- in-memory: usually caches
- blob storage: amazon s3, data is a binary long object, retrieved by key/path
- flat file storage: sort of blob storage but you can query them
- server database: MySQL servers
- embedded: DBs that run in the same app
- row based
- columnar
- disk based
- graphDB: to model graph relationships
- time-series: x-axis is time, y-axis is a metric
- relational DB: SQL
- non-relational DB: noSQL
- Caching
- Scaling
- Delegation
- Concurrency
- Communication
The persistent layer, cos you'll need somewhere to store the data
Horizontal/Vertical
Basically about how you delegate work, the most underrated way to squeeze more performance for a system
How to handle many concurrent users
GRPC system? Raw TCP? UDP?