Design a Weather App
A weather app is a service that answers forecast questions for places from data gathered upstream. The load is huge and the answers repeat, so one fresh forecast serves a whole city at once.
The ask
A user asks for the forecast at a place. The answer covers now, the next hours and the next days.
Severe weather warnings reach users in affected places fast. A late warning has no value.
The service buys or gathers forecast data from upstream providers. Upstream data is the raw material, not the product.
Freshness needs vary. A warning ages in minutes, and a weekly outlook ages in hours.
Estimate the scale
Requests run at 100,000,000 a day.
100,000,000 requests / 86,400 seconds = 1,157 requests per second.
Forecasts cover 10,000 locations. Each location is refreshed every 10 minutes.
10,000 locations / 600 seconds = about 17 upstream fetches per second.
The gap between the two rates is the design. Thousands of askers share each fetched forecast.
API and data
The forecast operation takes a place or coordinates and a time range. It returns the forecast and the time it was made.
The warning operation takes a place. It returns any active severe weather warnings there.
A forecast record holds a location, a made-at time, an expiry time and values by hour. Values cover temperature, rain chance and wind.
A location record maps names and coordinates to one forecast location. Nearby askers land on the same location.
A warning record holds a location, a kind, a severity and an end time. Warnings bypass the normal refresh rhythm.
High-level design
A fetch service pulls forecasts for all locations on a schedule. It writes each forecast into a cache keyed by location.
App servers answer user requests from the cache. A request almost never waits on an upstream fetch.
A warning service watches upstream warning feeds. A new warning is stored and pushed to users in its location at once.
Push here means the service sends the warning to the phone without the user asking. Phones also check for warnings when the app opens.
Old forecasts stay in storage for a short history. The history shows how a forecast changed over a day.
Deep dive: freshness against load
A cached forecast expires after 10 minutes. The next scheduled fetch replaces it before most users notice any age.
A storm can outrun the schedule. The warning path ignores the schedule and updates the location at once.
Popular places get the same treatment as quiet ones. Equal refresh keeps the upstream rate flat and predictable.
An on-demand fetch fires only for a location with no cached copy. One fetch fills the cache for every later asker.
Concurrent askers share that one fetch. The rest wait a moment or receive the previous copy with its age shown.
Deep dive: when upstream fails
An upstream provider goes down for an hour. Forecasts age past their expiry.
The service keeps serving the last forecast and shows its age. A stale answer with an honest age beats no answer.
A second provider fills priority locations first. Big cities and warning areas refresh before quiet places.
Warnings never go stale silently. If the warning feed fails, the app says warnings may be missing for that place.
Place matching
Coordinates from a phone rarely land exactly on a stored location. The service maps them to the nearest covered location.
Mountains and coasts break simple distance. Two near places can have very different weather across a ridge.
Location records carry the area each forecast stands for. Matching uses the area, not distance alone.
A wrong match is a visible product failure. Users compare the answer with the sky outside.
Evaluation and trade-offs
Scheduled fetching makes upstream load tiny and flat. The price is an answer that can be minutes old.
Warnings take a separate fast path. One rhythm cannot serve both slow forecasts and urgent warnings well.
Shared forecasts are the core idea. A weather app scales because a city reads one forecast together.
The cache is the product surface. Upstream stays a replaceable supplier behind it.
Scale at a glance
| Measure | Figure |
|---|---|
| Requests a day | 100,000,000 |
| Requests per second | 1,157 |
| Locations covered | 10,000 |
| Upstream fetches per second | 17 |
Exercise
Why does the design fetch upstream forecasts on a schedule instead of asking upstream for every user request?