Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 95

Designing System Architectures: Services & Components

Recommended resources

Hello! Welcome to the final module of our course, "CI/CD & System Design Interview Practice."

In our previous lessons, we've gone deep into the implementation details of building, testing, and deploying robust Spring Boot applications. You've mastered everything from crafting CI/CD pipelines to writing comprehensive API tests. Now, we pivot from the "how" of implementation to the "what" and "why" of architecture. This is a critical skill set for the senior roles you're targeting.

Today's lesson addresses the learning outcome: Outline a high-level architecture for a system design prompt (e.g., TinyURL), defining service boundaries and core components. System design questions are not about writing code; they are structured conversations to assess your ability to handle ambiguity, think at scale, and make reasoned trade-offs. We will learn a framework for navigating these interviews and then apply it to a classic problem.

1. The Anatomy of a System Design Interview

Before diving into a specific problem, it's essential to understand the "meta-game" of the interview itself. Interviewers are looking for a structured thought process, not a single "correct" answer. A typical 45-60 minute session follows a predictable pattern.

System Design Interview Cheat Sheet: 12 Templates ...

The article 'System Design Interview Cheat Sheet' provides an excellent overview of what interviewers expect and the standard format of these interviews. Understanding this structure is the first step to success.

Please read the section titled 'Standard Interview Format'. It breaks down the interview into four key steps. Internalize these steps, as we will be following them for the rest of the lesson.

As you've just read, the process can be broken down into four essential stages:

  1. Problem Clarification: Understand functional and non-functional requirements. Ask questions to scope the problem.
  2. High-Level Design: Sketch the main components and their interactions. This is the "bird's-eye view" of your system.
  3. Detailed Design: Dive deeper into specific components as guided by the interviewer (e.g., API contracts, database schema).
  4. Wrap-up and Optimization: Discuss bottlenecks, failure modes, and potential improvements (e.g., scaling, reliability).

This lesson will focus on mastering the first two stages: Clarification and High-Level Design.


2. Case Study: Designing a URL Shortener (e.g., TinyURL)

"Design TinyURL" is a classic system design question. It's simple enough to cover in an interview but has enough depth to explore concepts like scalability, data modeling, and caching. Let's apply our 4-step framework.

Step 1: Problem Clarification & Estimation

Never jump straight to a solution. The first thing you should do is ask questions to define the scope. What features are essential? What are the performance and reliability goals?

How Would You Design TinyURL? Most Candidates Struggle Here

The article 'How Would You Design TinyURL?' provides an excellent, detailed breakdown of the requirements gathering and estimation phase. This is a perfect model for how you should start your own interview discussion.

Please read the first section, '1. Requirements & Estimations'. Pay close attention to the distinction between functional and non-functional requirements. Also, note how back-of-the-envelope calculations for traffic and storage immediately inform the scale of the system you need to design.

From the reading, we can summarize the key requirements:

  • Functional Requirements:

    • Given a long URL, return a short URL.
    • Given a short URL, redirect to the original long URL.
    • Support for custom aliases (optional).
    • Analytics (click counts, etc.).
    • Users can manage their links (optional).
  • Non-Functional Requirements:

    • High Availability: The service must be highly available, especially for redirection.
    • Low Latency: Redirection should be extremely fast.
    • Scalability: Must handle a large number of reads (redirections) and writes (creations). The estimations suggest a read-heavy system (10:1 read-to-write ratio).

The capacity estimates (100 million writes/day, 1 billion reads/day) are crucial. They tell us that a single server or database won't be sufficient. We must design a distributed system from the outset.

Step 2: High-Level Architecture

Now that we have the requirements, we can sketch out the high-level architecture. This involves identifying the core components and how they fit together. A diagram is your best friend here.

Let's start with a basic architectural diagram.

TinyURL System Design Architecture
A simplified high-level architecture for a TinyURL service. It shows the client, load balancer, application servers, a dedicated key generation service (KGS), a cache, and the database.

This diagram illustrates the main building blocks. Let's define the roles and boundaries of these components, which can be thought of as different services or logical units in your system.

How Would You Design TinyURL? Most Candidates Struggle Here

The 'How Would You Design TinyURL?' article also provides a more detailed architecture and explains the data flow for the two main use cases: creating a short URL and redirecting it.

