Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

System Design (High-Level Design)  Module 26 – Case studies: booking, commerce and contention

Design a price tracker: history and drop alerts

Design price history and drop alerts: change-only rows, the lowest price of 30 days, alerts that fire once, and sale-day bursts without spam.

  • Advanced
  • 30 minutes
  • Examples run with Python 3.14.8, Pyodide 314.0.7, Node.js 24.21.0 and quickjs 0.32.0
  • By MySmartCoPilot
Free intro, Pro: 7 of 30 minutes free
Free: One drop can fire a million alerts, and the first design sends each once. With a pass: the other 13 sections and 3 interview answers, about 23 minutes.

What you will learn

  • Estimate history storage and the alert burst of a sale day
  • Store price history compactly and answer lowest-price queries over 30 days
  • Match price changes to millions of alerts and fire each one exactly once
  • Plan sale-day alert bursts that arrive promptly without spamming anyone
  • Explain what unsubscribe rules and honest-pricing rules require of alert messages

Before you start

What you’ll learn · Before you start

What you will learn

  • Estimate history storage and the alert burst of a sale day
  • Store price history compactly and answer lowest-price queries over 30 days
  • Match price changes to millions of alerts and fire each one exactly once
  • Plan sale-day alert bursts that arrive promptly without spamming anyone
  • Explain what unsubscribe rules and honest-pricing rules require of alert messages

Before you start

On this page

The alert side of a price tracker stores what each price did and tells people when a price they watch drops to their target, exactly once and only when it is true. History keeps a row only when a price or the stock changes, in integer minor units with a currency code, and answers questions such as the lowest price of the last 30 days, which shoppers want and some consumer rules use to judge a reduction.

Alerts are indexed by item and target, so a drop finds the alerts it fires with one range scan. Each alert fires once per change, re-arms only after the price has risen clearly above the target, and waits until a surprising drop has been confirmed by a second fetch. On a sale day one drop can fire a million alerts, so messages are queued, merged into digests per person, held during quiet hours and sent within each provider’s limits, with one-click unsubscribe and no invented urgency.

One drop can fire a million alerts, and the first design sends each once

What makes alerts different

A wrong alert is worse than a late one: it sends people to a price that does not exist, and they stop trusting every later alert. One event can fan out enormously, because the product everyone watches is the one that drops on a sale day. Prices wobble around targets, so a naive alert fires again and again. And alert messages are bulk messages, under the rules that mail providers and consumer laws set for them.

What is different What the design does
A wrong alert costs trust A surprising drop is fetched again first
One drop fans out to a million alerts Messages are queued, merged and paced
Prices wobble around targets An alert re-arms only after a clear rise
Alerts are bulk messages One-click unsubscribe and no invented urgency

Requirements

People set a target price for a product, seller and region, and receive a push or an email when the price reaches it while the item is in stock. They see each product’s history and its lowest price of the last 30 days. The qualities: every alert fires once per qualifying change; no alert is sent for a price that has not been confirmed; alerts arrive within a minute or two even on a sale day; quiet hours and opt-outs are respected; history is kept for years at low cost.

Estimates

The questions give each assumption, and the last row assumes that 30 % of the alerts go by email. Work each figure out, then check yourself; the workings follow.

Checkpoint

Check the estimate

  1. Question 1 of 3 Why is a wrong price alert worse than a late one?

    Choose one answer.

    Show the answer: Question 1 of 3

    Answer: It sends people to a price that does not exist, and they stop trusting every later alert

    A wrong alert sends people to a price that does not exist, and they stop trusting every later alert, which is why a surprising drop is confirmed by a second fetch before anyone is told.

  2. Question 2 of 3 A tracker follows 20 million items whose prices change 0.3 times a day on average. With a 40-byte row per change, how many gigabytes does a year of history take?

    Type a number.

    A hint

    Count the changes of a year first, then multiply by the bytes of a row.

    Show the answer: Question 2 of 3

    Answer: 87.6 GB (anything from 78.8 to 96.4 counts)

    20,000,000 × 0.3 × 365 = 2.19 billion changes a year, and 2.19 billion × 40 bytes ≈ 87.6 GB. That fits on one database with replicas, which is why the history can keep every change.

  3. Question 3 of 3 On a sale day, 1,000,000 alerts fire within the first minute. How many alerts a second is that?

    Type a number.

    Show the answer: Question 3 of 3

    Answer: 16667 alerts a second (anything from 15000 to 18334 counts)

    1,000,000 ÷ 60 ≈ 16,667 a second, from one minute of price drops. The matcher can find them that fast; the senders are what limit how quickly people hear.

Quantity Working Result
History, change rows only 20 million items × 0.3 changes a day × 365 × 40 bytes about 88 GB a year
History, a row per hourly check 20 million × 24 × 365 × 40 bytes about 7 TB a year
Alerts in a sale’s first minute 1,000,000 ÷ 60 s about 16,700 a second
Separate emails at 2,000 a second 300,000 ÷ 2,000 150 seconds for the last

Storage is easy once only changes are kept; the burst is where the design is tested.

The first design

Price alerts: changes feed the history and an alert matcher; drops are confirmed, fire once and go out through a queue.Price eventsonly when price or stock changedHistory writerchange rows, daily low and highLowest price ofthe last 30 daysAlert matcherarmed alerts by item and targetConfirm surprising dropsfetch again firstAlert statesarmed, fired, re-armedNotification queuedigests, quiet hoursPush and emailrate limits, one-click unsubscribePeople watchingfire onceshown in the message

The first design of a price tracker's alert side

Text description of the diagram

