System Design
Fundamentals
Scalability of Application

Scalability of Application

In today's fast-paced digital world, applications must perform reliably and efficiently, even under varying workloads. Optimizing application performance is crucial to keeping clients satisfied. However, as demand grows, so do challenges. This article explores how to design scalable systems to handle increasing workloads without sacrificing performance or reliability.

Current System Performance

  • Request-Response Latency:
    • Average: 150 ms per request
    • Tail Latency: 350 ms
  • Throughput: 1000 concurrent requests per second

The system performs well during normal hours, but peak traffic causes the application to fail or shut down. To address this, scaling the system is essential.


What is Scaling in System Design?

Scaling in system design refers to the ability of a system to handle increased demand while maintaining or improving its performance. It ensures that applications can grow seamlessly alongside user traffic and data loads.

Key goals of scaling:

  • Adapt to changing workloads.
  • Maintain system responsiveness and reliability.
  • Prevent downtime or degraded performance during traffic spikes.

Scaling is a foundational concept in cloud and distributed applications, where workloads often vary unpredictably.


Performance vs. Scalability

Performance

Performance focuses on ensuring an application operates efficiently under its current load. It involves:

  • Low Latency: Ensuring fast response times.
  • High Throughput: Handling large numbers of requests efficiently.
    • Concurrency:
      • Single Machine: Uses multithreading for efficient operations.
      • Multi-Machine: Combines multithreading and distributed processing.
    • Capacity: Utilizing system resources effectively.

Scalability

Scalability is a subset of performance, emphasizing a system's ability to grow and handle larger workloads by:

  • Increasing throughput by adding resources.
  • Adjusting capacity both up (for increased demand) and down (to save costs).

Types of Scaling

To achieve scalability, there are two primary approaches:

** Vertical Scaling (Scaling Up)**

Vertical scaling, also known as scaling up or scaling vertically, refers to the process of increasing the capacity of a single server or resource in order to handle a larger load or improve performance. This is typically achieved by adding more CPU, memory, storage, or other resources to a single machine. Vertical scaling involves increasing the capacity of a single machine. This can be achieved by adding more:

  • CPU power
  • Memory (RAM)
  • Storage
  • Network bandwidth

Advantages / Pros of Vertical Scaling

  • Simplicity: Minimal architectural changes are required (It is often simpler to implement, requiring minimal changes to the existing architecture or application).
  • Performance: Improved performance for individual tasks (Vertical scaling can lead to improved performance for individual tasks since the resources available to a single machine are increased).
  • Cost-Effective: Suitable for applications with predictable workloads (For applications with relatively small or predictable workloads, vertical scaling can be cost-effective).

How to Achieve Vertical Scaling

  • Add More CPU: Increase the processing power by adding more powerful CPUs or additional processors to the existing hardware.
  • Add More Memory (RAM): Upgrade the amount of random access memory (RAM) to allow the server to handle more concurrent processes and data.
  • Increase Storage Capacity: Add more storage space, either by expanding existing drives or adding new ones, to accommodate growing data needs.
  • Upgrade to a More Powerful Server: Replace the current server with a more powerful one that can handle increased workloads.

Why Not Vertical Scaling? What are The Problems We Still Have?

limitation: There is a practical cap on how much a single machine can be upgraded. Once the maximum capacity of the server is reached—whether in terms of CPU, memory, or storage—further enhancements may necessitate a more complex and costly transition to a different architecture or hardware setup.

Challenges of Vertical Scaling / Cons of Vertical Scaling

  • Limited Scalability: There is a practical limit to how much a single machine can be scaled vertically. Once the maximum capacity is reached, further scaling may require a more complex and expensive approach.
  • Downtime: Increasing resources often requires shutting down the server, which can result in downtime.
  • Higher Costs for High-Performance Needs: For very high-performance requirements, the cost of acquiring extremely powerful hardware may become prohibitive.
  • Single Point of Failure: If the single server fails, it can impact the entire system. Redundancy and failover mechanisms are crucial to mitigate this risk.

When to Use Vertical Scaling

  • Vertical scaling is suitable when the workload is well-suited to a single, powerful machine.
  • It's a viable option for applications with predictable resource needs.
  • In scenarios where simplicity and quick upgrades are crucial.

** Horizontal Scaling (Scaling Out)**

