Skip to main content

Welcome to a Grasp lesson

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

Lesson 55

Designing Time-Series Metrics Systems

Recommended resources

Hello! Welcome to our lesson on designing a time-series metrics collection and aggregation system.

In our previous lesson, we designed a ride-sharing service. We focused on handling high-throughput, real-time data for location tracking and ensuring consistency in the matching process. A key takeaway was the challenge of managing massive write volumes, which we solved using Redis and Geohashing.

Today, we will expand on that theme of high-throughput data by tackling another critical infrastructure component. Your learning outcome is to design a time-series metrics collection and aggregation system. This is the backbone of observability for any large-scale company, providing the data needed for monitoring, debugging, and business analytics. Understanding how to build this system is a key expectation for senior backend engineers in top-tier interviews.

1. Defining the System: Requirements and Scope

As always, we begin by clarifying the problem. A metrics system can be vast, so we need to define a clear set of functional and non-functional requirements to guide our design.

Let's start by outlining what our system must do. A good set of requirements forms the foundation of a strong design.

System Design Interview: Metrics Monitoring and Alerting System

This article provides a concise list of functional and non-functional requirements for a metrics monitoring system. Use it to frame the problem scope.

Read the section titled 'Requirement Gathering'. Focus on the functional and non-functional requirements, as well as what the system will not handle (e.g., log aggregation).

Based on that reading and common expectations for this problem, here is our refined scope:

Functional Requirements:

  1. Collect Metrics: The system must gather metrics from millions of sources (servers, applications, devices). Metrics include CPU utilization, memory usage, request latency, error counts, etc.
  2. Store Metrics: Store the collected time-series data efficiently.
  3. Aggregate & Downsample: Provide aggregated views of data over different time windows (e.g., average CPU over the last hour, day, or month).
  4. Query & Visualize: Expose an API for querying the data, which will be used by dashboards (like Grafana) to display graphs and charts.
  5. Alerting: Allow users to define rules (e.g., "alert if CPU > 90% for 5 minutes") and trigger notifications.

Non-Functional Requirements:

  1. High Write Throughput: The system must handle millions of metric data points per second. This is a write-heavy system.
  2. Low Query Latency: Queries for recent data (e.g., last hour) for dashboards should be very fast (sub-second).
  3. Scalability: The architecture must scale horizontally to accommodate growth in the number of metrics and sources.
  4. Reliability & Durability: The system should not lose metric data, and the alerting component must be highly reliable.
  5. Cost-Effectiveness: Manage storage costs through data retention policies and compression.

The fundamental data point we are dealing with has a specific structure, which is crucial for the entire design.

Metrics Monitoring System Design Explained Step-by-Step | Crack FAANG Interviews

Let's quickly review the typical data model for a time-series metric. Understanding this structure is key to designing the storage and query layers.

Watch from 10:34 to 11:30. Pay attention to the four core components of a metric data point: name, value, source (or tags), and timestamp.

A metric data point is typically composed of:

  • Metric Name: e.g., cpu.utilization
  • Timestamp: The time the measurement was taken (e.g., a Unix epoch).
  • Value: The measured value (e.g., 0.75).
  • Tags/Labels: Key-value pairs that add context, like host=server-123, region=us-east-1. These are critical for filtering and aggregation.

2. High-Level Architecture

Now, let's sketch out the main components of our system. The architecture can be broken down into a pipeline: collection, ingestion, storage, processing, and consumption (querying, alerting).

Metrics Monitoring System Design Explained Step-by-Step | Crack FAANG Interviews

This video segment provides an excellent walkthrough of building the system from a basic concept to a scalable architecture. We'll start with the initial, high-level components.

Watch from 13:59 to 18:20. Focus on the initial components introduced: servers with agents, a collector service, a database, a dashboard, and an alerting mechanism. Pay close attention to the push vs. pull discussion.

The initial design introduces several key ideas. Let's formalize the data collection models and then address the obvious scalability bottleneck.

Data Collection: Push vs. Pull

There are two primary models for getting data from the sources to our collection service:

  1. Push Model: An agent running on each source actively sends metrics to a central endpoint. This is simpler for dynamic environments (e.g., serverless functions, short-lived jobs) as the source doesn't need to be discoverable.
  2. Pull Model: A central collector periodically scrapes a /metrics endpoint on each source. This gives the monitoring system more control and doubles as a health check (if a scrape fails, the source is likely down).
