Hello. This five-lesson course builds an interview-ready design for a price-tracking service, beginning with the decision that determines every later component choice: what problem, exactly, is the system promising to solve?
In a senior system-design interview, a requirement such as “track prices and notify users” is deliberately incomplete. Before discussing databases, queues, or crawlers, turn it into a bounded product contract with measurable success criteria. By the end of this lesson, you will be able to state that contract concisely: who interacts with the system, which flows matter, what lies inside its boundary, what is excluded, and how reliability is measured.
Start with scope, not a component diagram
A common interview failure mode is to begin drawing services immediately. This locks in an architecture before deciding which guarantees are needed. A price tracker can mean anything from a single-merchant scraper that emails on drops to a multi-country comparison engine that tracks availability, coupons, variants, and millions of listings. Those are not the same design problem.
Use the opening minutes to make the ambiguity visible and then reduce it. Say your assumptions out loud, invite correction, and choose an MVP scope that leaves enough depth to discuss the difficult parts: collection, freshness, scale, and correct alerting.
How to Answer System Design Interview Questions (Complete Guide)
Watch Exponent's “How to Answer System Design Interview Questions (Complete Guide)” for a compact framing method: clarify the problem, state assumptions, identify functional and non-functional requirements, and prioritize the constraints that drive design.
Watch stage one. Focus on the discipline of narrating assumptions and prioritizing constraints before estimating volume or selecting infrastructure.
For this course, use the following working premise unless an interviewer changes it:
We are designing a consumer price-tracking service for a defined set of supported online merchants. An authenticated user submits a supported product listing, sets a target price, views the latest observed price and price history, and receives an email when a newly observed price satisfies the target.
This premise makes several intentional choices:
- We track a merchant listing: a particular variant at a particular merchant URL, in a particular storefront and currency.
- The service displays the latest observed listed price, not a guaranteed real-time merchant price.
- The first notification channel is email.
- The system supports several merchants, but not the entire web.
- A user watches a listing against an explicit threshold.
The phrase “listing” is important. “Wireless headphones” is not specific enough to monitor: color, size, seller, region, currency, and membership status can materially change the price. We will later introduce canonical products for grouping equivalent listings, but the price observation itself must attach to something unambiguous.
The SLO lifecycle overview below places today’s work in context. We are primarily in the Initiate, Discover, and early Design phases: establish the business outcome, identify stakeholders, observe the system’s required behavior, then define meaningful indicators and objectives. The later lessons will turn those objectives into scheduling, storage, ingestion, and alerting mechanisms.