Horizontal scaling, also known as scaling out, involves adding more machines or nodes or instance or server to a system to distribute the load and increase its overall capacity. Instead of making a single machine more powerful, horizontal scaling adds more machines to share the workload.

Advantages / Pros of Horizontal Scaling

  • Improved Scalability: Horizontal scaling allows a system to handle increased loads by adding more machines, providing a more flexible and scalable solution.
  • Cost-Effective: Horizontal scaling can be more cost-effective than vertical scaling, especially with the use of commodity hardware or cloud services where resources can be provisioned on demand.
  • Redundancy and Fault Tolerance: With multiple machines, the system becomes more resilient to failures. If one machine goes down, others can continue to handle requests.
  • Easy to Add Capacity: Adding more machines to a cluster is often a straightforward process and can be done without significant downtime.

How to Achieve Horizontal Scaling

  • Load Balancing: Distribute incoming requests across multiple servers to ensure even utilization and prevent overloading a single server. Load balancers help achieve this by intelligently routing traffic.
  • Clustering: Create a cluster of machines that work together to handle requests. Clustering involves connecting multiple servers in a way that they act as a single system.
  • Containerization: Use containerization technologies like Docker or Kubernetes to deploy and manage applications in lightweight, portable containers. This facilitates the deployment of applications across multiple machines.
  • Auto-Scaling: Implement automated processes that dynamically adjust the number of instances based on demand. Cloud services often provide auto-scaling features to add or remove instances as needed.

Monolithic Architecture: An Anti-Pattern for Scalability

Issues with Monolithic Architecture

  • Two Different IP Addresses: This can lead to confusion and increased complexity in routing requests.
  • Two Different Databases: Managing multiple databases can complicate data consistency and integrity.
  • Two Different Storage Solutions: Using different storage systems can create challenges in data management and retrieval.
  • Client Decision-Making: Clients may struggle to determine which route to take for their requests, leading to inefficiencies.

Solutions

  • Use a Load Balancer: Implementing a load balancer can help distribute traffic evenly across servers, improving performance and reliability.
  • Utilize a Single Database: Adopt a stateful service with a single database that incorporates:
    • Replica Sets: For high availability and redundancy.
    • Sharding: To enhance scalability by distributing data across multiple servers.
    • Indexing: To improve query performance and speed up data retrieval.
    • Partitioning: To manage large datasets effectively by dividing them into smaller, more manageable pieces.
  • Implement a Unified Storage Solution: Use a single stateful service for storage to streamline data management and access.

Challenges of Horizontal Scaling / Cons of Horizontal Scaling

  • Complexity: Managing and coordinating multiple instances and ensuring they work seamlessly together can introduce complexity, especially in distributed systems.
  • Inter-Node Communication: In some cases, horizontal scaling may require efficient communication between nodes, which can be challenging to implement and maintain.
  • Data Consistency: Maintaining data consistency across multiple nodes can be complex, especially in distributed databases. Ensuring all nodes have the latest data can be a challenge.
  • Not Suitable for All Workloads: While horizontal scaling is effective for many scenarios, some applications may not benefit from it, especially those with high inter-process communication requirements.

When to Use Horizontal Scaling

  • Horizontal scaling is suitable for applications with dynamic or unpredictable workloads.
  • It's effective for cloud-based architectures where resources can be provisioned and deprovisioned on demand.
  • When redundancy, fault tolerance, and improved scalability are critical.

Summary of Vertical vs. Horizontal Scaling

FeatureVertical Scaling (Scaling Up)Horizontal Scaling (Scaling Out)
ApproachIncrease capacity of a single machineAdd more machines to distribute load
CostHigher for high-end hardwareLower with commodity hardware
ScalabilityLimited by hardware constraintsVirtually unlimited (add more machines)
DowntimeOften requires downtimeCan scale with minimal or no downtime
Fault ToleranceSingle point of failureRedundant and fault-tolerant
Use CasesPredictable workloads, smaller systemsDynamic, cloud-based, and distributed apps

Scalability Principles

One component is not responsible for all the work. If one component is responsible for all the work it is called Monolithic. Monolithic is an anti-pattern for scalability. Decentralization in scalability refers to the distribution of responsibilities and functions across multiple components or nodes within a system rather than centralizing them in a single entity. In a decentralized architecture, different parts of the system can operate independently, reducing bottlenecks and improving overall scalability.


