## What is Scalability? Let's imagine we just built an app that helps users land jobs. We woke up the following day to notice our app was an overnight success. Multiple technology publications are raving about our new software, and we are even trending on Twitter. What a great launch! However, we check our email and notice we received multiple reports of our app crashing. It looks like our app isn't able to handle the extreme increase in requests from all the attention it is garnering. It's time for us to consider _scaling_ our software to manage the dramatic shift in usage. Scalability, also commonly referred to as the process of "scaling", is the ability of a software system (e.g., an application, a database) to increase or decrease performance and cost in response to demand. Thinking about a software's ability to scale is crucial because it leads to lower maintenance costs, increased user experience, and a decrease in overall cost over the system's lifetime. However, unlike our new app, not every software is an overnight success. This raises the question, when do we choose to scale a system? ## The "Right" Time to Scale When considering a software system's performance, the answer to when we should plan to scale a system isn't always trivial. In our previous example, if we had known in advance that our new app would blow up in popularity overnight, our scalability discussion might have started much sooner. Even though scalability is essential and should be considered, not every system needs to be immediately scaled. As a golden rule, when building a system, we want to avoid _premature optimizations_. In software design, premature optimization refers to the process of trying to make software more efficient, when the software is at a stage that is too early to justify the optimization. Creating premature optimizations often leads to time being wasted on code that will likely change later on. A famous quote from Donald Knuth (a notable computer scientist and author) sums up this notion: > We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%. In essence, we want to utilize our resources to design and build our system with some initial optimizations (that critical 3% Donald Knuth mentions). Once completed, we can benchmark specific parts of the system to find what needs to be optimized. Keep in mind, even though we can build a system to handle millions of requests, doesn't mean we should if our system currently only receives hundreds. Returning to the previous example of our app, we made the correct move by not optimizing for millions of users initially. However, now that our application is serving a huge number of requests, let's examine techniques for scaling the software to deal with the influx. ## Scaling Techniques Before we dive into the actual techniques we can use, let's consider what we are actually scaling. Whenever we want to scale software, we are usually referring to scaling a _resource_ (or resources). A resource can be any physical or virtual component of a software system. Some examples of resources include memory, storage, or even a database. Each of these resources can be part of a _resource pool_, a collection of resources that are ready to use. When a resource is used and is no longer needed, it is returned to the pool to be used at a later point. Knowing we are working with resources, we can perform two types of scaling: _Vertical Scaling_ and _Horizontal Scaling_ ### Vertical Scaling Vertical Scaling, also known as "scaling up", increases the power of one particular resource in a resource pool. For example, if we are working on a financial trading platform, our single machine may be running on a 2 core CPU. The platform has started to gain traction and users are reporting slow load speeds of their current assets. We decide that in order to keep up with demand, the machine needs to be upgraded to a 4 core CPU. Here is what it might look like: ** Art-Request - Vertical Scaling of the above example** Some advantages of Vertical Scaling are: * It is easy to implement. * Reduced software costs as no new resources are added. * Decrease in maintenance and operation costs. Some disadvantages of Vertical Scaling are: * A single-point of failure. Since it is typically one machine, we don't have any backups if something goes wrong. * Limited Scaling. Most machines have limits on how many upgrades they can implement. <Assessment id="61bbae4a533bcf001dc50697" /> ### Horizontal Scaling The second main type of scaling is _Horizontal Scaling_, also known as "scaling out". Horizontal Scaling is the process of increasing (or decreasing) the number of instances of a particular resource in a resource pool. For example, let's imagine that we run an on-demand transportation app. Our application runs 3 different services: taxi, water taxi, and food delivery. Our single server can't handle all the requests for all three services, so we decide to scale horizontally by purchasing two more servers so that each service can run on its own specific instance. Here is what it would look like: ** Art-Request - Horizontal Scaling of the above example** Some advantages of Horizontal Scaling are: * Typically cheaper compared to vertical scaling. * Ensures an increase in performance and lighter request load. * Downtime (offline, not available) is reduced. * No single point of failure since an app can be hosted on multiple machines. Some disadvantages of Horizontal Scaling are: * Increase in complexity of maintenance and operation since there are multiple instances of a resource. * Increase in initial costs. <Assessment id="5f7df312d2e7c600129881d5" /> ## Wrap Up When it comes to designing any type of system, it is important to note that a combination of both horizontal and vertical scaling can be implemented. With the different variations of scalability available, it is important to understand the trade-offs between each type so that the system has high performance, is on budget, and doesn't cause an increase of time or cost to maintain. When considering your next scaling solution, consider both types of scaling techniques, and think deeply about the resources that need to be scaled.