WalzoneInterview Prep
📞 Interviewing soon? Practice with a realistic AI mock phone interview — it calls you, then scores you. First 15 min FREE →

Coding Interview Essentials · Designing Real-World Systems · question 116 of 120

How would you design a service to monitor the uptime of a million websites?

📕 Buy this interview preparation book: 120 Coding Interview Essentials questions & answers — PDF + EPUB for $5

Designing a service to monitor the uptime of a million websites can be a challenging task considering the scale and reliability required. Here are some steps:

1. **Divide & Conquer**: We are tackling a huge number of websites (a million!). Hence, we need to divide the tasks into manageable chunks. Allocate a fixed number of websites to each worker server and make sure no two servers are checking the same website.

2. **Fault Tolerance**: Every system can fail, hence, it’s important to design a fault-tolerant system. If one worker server dies another should take over its job.

3. **Choosing an Efficient Data Structure**: We can use a HashMap where key is URL and value is a boolean array of size 24*60 (n). This boolean array will represent the status of each minute of the last 24 hours. 1 indicates up and 0 indicates down.

4. **Notifications**: Users should be notified when any tracked website goes down or comes back up. An observer pattern should be incorporated into the system.

5. **Selected Websites Balancing**: Put the monitored websites into a database, distribute cases to various servers according to the workload and remain flexible to the server performance.

Let’s look more in detail about these points.

### Multithreading

Given the huge number of websites, we can use multiple threads on each server. Each thread is responsible for checking the status of one or more websites. This way, we can monitor more websites simultaneously.

import requests

def is_site_alive(url):
    response = requests.head(url)
    return response.status_code == 200

### Fault tolerance

For ensuring this, we can maintain a master server, which is responsible for distributing the load among the worker servers. Master server will continuously monitor the heartbeat of worker servers. If any server dies, the master server can reallocate the websites to other servers.

### Choosing an Efficient Data Structure We need to query the status of the site for the last 24 hours. These are 24 * 60 = 1440 minutes. Hence, for quick retrieval and updates, we can keep them in main memory.

class WebSite:
  def __init__(self):
    self.status = [False] * (24 * 60)  # Initialize with False

  def update(self, minute, is_alive):  # O(1) operation
    self.status[minute] = is_alive

  def status_last_day(self):  # O(1) operation
    return self.status

### Notifications

Observer pattern can be used to notify users. Websites are ’subjects’ and users are ’observers’. We maintain a list of observers for each subject. When the state of subject changes, all its observers are notified.

### Selected Websites Balancing

We use master-slave mode. The master server detects and distributes new tasks, and each slave server automatically reports the running state and receives new tasks. For example, a slave server can monitor 10,000 websites, so we use about 100 slave servers. Alternatively, a load balancer can be put in place to redirect requests to less busy servers, providing a balanced workflow.

In conclusion, system design can considerably vary depending upon the functional and non-functional requirements. The design decisions mentioned above are a good starting point, but each system may require additional optimizations on case-by-case basis.

Reading is step one. Saying it out loud is the interview. Our AI interviewer calls your phone and runs a realistic Coding Interview Essentials interview — then scores it.
📞 Practice Coding Interview Essentials — free 15 min
📕 Buy this interview preparation book: 120 Coding Interview Essentials questions & answers — PDF + EPUB for $5

All 120 Coding Interview Essentials questions · All topics