Decentralization

Decentralization ensures that no single component is responsible for handling all tasks, which eliminates bottlenecks and makes systems more scalable and fault-tolerant.

Key Aspects of Decentralization

  • Distribution of Components
    • Break down monolithic architectures into smaller, independent services or components.
    • Each component can operate autonomously, improving fault tolerance.
  • Data Distribution
    • Distribute data across multiple nodes using techniques like partitioning or replication.
    • Prevent a single node from becoming a performance bottleneck.
  • Load Distribution
    • Distribute workloads across multiple nodes or instances using load balancers.
    • Ensure no single component bears the entire burden of incoming requests.

Advantages of Decentralization

  • Improved Scalability
    Systems can scale horizontally by adding more nodes to distribute the workload efficiently.
  • Fault Tolerance
    Failures in one component don’t bring down the entire system.
  • Flexibility
    Decentralized architectures are more flexible and adaptable to changes in workload. Adding or removing nodes can be done without disrupting the entire system.

Independence

Independence in scalability refers to the ability of components or modules within a system to operate autonomously without strong dependencies on each other. Each component can function independently, making it easier to develop, deploy, and scale.

Key Aspects of Independence

  • Loose Coupling
    • Changes in one component don’t significantly impact others.
    • Enables flexibility and easier modifications.
  • Isolation of Concerns
    • Each component focuses on a specific functionality, making the system modular.
  • Service-Oriented Architecture (SOA)
    • Components act as independent services that interact through well-defined APIs.

Advantages of Independence

  • Easier Maintenance
    Independent components are easier to maintain and update.
  • Scalability
    Individual components can scale without affecting the rest of the system.
  • Parallel Development
    Teams can work on separate components simultaneously, reducing development time.

Load Balancer

A load balancer is a device or software application that distributes incoming network traffic across multiple servers or resources to ensure optimal utilization, prevent overload on any single server, and enhance the availability and reliability of a system or application. Load balancers are commonly used to manage traffic for web servers, databases, and other types of server farms.

Key Functions of Load Balancers

  • Single IP Address
    • Client don't need to know about IP addresses of all servers(instances). Load balancer will keep track of it and expose a single IP address for client.
  • Traffic Distribution
    • Load balancers evenly distribute incoming network traffic, such as web requests, across multiple servers. This ensures that no single server bears the entire load and prevents any server from becoming a performance bottleneck.
  • Load Distribution
    • By distributing the workload across multiple servers, load balancers optimize resource utilization, preventing overloading on specific servers. This leads to improved performance and responsiveness of the overall system.
  • Scalability
    • Load balancers support horizontal scalability by easily integrating additional servers into the system. This enables the infrastructure to grow or shrink dynamically based on demand, enhancing the system's overall scalability.
  • Health Monitoring
    • Load balancers continually monitor the health and performance of individual servers. If a server becomes unavailable or experiences degraded performance, the load balancer can redirect traffic to healthier servers to maintain system stability.
  • Session Persistence
    • Some load balancers support session persistence, ensuring that requests from the same client are consistently directed to the same server. This is essential for applications that require maintaining session state, such as in e-commerce websites.

Use Cases of Load Balancers

  • Web Servers and Applications
    • Load balancers distribute incoming web requests across multiple servers, ensuring even utilization and preventing any single server from becoming a bottleneck. This is common in websites, online applications, and e-commerce platforms.
  • Application Servers in Multi-Tier Architectures
    • In multi-tier architectures, load balancers distribute traffic among application servers, helping to balance the load and improve the overall performance of the application
  • Database Servers
    • Load balancers can be used to distribute read queries among multiple database servers, optimizing the use of database resources and improving query response times.
  • Content Delivery Networks (CDN)
    • CDNS use load balancers to distribute content to edge servers located in different geographical locations. This reduces latency and improves the speed of content delivery for users around the world.
  • File Servers and Storage Clusters
    • Load balancers distribute file requests across multiple file servers or storage clusters, preventing any single server from becoming overwhelmed and ensuring efficient data retrieval.
  • Mail Servers (SMTP, IMAP)
    • Load balancers distribute email traffic across multiple mail servers, ensuring efficient handling of incoming and outgoing emails and preventing any single server from being overwhelmed.

Hardware-Based vs. Software-Based Load Balancers