Push vs. Pull Data Collection Models for Realtime Monitoring
This diagram shows the fundamental difference in data flow between push and pull models. In the push model, agents initiate the connection. In the pull model, the monitoring system initiates it.
Metrics Pull Model with Service Discovery
In a dynamic environment, the pull model relies on a Service Discovery mechanism (like Zookeeper or Kubernetes' internal service registry) to find targets to scrape.

For a large, heterogeneous environment, a hybrid approach supporting both models is often best.

Scaling the Ingestion Pipeline

The simple design from the video (Agent -> Collector -> DB) has a major bottleneck: the collector service and the database will be overwhelmed by the high write volume. Your experience with backend systems should immediately flag this as a point of failure.

The solution is to decouple the write path using a message queue.

Metrics Monitoring System Design Explained Step-by-Step | Crack FAANG Interviews

Now, let's see how to evolve the high-level design to handle massive scale. The introduction of a message broker is a critical step.

Watch from 20:28 to 25:26. Observe how a load balancer and a message broker (Kafka) are introduced to decouple the collectors from the downstream consumers, enabling independent scaling and resilience.

Our scaled-up high-level architecture now looks like this:

  1. Metric Sources (with Agents) send metrics.
  2. A Load Balancer distributes the incoming traffic across a fleet of stateless Collector Services.
  3. The collectors publish the metrics to a Message Queue (like Apache Kafka). This queue acts as a durable buffer, absorbing write spikes.
  4. A set of Consumer/Processor Services read from the queue.
  5. These services write the data to a specialized Time-Series Database (TSDB).
  6. A Query Service provides an API for reading data from the TSDB.
  7. Dashboards and an Alerting System use the Query Service.

3. Deep Dive: The Time-Series Database (TSDB)

The choice of database is the most critical decision in this design. Why can't we just use a standard SQL database like PostgreSQL, or a general-purpose NoSQL store like Cassandra?

The answer lies in the unique characteristics of time-series data: an extremely high volume of writes, append-only operations, and queries that are almost always filtered and aggregated by time. This workload requires a purpose-built solution.

This next video is a masterclass on the internal workings of TSDBs. Understanding these principles is what interviewers at top companies look for in a senior candidate.

How do Time Series Databases Work?

This video explains why TSDBs are necessary and how they are optimized for time-series workloads. We will break it down into several parts.

We will go through this video section by section.

Part A: Why Not Relational Databases?

First, let's understand the problem we're solving.

How do Time Series Databases Work?

Let's begin by examining the specific reasons why traditional relational databases are ill-suited for handling time-series data at scale.

Watch from 03:16 to 06:44. Focus on the three key problems identified: high write volume, inefficient storage, and slow query performance.

Part B: Optimizing for High-Throughput Writes

To handle millions of writes per second, TSDBs use a storage engine structure that favors sequential writes. The Log-Structured Merge (LSM) Tree is a perfect example.

How do Time Series Databases Work?

Now, let's explore the core mechanism that allows TSDBs to achieve such high write performance.

Watch from 06:44 to 14:47. The key concepts to grasp are: Append-only Storage: Why writing sequentially to disk is much faster than random writes. LSM Trees: How they work by buffering writes in an in-memory memtable and then flushing sorted segments (SSTables) to disk.

Part C: Optimizing for Storage and Queries

TSDBs employ clever tricks to reduce storage footprint and speed up queries.

How do Time Series Databases Work?

Beyond write performance, TSDBs use specialized compression and indexing techniques to be highly efficient.

Watch from 14:47 to 25:33. This is a dense but crucial segment. Focus on understanding: Compression: Techniques like Delta encoding and Delta-of-deltas for timestamps and values. Time-based Partitioning: How data is organized into files based on time ranges to prune the search space for queries. Downsampling: The process of creating lower-resolution aggregates (e.g., hourly, daily) from raw data to speed up long-range queries and save space.

Part D: The Achilles' Heel - Cardinality

The biggest performance challenge for TSDBs is high cardinality. Cardinality refers to the number of unique time series, which is determined by the unique combinations of a metric name and its tags.

How do Time Series Databases Work?

This is a critical trade-off to discuss in an interview. Let's see why high cardinality can bring a TSDB to its knees.

Watch from 31:20 to 34:26. Understand why using a tag with a huge number of unique values (like user_id or request_id) is an anti-pattern that leads to an explosion of series and breaks the TSDB model.


4. Aggregation and Data Lifecycle

As we saw, downsampling is a key feature of TSDBs. In our system design, we need to formalize this into a concrete data lifecycle and retention policy. This is essential for managing storage costs and maintaining query performance.

We will define a tiered retention strategy:

  • Hot Tier: Raw, high-resolution data (e.g., 10-second granularity) is kept for a short period (e.g., 7 days) in the fastest storage for real-time dashboards and immediate debugging.
  • Warm Tier: Data is downsampled to a lower resolution (e.g., 1-minute granularity) and kept for a medium term (e.g., 30-90 days). This is used for trend analysis over recent weeks.
  • Cold Tier: Data is further downsampled (e.g., 1-hour granularity) and kept for a long term (e.g., 1-2 years) for historical reporting. For compliance, raw data might be moved from the ingestion pipeline to cheap, long-term object storage like Amazon S3.

The video below discusses this concept of having a real-time path for dashboards and a separate path for raw data archiving.

Metrics Monitoring System Design Explained Step-by-Step | Crack FAANG Interviews

Let's look at a practical implementation of this tiered data strategy, separating the real-time aggregated path from the raw data archival path.

Watch from 25:26 to 31:20. Note how the design splits the pipeline: An Aggregator Service creates second-level data for the 'hot' OLAP database used by dashboards. A separate consumer dumps the raw millisecond-level data from Kafka into a Blob Storage (S3) for the 'cold' path.


Conclusion

In this lesson, we designed a scalable and robust time-series metrics collection and aggregation system. We moved from basic requirements to a sophisticated, decoupled architecture and dove deep into the specialized technologies that make it possible.

Key Takeaways:

  • Decouple for Scale: Use a message queue like Kafka to buffer the massive write load, allowing the collection and storage tiers to scale independently.
  • Use the Right Tool: Time-series data has a unique workload. A purpose-built Time-Series Database (TSDB) is essential for performance.
  • Understand TSDB Internals: For a senior-level discussion, you should be able to explain why TSDBs are fast, referencing concepts like LSM trees for writes and delta encoding for compression.
  • Beware High Cardinality: The number of unique time series is a critical performance factor. Avoid using high-cardinality identifiers (like user_id) as tags.
  • Implement a Data Lifecycle: Use downsampling and tiered storage (hot, warm, cold) to balance query performance, data granularity, and storage cost.

Next Lesson Preview:

We've now completed several complex system design problems. Your goal, however, isn't just to be a great designer but to prove it in an interview. The other half of that challenge is the behavioral interview. In our next lesson, we will shift gears and begin our module on Behavioral Interview Fundamentals. We'll start by learning to describe the purpose and evaluation criteria of behavioral interviews and introduce the famous STAR method for structuring your answers.