Please read the section 'High-Level Architecture' and the 'Data Flow' subsection. Focus on understanding the responsibility of each component in the diagram and tracing the path of a request for both URL creation (a write operation) and URL redirection (a read operation).

Based on the readings, let's define the core services and components:

  1. Client: The user's browser or a programmatic API client.
  2. Load Balancer (LB): Distributes incoming traffic across multiple application servers. This is the first step to achieving high availability and scalability.
  3. Application Servers (The Core Service): This is the stateless backend logic that handles the HTTP requests. In your context, this would be a cluster of Spring Boot applications. Its responsibilities include:
    • Handling API requests to create new short URLs.
    • Handling requests for short URLs and performing the redirection.
    • Validating inputs.
  4. Key Generation Service (KGS): A dedicated service responsible for generating unique 6-8 character keys. Decoupling this logic is a smart design choice. If it were part of the main application server, generating unique keys in a distributed environment would become a significant bottleneck. The KGS can ensure uniqueness by using a distributed counter or pre-generating a large batch of keys and storing them in a database.
  5. Database (DB): The persistent storage for the short_key -> long_url mapping. Given the scale (terabytes of data over 5 years), this will need to be a distributed/sharded database. The primary lookup will be on short_key, which should be the primary key and indexed for fast retrieval.
  6. Cache: A distributed in-memory cache (like Redis) that sits in front of the database. Since our system is read-heavy and users often access the same popular links, a cache is critical for achieving low latency and reducing load on the database. The flow is simple: on a redirect request, first check the cache. If the key is present (cache hit), return the long URL immediately. If not (cache miss), query the database, return the result, and populate the cache for subsequent requests.
Test your understanding!

In the TinyURL system, which component is most critical for ensuring low latency during redirection, and which component is the primary bottleneck for ensuring uniqueness during URL creation?

Show answer
  • Low Latency (Redirection): The Cache is the most critical component. A high cache-hit ratio means that most redirection requests can be served directly from fast in-memory storage, avoiding slower database queries.
  • Uniqueness (Creation): The Key Generation Service (KGS) or the mechanism for generating a unique short_key is the primary bottleneck. In a distributed system, ensuring that two different application servers don't generate the same key at the same time is a classic coordination problem that this service is designed to solve.

3. Generalizing the Pattern

The architecture we just outlined for TinyURL isn't unique. It's an application of several common system design patterns. Recognizing these patterns will help you tackle unfamiliar problems in interviews.

System Design Interview Cheat Sheet: 12 Templates ...

The 'System Design Interview Cheat Sheet' resource introduces 12 common design templates. It's useful to see how our TinyURL design fits into this broader context.

Skim through the section '12 System Design Templates Used by Google Engineers'. You don't need to memorize them all, but notice that 'URL Shortener Service' is one of them. Also, see how our design incorporates elements from other templates like 'Scalable Web Application' (load balancing, horizontal scaling) and 'Distributed Caching Layer'.

By recognizing these fundamental patterns—load balancing, caching, stateless services, database sharding—you build a mental toolkit that you can apply to almost any system design prompt, whether it's designing a news feed, a chat application, or a video streaming platform.


Conclusion

In this lesson, we established a structured framework for approaching system design interviews and applied it to outline a high-level architecture for a URL shortener. You learned how to move from ambiguity to a concrete plan by clarifying requirements, making estimations, and identifying the core components and their interactions.

Key Takeaways:

  • Follow a 4-Step Process: Clarify -> High-Level Design -> Detailed Design -> Optimize. This structure demonstrates a methodical and professional approach.
  • Requirements Drive Design: Functional and especially non-functional requirements (scale, latency, availability) dictate your architectural choices.
  • Identify Core Components: Most web-scale systems involve a client, load balancer, stateless application servers, a cache, and a database.
  • Define Service Boundaries: Decouple responsibilities into logical services (e.g., Core API, Key Generation Service) to manage complexity and reduce bottlenecks.
  • Recognize Patterns: The TinyURL architecture is a classic example of a read-heavy, scalable web application that leverages caching for performance.

Preview of the Next Lesson:
Today, we focused on outlining the what—the components and their layout. In a real interview, the crucial follow-up questions will be about why. In our next lesson, we will address the learning outcome: "Justify the choice of data stores, communication patterns, and resilience strategies for a given system design scenario." We will revisit our TinyURL design and defend our choices for the database, cache, and other components, preparing you to handle the deep-dive portion of the interview.