FeatureHardware-Based Load BalancerSoftware-Based Load Balancer
OSI LayersHandles both Layer 4 (L4) and Layer 7 (L7)Primarily operates at Layer 7 (L7)
ExamplesF5 Big-IP SeriesNGINX, HAProxy
Connections300M+~225K
ThroughputUp to 320 Gbps~70 Gbps
Requests per Second (RPS)10M RPS~3M RPS
Key FeaturesHighly scalable, supports high throughputContent-based routing, SSL termination

Reverse Proxy

A reverse proxy is a server that sits between client devices and a web server, forwarding client requests to the web server and returning the server's responses to clients. Unlike a forward proxy that sits between client devices and the internet, a reverse proxy is positioned on the server side to handle requests on behalf of the server. Reverse proxies provide several benefits, including improved security, load distribution, and caching.

Key Functions of Reverse Proxy

  • Request Forwarding
    • Reverse proxies forward client requests to backend servers, acting as an intermediary that relays requests on behalf of the clients.
  • Load Distribution
    • Similar to load balancers, reverse proxies distribute incoming requests across multiple backend servers to optimize resource utilization and improve the overall performance of the system.
  • SSL Termination
    • Reverse proxies can handle SSL/TLS encryption and decryption, relieving backend servers of the resource-intensive task of managing secure connections. This enhances server performance and simplifies SSL certificate management.
  • Caching
    • Reverse proxies can cache static content, such as images, CSS files, and other assets, to reduce the load on backend servers and improve response times for frequently requested content.
  • Compression
    • Reverse proxies can compress content before sending it to clients, reducing bandwidth usage and improving the overall speed of content delivery.
  • Security
    • Acting as a barrier between clients and backend servers, reverse proxies enhance security by concealing the internal server structure, preventing direct access to backend servers, and mitigating certain types of attacks.
  • Web Acceleration
    • Optimizes content delivery and reduces latency.

Use Cases of Reverse Proxy

  • Load balancing and caching.
  • SSL termination and offloading.
  • Security enhancements by hiding backend infrastructure.
  • Compression and acceleration of web content delivery.

Load Balancer vs. Reverse Proxy

FeatureLoad BalancerReverse Proxy
LocationBetween clients and multiple serversIn front of backend servers
FunctionalityPrimarily focuses on load distribution.Manages communication between clients and servers, handles SSL termination, caching, and security.
Use CasesDistributing traffic for performance and availability.Caching, SSL termination, security, and serving as a barrier between clients and servers.
SSL/TLS HandlingCan handle SSL/TLS offloading for multiple servers.Performs SSL/TLS termination, offloading encryption/decryption from backend servers.
CachingPrimarily focused on load distribution, may have limited caching capabilities.Often incorporates caching to store and serve static content, reducing the load on backend servers.
Client CommunicationDirects client requests to appropriate backend servers.Communicates with clients on behalf of backend servers, protecting servers from direct exposure to the internet.
TypeSoftware and HardwareSoftware

API Gateway

An API Gateway is a server that acts as an intermediary between an application and a set of microservices or APIs (Application Programming Interfaces). It serves as a single entry point for multiple APIs, handling tasks such as request routing, composition, security, and protocol translation. API Gateways are a crucial component in modern software architectures, providing a centralized point for managing and securing API interactions.

Features of API Gateway

  • Request Routing: API Gateways route incoming requests from clients to the appropriate backend services or APIs based on predefined rules and configurations.
  • Authentication and Authorization: Ensures that only authorized users or applications can access the APIs by implementing authentication mechanisms such as API keys, OAuth, or other authentication protocols.
  • Request and Response Transformation: Modifies or transforms incoming requests and outgoing responses to ensure compatibility between client and server, such as converting data formats or handling versioning.
  • Rate Limiting and Throttling: Implements controls to limit the number of requests a client can make within a specified time frame, preventing abuse and ensuring fair usage of API resources.
  • Logging and Analytics: Captures detailed logs of API requests and responses, providing insights into API usage, performance, and potential issues. Analytics tools help in monitoring and optimizing API performance.
  • Caching: Stores and serves cached responses for frequently requested data, reducing the load on backend servers and improving response times for clients.
  • Security: Enforces security measures such as HTTPS, SSL/TLS termination, and protection against common security threats like SQL injection or cross-site scripting.
  • Monitoring and Health Checks: Monitors the health and availability of backend services, performing health checks and dynamically adjusting routing based on the status of the services.
  • API Versioning: Supports versioning of APIs, allowing clients to specify the desired version and ensuring backward compatibility as APIs evolve.
  • Distributed Tracing: Enables the tracking of requests across multiple microservices, providing insights into the flow of requests and helping identify performance bottlenecks.

