You open up the restaurant with a single chef. There comes a point that A single chef can not handle all the orders.
How would you then manage all the incoming orders then?
If you think like a manager, You'll ask the chef to work harder 😁. And you'll pay them more: Put more money, get more output.
We are Optimizing Processes and Increase Throughput Using the same resource. It's called Vertical Scaling
The other thing you can do is: If the order is a pizza, you can have some ingredients/pieces prepared beforehand so when the order comes, less time is taken.
Preparing beforehand during non-peak hours. It's termed as Pre-processing & Cron Job
Let's say that chef calls in sick one day and you won't have any business that day, So the chef becomes a single point of failure.
What you can do for this kind of emergency:
Hire a backup chef, so, in case if the primary chef doesn't comes, you can employ the backup chef that day.
Keep backups and avoid single point of failure. Backups
Aside from backups, what you can do is hire more primary and backup chefs.
That's buy more resources. It's called Horizontal Scaling.
Let's say you got 3 chefs in the Pizza shop and they have their specialties:
chef 1 and chef 2 got specialty in Pizzas, while chef 3's specialty is in garlic bread.
So, to efficiently get the orders done, when an order comes you can direct/route those orders according to the specialty of a chef.
If the order is of a pizza, you can send it to either chef 1 or 2 according to their availability etc. If you want any change in the recipe of a garlic bread, chef 3 is your man.
Let's make a team around the chefs that we have,
Team1: totals chefs: 3, leading: Chef 3 (Getting all the Garlic Bread order)
Team2: total chefs: 3, leading: Chef 2
Team3: total chefs: 4, leading: Chef 1
(Team 2 and 3 get all the Pizza orders)
Now all the pizza orders are being divided/routed towards the Team 2 and 3, while all the garlic bread orders are going to Team 1.
What you're doing is that you are scaling these three teams at different rates and dividing the responsibilities among them.
What we have here now is a Micro-Services Architecture.
At this point your restaurant/Shop is doing pretty well, able to handle different orders and this business is scale-able to a large extent.
But, What if, there is an electricity outage in this shop? You won't have business that day.
What if you loose licence that day? You won't have business that day.
You don't want your eggs in a single basket, you want a separate shop, in a different place may not have the same number of chefs, but, at-least you have a backup.
Now, we create a new shop SHOP 2. This is very we take complexity to a new level. An advantage of shop 2 is that orders close to its range, can be served by it.
Now if you receive an order, you need to be able to route it that either you want this order to be sent to SHOP 1 or SHOP 2. This is called a Distributed System.(partitioning)
It's more response tolerant and gives a quicker response time.
Now let's say you have a customer who sent its order to the Central Authority(the routing mechanism), but you need some specific requirements to route that order to either SHOP 1 or SHOP 2. The parameter can be the delivery time.
Let's say, if you send the order to the SHOP 1, it takes 1.5 hours for it to deliver to the customer, as it's a popular shop. But the SHOP 2 only takes 1 hour to deliver the order.
So, the central authority should route the order to the SHOP 2, and as long as the Central Mechanism is getting real time updates, It can make smart business decisions, which means, more money.
This central Mechanism is called Load Balancer.
At this point, The System is:
Scalable and Fault Tolerant.
How to make it Future Proof?(Extensibility).
You have a delivery agent and a pizza shop, and they have nothing in common, The delivery agent's concern is to only deliver the order as quickly as possible to the customer, while the shop's concern is to prepare the order as quickly as possible, it does not cares who is going to pick the order up.
We can see the separation in responsibilities. It's called Decoupling the System. (Separating out the concerns).
Let's say, SHOP 1's oven becomes faulty or the Delivery agent's bike becomes faulty. You need all the events(logs) happening in present or that have already happened. It's called Logging and Metrics.
The Most Important Point, as a back-end engineer, you need to make your system as extensible as possible, you do not need to rewrite your code again and again to serve a different purpose.
For example, Delivery Agent doesn't need to know that it's delivery a Pizza, it could be a burger tomorrow. Extensible
Finally, Now we are able to scale our business.
Let's recap and see what are the High level problems that we faced and how we resolved them:
Following is know as HIGH LEVEL DESIGN
LOW LEVEL DESIGN has a lot to do with how you code, making classes, objects, functions, signature.