Turn the product idea into actors and user-visible flows
A requirement brief should distinguish actors from components. “Kafka,” “the scraper,” and “the database” are possible components; they are not actors. An actor either has a goal in the system or materially affects whether the system can meet its goal.
For our scoped service, the relevant actors are:
| Actor | Goal or responsibility |
|---|---|
| End user | Add a listing, set or change a target price, inspect the latest price and history, and manage watches. |
| Authenticated client | Calls the service on the user’s behalf through web or mobile interfaces. |
| Merchant or data provider | Exposes price information through an API, feed, or public web page; it is the external source of price data. |
| Email delivery provider | Accepts messages for delivery and may report delivery or bounce events. |
| Operations/support staff | Onboards supported merchants, investigates broken collection, and responds to user issues. |
The end user is the primary actor. The merchant and delivery provider are especially important because they establish external dependencies that the service cannot fully control.
Now state the core functional flows. A useful test is: can a user or external system observe a meaningful before-and-after outcome?
1. Add a listing and create a watch
- The user submits a URL for a supported merchant and selects the concrete product variant if the URL represents several variants.
- The service resolves the listing, shows the latest known price and its observation time, and accepts a target price.
- The user creates a watch.
- The service durably records the watch and confirms that it is active.
A successful “create watch” response means the user’s request is stored durably. It does not mean the listing has just been checked, nor does it promise an immediate notification.
2. Read current price and historical observations
The user opens a watched listing and sees:
- the latest validated observed price;
- the merchant, currency, and relevant variant;
- when the service observed that price; and
- a paginated history of prior observations.
Showing the observation timestamp is a product requirement, not merely a debugging convenience. A price from four hours ago may be valid data but is a poor substitute for a live quote. The user needs the context to interpret it.
3. Collect and validate price observations
The system periodically obtains a price from each eligible merchant listing, using an approved source such as a merchant API, product feed, or web page. It validates the result and records an observation with a timestamp. This is an internal workflow rather than a direct user request, but it is essential because every freshness and alert promise depends on it.
4. Detect a qualifying price and notify
When a newly validated observed price is at or below a user’s target, the system evaluates the watch and submits an email notification.
Define the alert’s product semantics before defining its machinery:
A watch fires when an observed price transitions from above the user’s threshold to at or below it. The service sends at most one alert for that crossing. It becomes eligible again only after the price is observed above the threshold and subsequently crosses downward.
This avoids an irritating outcome in which a user receives an email every time the collector observes the same qualifying $15 price. The detailed state machine, retries, and duplicate prevention belong in Module 4; at this stage, the important requirement is the observable rule.
The opening of the curated price-tracker walkthrough provides a useful example of choosing a narrow initial scope: price subscriptions and threshold-based email alerts, with price history treated as an additional feature.
Meta Interview Question | System Design: Price Drop Tracker
Read the opening transcript of “Meta Interview Question | System Design: Price Drop Tracker.” It illustrates how a system-design answer can commit to a small set of user-facing flows before introducing a scraper or data stores.
In the opening requirements discussion, read the stated scope. Notice that the speaker explicitly separates the must-have alert flow from the optional price-history flow. For your own brief, be equally clear about what is core and what is merely desirable.
Draw the boundary: what the service owns and what it does not
A system boundary prevents accidental promises. It says which behavior your design must provide, which systems it depends on, and where responsibility ends.
For the initial design, the price-tracking service owns:
- accepting and validating supported listing URLs;
- maintaining listing metadata, watches, current observed prices, and price history;
- scheduling price checks;
- obtaining and validating observations through supported acquisition methods;
- evaluating threshold transitions;
- creating notification requests and tracking their internal outcome;
- exposing current-price, history, and watch-management APIs; and
- operational visibility into freshness, failures, backlog, and notification processing.
The service depends on but does not own:
- merchant catalogs, merchant availability, source correctness, and source-side rate limits;
- the identity provider, if company authentication already exists;
- DNS, networks, and cloud infrastructure;
- the email provider’s final delivery to an inbox; and
- the user’s mailbox, spam filter, and email client.
This distinction changes how you speak about guarantees. The service can guarantee that it submits a well-formed email request to its provider after processing a valid qualifying observation. It cannot guarantee that the user reads it, or even that it avoids a spam folder.
A strong brief also names exclusions. Exclusions are not apologies; they concentrate the design on the problem being evaluated.
Initial non-goals
For this interview scope, explicitly exclude:
- purchasing products, handling carts, or redirecting users through affiliate transactions;
- guaranteeing the merchant’s checkout price;
- tracking tax, shipping, personalized discounts, coupons, loyalty pricing, or membership-only prices;
- stock-level alerts and seller-rating changes;
- worldwide currency conversion and every regional storefront;
- arbitrary unsupported URLs;
- real-time monitoring of every price change at the merchant; and
- predicting future price movements.
The exclusion of “real-time monitoring” is particularly consequential. With polling, the service discovers a price change only when it checks the source. It cannot alert at the instant the merchant changes a page it has not yet observed.
A compact way to state the data contract is:
The service reports the latest validated observation of a supported listing’s public base price, together with the observation time and currency. It does not claim that this is the current checkout price.
That sentence will protect later design choices around crawling, freshness, and user expectations.
Translate quality words into measurable targets
Words such as fast, fresh, and highly available are not requirements until they specify a population, a measurement point, a percentile or threshold, and a time window.
For this design, treat the following as initial targets to confirm with the interviewer. They are deliberately different because the system has different promises for reads, collection, and alerts.
| Dimension | Initial target | How it is measured |
|---|---|---|
| Price freshness | At least 95% of distinct listings with one or more active watches have a validated observation no older than 1 hour; 99% are no older than 4 hours. | At measurement time, calculate the age from the latest successful validated observation for each active watched listing. |
| Current-price read latency | ; . | Successful current-price API requests, measured at the service edge over a rolling window. |
| User-facing availability | monthly availability for current-price reads and watch-management operations. | Fraction of valid requests receiving a successful response within the latency objective, excluding agreed client-side failures. |
| Notification delay | minutes and minutes from durable recording of a qualifying validated observation to acceptance by the email provider. | Timestamp the validated observation and the provider-accepted send request; measure only alerts that should be sent. |
The availability target allows about minutes of unavailable time in a 30-day month. That number is not the main point; the key is that a percentage becomes operationally meaningful only when its scope and accounting rules are explicit.
Freshness is not latency
Read latency asks: “Once we know a price, how quickly can we return it?”
Freshness asks: “How old is the price we know?”
A system can return a cached price in milliseconds while that price is three days old. It would meet a latency target and fail its product promise. Conversely, a system may have a recent observation but experience a temporary API outage. The two dimensions need separate instrumentation and design decisions.
The freshness clock must also be defined carefully. In this course, it begins when our service successfully observes and validates the merchant price. Therefore, a one-hour freshness objective does not mean “we detect every merchant price change within one hour.” It means “for the targeted population, our latest known valid observation is usually less than one hour old.”
If a merchant offers authoritative event feeds later, the definition and target may improve. Do not quietly claim that stronger guarantee for a polling system.
Notification delay is also a bounded promise
The notification target begins after the service has a valid qualifying observation. It deliberately does not include time between an actual merchant price change and the next poll; that time is governed by freshness. It also ends when the email provider accepts the request, because inbox delivery is outside the service’s control.
Together, the two objectives give a useful upper-bound intuition:
- a price may wait up to the collection freshness window before being observed;
- after it is observed and qualifies, alert processing should usually consume no more than five minutes; and
- the email provider then controls final delivery behavior.
Do not collapse these into a vague statement such as “users get alerts within an hour.” The separate clocks reveal where bottlenecks originate.
Prioritize the tension
The key product tension is between freshness and the cost, reliability, and compliance constraints of checking merchants. Checking every listing every minute sounds fresh, but it can violate source rate limits, increase cost, and make the service less reliable. Checking once daily is cheap but makes alerts much less valuable.
The chosen target therefore limits the population to listings with active watches. Cold catalog listings can be refreshed less often or on demand without violating the principal customer promise. This distinction will become central to scheduling and capacity estimation in later lessons.
An interview-ready requirements brief
Here is a concise brief you could say or write after clarification. It is intentionally specific enough to drive an architecture, but avoids prematurely selecting technologies.
Goal. Build a multi-merchant consumer price tracker for supported online listings. Authenticated users can submit a supported listing, set a target price, view the latest observed price and paginated price history, and receive an email when the observed price crosses to at or below their target.
Actors. The primary actor is the end user. Merchant APIs, feeds, or public listing pages are external price sources. An email provider is an external delivery dependency. Operations staff manage merchant support and investigate collection failures.
Price definition. A price is the public base price for a specific merchant listing, concrete variant, storefront, and currency. The response includes the observation time. Tax, shipping, coupons, personalized prices, and final checkout totals are out of scope.
Core flows. Users create, modify, pause, and delete watches; read the latest price and history; and receive a single email per downward threshold crossing. The system periodically collects and validates prices for active watched listings.
Boundaries. We own watch management, price observations, collection scheduling, validation, alert evaluation, and notification submission. We do not own merchant correctness or availability, user authentication infrastructure, or final inbox delivery.
Non-goals. No purchasing, stock alerts, price prediction, arbitrary web coverage, real-time merchant-change detection, or global price normalization in the initial version.
Objectives. For active watched listings, 95% have observations under one hour old and 99% under four hours old. Current-price reads meet and . Read and watch-management APIs provide monthly availability. Qualifying alerts reach email-provider acceptance within five minutes at , and fifteen minutes at , after a valid observation is recorded.
In an interview, end with the constraints that need confirmation rather than inventing certainty:
- Which merchants and acquisition methods are permitted?
- Is email sufficient for the first version, or are push and SMS required?
- Is a one-hour observation age acceptable for watched listings?
- Must the service support price comparison across equivalent products, or only tracking a submitted listing?
- What user and listing scale should we assume?
That final question leads directly into the next lesson. Requirements determine which numbers matter; estimates determine whether the targets can be met.
Key takeaways
A credible price-tracker design begins with a precise product contract:
- Track a concrete merchant listing, and expose its observation time rather than pretending it is a live quote.
- Separate user flows from internal workflows, and distinguish actors from architectural components.
- Name external dependencies and explicit non-goals so the system does not promise control it lacks.
- Measure freshness, latency, availability, and alert delay with defined populations, clocks, percentiles, and ownership boundaries.
- Treat the freshness target for actively watched listings as a key driver of the whole design.
Next, you will turn this brief into explicit workload assumptions and capacity estimates: API requests, checks against merchants, events, notifications, bandwidth, and storage.
Can't find a good explanation? Sign up and we'll make it for you
Sign up