Use Cases of API Gateway

  • API Management: Centralizes the management of APIs, making it easier to create, deploy, version, and retire APIs.
  • Security and Access Control: Enforces security policies, authenticates users, and ensures that only authorized clients can access specific APIs.
  • Request Transformation and Composition: Modifies or combines API requests to suit backend service expectations, optimizing the communication between clients and microservices.
  • Distributed Microservices Architecture: Serves as the entry point for client interactions with microservices, handling the complexity of multiple services and ensuring a unified API surface.
  • Legacy System Integration: Bridges the gap between modern applications and legacy systems, allowing newer applications to interact with older services through a standardized API.
  • Cross-Origin Resource Sharing (CORS): Facilitates secure cross-origin communication by enforcing CORS policies, allowing web applications to securely make requests to APIs hosted on different domains.
  • API Versioning and Evolution: Manages API versioning, ensuring backward compatibility and smooth transitions as APIs evolve over time.
  • Ingress Controller for Kubernetes: An API Gateway can serve as an Ingress Controller in Kubernetes, managing external access to services, handling SSL termination, and performing request routing based on domain
  • Third-Party Integration: Facilitates integration with third-party APIs and services, managing API keys, authentication, and data translation to ensure seamless communication between different services.
  • Microservices Communication: Serves as a central point for communication between microservices within an architecture, managing the complexities of service discovery, load balancing, and fault tolerance.

Popular API Gateways

  • Kong
  • Apache APISIX
  • Tyk
  • Ocelot
  • Amazon API Gateway
  • Azure API Management

Replication

Replication in system design refers to the process of creating and maintaining multiple copies of data, components, or systems to improve reliability, fault tolerance, and performance. The purpose of replication is to ensure that a system remains available and functional even in the face of failures, outages, or increased demand.

Key Concepts

  • Data Replication
    • Maintains copies of data across multiple servers or locations to improve availability and reduce latency.
  • Component Replication
    • Creates multiple instances of components or services to handle more traffic and provide redundancy.

Types of Replication

Stateless Replication

  • Stateless replication involves replicating the functionality of a system or service without necessarily replicating its state. Each replica operates independently, and there is no shared state between replicas.
  • Key Characteristics:
    • No Shared State: Each replica manages its own state.
    • Scalability: Easier to scale horizontally.
    • Simplicity: Minimal synchronization required.
    • Use Cases:
      • Load balancing in web servers.
      • Content Delivery Networks (CDNs).
      • Stateless microservices.

Stateful Replication

  • Stateful replication involves replicating both the data and the state of a system. In stateful replication, each instance or replica maintains the current state, and changes made to one replica are reflected in others.
  • Key Characteristics:
    • Shared State: All replicas have up-to-date copies of data.
    • Consistency: Critical for distributed databases and applications.
    • Challenges: Requires complex synchronization and coordination.
    • Use Cases:
      • Distributed databases.
      • Distributed file systems.
      • Applications needing consistent state across replicas.

Stateful Replication in Practice

Web Applications

  • Challenges:
    • Not ideal for scalability and reliability.
    • Low latency but difficult to scale horizontally.
  • Solutions:
    • Use sticky sessions or session clustering for session management.

Databases

  • Master-Slave (Primary-Secondary):
    • Asynchronous:
      • Low latency writes.
      • Eventual consistency.
      • Used for read replicas.
    • Synchronous:
      • Ensures consistency.
      • High latency for writes.
      • Used for backups.
  • Peer-to-Peer:
    • Ensures high availability.
    • Can lead to write conflicts.
    • Suitable for multi-regional services.

Final Thoughts

Scalability is a critical aspect of modern application design. By implementing tools like API Gateways and replication strategies, developers can ensure their systems are resilient, high-performing, and capable of handling dynamic workloads.

With principles like decentralization, independence, and robust replication techniques, systems can grow seamlessly while maintaining reliability and user satisfaction. Whether dealing with stateless microservices or stateful applications, scalable designs are the foundation of successful software in today’s cloud-driven world.