The diagram shows what happens to a price change, from top to bottom.

  1. Price events arrive only when a price or the stock changed.
  2. The history writer stores change rows and the daily low and high, from which the lowest price of the last 30 days is answered.
  3. The alert matcher finds the armed alerts of the item whose target the new price meets.
  4. A surprising drop is confirmed by fetching the page again first.
  5. Alert states record armed, fired and re-armed alerts, so each one fires once.
  6. The notification queue applies digests and quiet hours, and push and email providers send the messages within their rate limits, with one-click unsubscribe, to the people watching.
  7. A dashed arrow shows the lowest price of the last 30 days going into the message.

Price events from collection reach two consumers. The history writer stores change rows and daily lows and highs, from which the lowest price of the last 30 days is read. The alert matcher finds the armed alerts that the new price meets, a surprising drop is confirmed by a second fetch, and the alert states record each firing. The notification queue groups, holds and paces the messages, and the providers deliver them.

Step through one drop, from the price event to the person watching:

Interactive · step by step One price drop through the first design Step through one drop from the price event to the person watching, and see where each check sits.
One price drop through the first design, step 8 of 8. Showing Price events, History writer, Alert matcher, Lowest of 30 days, Confirm surprising drops, Alert states, Notification queue, Push and email, People watching.fire oncePrice eventsonly on a changeHistory writerchange rowsAlert matcherarmed alerts by targetLowest of 30 daysfrom the historyConfirm surprising dropsfetch again firstAlert statesarmed, fired, re-armedNotification queuedigests, quiet hoursPush and emailwithin their rate limitsPeople watchingone message

The drawing shows the whole scene; its 8 steps are listed below.

Every step as text
  1. A change arrives. Collection sends a price event only when the price or the stock changes, here a drop from 2,499.00 to 2,299.00 for one item of one seller in one region.
  2. History keeps the change. The history writer stores a change row, in integer minor units with the currency code, and the daily low and high from which the lowest price of 30 days is read.
  3. Which alerts does it meet?. The alert matcher finds the armed alerts of this item whose target the new price meets.
  4. Is the drop surprising?. A surprising drop is confirmed by a second fetch before anyone is told, because a wrong alert is worse than a late one.
  5. Each alert fires once. The alert states record each firing, so an alert fires once for this change and re-arms only after the price has risen clearly above its target.
  6. Grouped and held. The notification queue merges each person's alerts into digests and holds messages during their quiet hours.
  7. The lowest price goes along. The message shows the lowest price of the last 30 days beside the new price.
  8. Sent within the limits. Push and email providers send the messages within their rate limits, with one-click unsubscribe, to the people watching.

Checkpoint

Check the first design

  1. Question 1 of 2 Which of these are on the path from a price event to a sent alert? Choose every one.

    Choose every answer that is right.

    Show the answer: Question 1 of 2

    Answer:

    • The push or email provider
    • The alert matcher
    • The notification queue
    • The alert states that record what fired

    A change is matched to armed alerts, recorded as fired, queued and handed to a provider. The scheduler and link intake belong to collecting prices, before any event exists.

  2. Question 2 of 2 A shop's template change makes one price read as a 90 % drop. Which part of the first design keeps that drop from reaching people?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: The step that confirms a surprising drop with a second fetch before any alert fires

    The alert matcher finds the armed alerts the new price meets, and a surprising drop is confirmed by a second fetch before the alert states record any firing.

The deep-dive questions

  1. How is history stored compactly, and how is the lowest price of the last 30 days answered correctly?
  2. How does one price change find the alerts it fires among millions?
  3. How does each alert fire exactly once, and when does it re-arm?
  4. How are surprising drops confirmed before anyone is told?
  5. How do a million alerts from one sale go out promptly without spamming anyone?
  6. What do unsubscribe rules and honest-pricing rules require of the messages?
  7. What breaks at 10× and 100×, and which designs are rejected?

History stores changes only, and the 30-day lowest needs the row before the window Pro: opens with a Pro, Premium or Ultimate pass

In this part:

  • A row only when the price or the stock changes
    • The lowest price of 30 days includes the row in effect at the start
  • Armed alerts sit in a partial index, so a drop reads only the alerts it fires
  • An alert fires once per change, and re-arms only past a margin
  • A surprising drop is fetched again before anyone hears of it
  • A sale-day burst becomes one prompt message per person, measured
  • Messages people want: one-click unsubscribe, consent and honest words
  • At 10× history writes give way first, and at 100× the providers’ limits
  • Failure drills: five faults, each with a safe way out
  • Options considered and rejected
  • What each level covers, and a 45-minute self-mock
    • What each level is expected to cover
    • A 45-minute self-mock
  • Practise: an alert that re-arms past a margin, then the whole design
    • An alert that fires once, ignores repeats and re-arms with a margin
  • Interview questions
    • On a sale day, 40 watched products drop in the first minute and fire 1 million alerts. Your email provider takes 2,000 messages a second and push 20,000. Design delivery so that people hear promptly, nobody gets a flood of messages, and nobody is woken in their quiet hours.
    • A product's price moves just below and just above a user's target several times a day, and the user gets an alert every time. Other users report receiving the same alert twice within a second. Explain both problems and fix them.
    • Shoppers want the lowest price of the last 30 days shown next to every price, and some consumer rules compare a reduction with it. Your history keeps one row per price change. How do you compute it correctly, and quickly enough for 20 million items?
  • Key takeaways

6 diagrams · 3 runnable examples (JavaScript, Python) · 1 exercise with sample tests · 3 interview answers · about 47 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

Read a complete sample first: Design movie seat booking like BookMyShow

References

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.