Design a Price Alert System — System Design Interview Practice
Design a price-tracking and alerting service that watches products across marketplaces and notifies users when their rules are met. Work through the requirements, architecture trade-offs, and an interactive design review.
What does the "Design a Price Alert System" problem ask you to design?
Design a price-tracking and alerting service that watches products across marketplaces and notifies users when their rules are met. It is a practice challenge with Hard difficulty, about 60-90 minutes.
Concepts and architecture decisions to consider
- event drivenConcept to explore
- notificationsConcept to explore
- schedulingConcept to explore
- scalabilityConcept to explore
Interview prompt
Design a service where users watch products across marketplaces and receive one timely notification when a price rule is met, despite stale data, provider limits, retries, and traffic spikes.
- Separate price collection freshness from alert evaluation and notification delivery.
- Make marketplace throttling, retries, and adaptive polling explicit.
- Use durable state and idempotency so at-least-once events do not spam users.
- Define what a price means when variants, sellers, currencies, shipping, or taxes differ.
Requirements and scale assumptions
- Create, pause, resume, and delete alerts for a product or offer.
- Support target-price, percentage-drop, and back-in-stock rules with a cooldown.
- Collect prices from multiple providers and show current price plus history.
- Notify through user-selected channels and expose delivery status.
- Allow users to unsubscribe, change cadence, and export or delete their data.
- Deliver a triggered alert within 1 minute after a qualifying observation is accepted.
- Never lose a committed alert or price observation; duplicate notifications are unacceptable.
- Respect provider rate limits, robots/terms constraints, user quotas, and notification opt-outs.
- Tolerate provider outages and stale prices without presenting stale data as current.
- Keep alert CRUD responsive even while collection and delivery backlogs grow.
- 10 million registered users, 2 million daily active users, and 50 million active alerts.
- 100 million product observations per day across providers, with a 10x burst during sales.
- A product is collected every 15 minutes by default; hot products can receive shorter cadences within quota.
- Assume 5% of observations qualify for evaluation and 1% result in a notification after cooldowns.
- Observation rate: ~1.2K/s avg — 100M daily observations; provision collectors and queues for ~12K/s bursts.
- Active rules: 50M — Rules drive indexed evaluation lookups; do not scan every user on each price event.
- Notification rate: ~12/s avg — At 1% of observations, with campaign spikes and provider-specific quotas.
- Freshness target: ≤15 min — Default product freshness; show observed_at and provider status with every price.
Key entities
- ProductOfferofferId, provider, productId, sellerId, variant, currency, availability
Normalized offer identity across provider and seller dimensions.
- AlertRuleruleId, userId, offerId, condition, threshold, cooldownUntil, status
Indexed user rule evaluated against accepted observations.
- PriceObservationobservationId, offerId, price, shipping, tax, observedAt, sourceVersion
Versioned provider observation with freshness and pricing semantics.
- NotificationLedgerdedupeKey, ruleId, channel, attempts, providerId, status
Idempotent delivery record for one alert transition.
Data flow
- 1. Create the alertThe API validates the rule, resolves product and offer identity, stores preferences, and returns without waiting for a provider fetch.
- 2. Schedule collectionA scheduler chooses due offers from cadence, demand, freshness, provider quota, and exponential backoff, then dispatches bounded jobs.
- 3. Accept a price observationAdapters normalize currency, variant, seller, shipping, and availability; late observations are rejected or marked and durable price events are published.
- 4. Evaluate the ruleThe evaluator loads only active rules for the offer, compares the previous accepted state, applies cooldowns, and writes one notification decision.
- 5. Deliver asynchronouslyChannel workers retry provider delivery, record attempts in the ledger, and expose opt-out or failure status without blocking collection.
Deep dives and trade-offs
- Provider freshness and adaptive pollingFor the multi-marketplace price-alert service, one qualifying price transition produces at most one notification per rule/cooldown window. Design for the failure case where provider throttling, stale variants, late observations, and retries must not spam users or show false prices; keep retries, versions, and repair state explicit. Expose freshness, version, lineage, or audit metadata so operators and clients can distinguish current, pending, and degraded state.
- Offer identity and rule evaluationFor the multi-marketplace price-alert service, one qualifying price transition produces at most one notification per rule/cooldown window. Keep this concern off unrelated request paths and partition it by the multi-marketplace price-alert service access key. Expose freshness, version, lineage, or audit metadata so operators and clients can distinguish current, pending, and degraded state.
- Cooldowns and notification idempotencyFor the multi-marketplace price-alert service, one qualifying price transition produces at most one notification per rule/cooldown window. Keep this concern off unrelated request paths and partition it by the multi-marketplace price-alert service access key. Expose freshness, version, lineage, or audit metadata so operators and clients can distinguish current, pending, and degraded state.
- Polling freshness versus provider limitsUse demand-aware cadence, provider quotas, adaptive backoff, and explicit stale indicators. Polling every alert uniformly overloads providers and still cannot guarantee fresh data.
- Observed price versus landed priceModel price, shipping, tax, currency, seller, and variant explicitly and let users choose comparison semantics. Comparing only sticker price produces misleading alerts across marketplaces.
- Immediate notification versus cooldownEmit on a rule transition with a cooldown and a durable notification ledger. Notifying on every observation creates alert fatigue and duplicate delivery.
Frequently asked questions
What are the key requirements for "Design a Price Alert System"?
Key requirements include: Create, pause, resume, and delete alerts for a product or offer; Support target-price, percentage-drop, and back-in-stock rules with a cooldown; Collect prices from multiple providers and show current price plus history; Notify through user-selected channels and expose delivery status.
What scale should I assume for "Design a Price Alert System"?
Plan for: 10 million registered users, 2 million daily active users, and 50 million active alerts; 100 million product observations per day across providers, with a 10x burst during sales; A product is collected every 15 minutes by default; hot products can receive shorter cadences within quota.
What are the main trade-offs in "Design a Price Alert System"?
Polling freshness versus provider limits: Use demand-aware cadence, provider quotas, adaptive backoff, and explicit stale indicators. Observed price versus landed price: Model price, shipping, tax, currency, seller, and variant explicitly and let users choose comparison semantics. Immediate notification versus cooldown: Emit on a rule transition with a cooldown and a durable notification ledger.
What are the core entities in "Design a Price Alert System"?
The core entities are ProductOffer, AlertRule, PriceObservation, NotificationLedger.
What are common mistakes when designing "Design a Price Alert System"?
Scanning every user rule for every provider observation; Overwriting a newer observation with a late response; Ignoring seller, variant, currency, shipping, or tax dimensions.