Design Weather App
In this mock interview, Suman (Senior Engineering Manager, SmartSheet) designs the backend system of a weather app.
Designing a Weather App is a classic read-heavy, data ingestion + aggregation system design problem, where you are asked to build a globally available, low-latency system that serves weather data collected from a large number of sensors and third-party sources.
Unlike transactional systems, the core challenge here is timely data ingestion, aggregation, caching, and fast reads at scale, while tolerating eventual consistency.
In this design, the following trade-offs are central:
- Accuracy vs freshness
- Low latency for reads
- High availability (global service)
- Eventual consistency (acceptable delay of 1–2 minutes)
- Handling high read QPS with comparatively fewer writes
This write-up presents a structured, interview-ready solution aligned with real-world weather platforms.
Step 1: Define the problem
Ask clarifying questions
Weather systems appear simple on the surface but hide significant complexity under scale. Asking clarifying questions early helps define scope and avoid over-engineering.
Some useful clarifying questions include:
-
What scale are we designing for?
Number of users, number of sensors, and global vs regional coverage.
-
What data sources do we support?
Government weather stations, IoT sensors, third-party APIs, satellites?
-
How real-time must the data be?
Is a delay of seconds or minutes acceptable?
-
Do we support historical data and forecasts?
How far back should past data be stored?
-
What granularity is required?
City-level, zip-code level, or precise GPS coordinates?
-
What SLAs are expected for latency and availability?
For this design, we’ll assume a global weather application that aggregates data from hundreds of thousands of sensors, supports current weather, forecasts, and historical data, and serves millions of users daily.
Define functional requirements
At its core, the Weather App exists to collect weather data from sensors and present accurate weather information to users in a fast and reliable manner.
Based on the clarified scope, the system must support the following functionality:
- Ingest weather data from multiple sensor types:
- Temperature
- Humidity
- Air quality
- Wind speed
- Pollen index
- Aggregate and normalize sensor data by location
- Allow users to request weather information for a given location
- Support:
- Current weather
- Weather forecasts
- Past (historical) weather
- Serve weather data to users via APIs or mobile/web clients
These requirements define the Weather App as a data ingestion + read-optimized serving system, rather than a transactional application.
Define non-functional requirements
For data aggregation systems, non-functional requirements often drive architecture more than functional ones. The CAP theorem is especially relevant when reasoning about consistency and availability.
Several key non-functional requirements shape the design.
First, high availability is critical. Users expect weather information to be accessible at all times, even during partial system failures. The target availability is 99.9% or higher.
Second, low latency is important for user experience. Weather data should load quickly, with a target latency of ~150 ms per request.
Third, the system must be globally scalable. It should support users across different regions and time zones, while ingesting sensor data continuously from around the world.
In terms of consistency, strong consistency is not required. Weather data is inherently approximate, and a delay of 1–2 minutes is acceptable for most readings. As a result, the system favors:
- Availability over strong consistency
- Eventual consistency for sensor ingestion
- Read optimization for user queries
This trade-off allows the system to scale efficiently while meeting user expectations.
Estimate the amount of data (Back-of-the-envelope)
Throughput from sensors
Assumptions from the requirements:
- 100,000 sensors
- Each sensor sends data every 5 minutes
Total sensor updates per second:
100,000 sensors / 300 seconds ≈ 333 writes/sec
Each update includes multiple metrics (temperature, humidity, etc.), typically stored as a single record.
User traffic
Assumptions:
- 100 million user requests per day
Requests per second:
100M / 86,400 ≈ 1,000 requests/sec
To account for peak traffic (e.g., during storms or extreme weather):
- Assume 10× burst traffic
- Peak read QPS ≈ 10,000 reads/sec
Read vs write profile
- Writes (sensor ingestion): ~300–400 writes/sec
- Reads (user requests): ~1,000–10,000 reads/sec
This clearly makes the Weather App a read-heavy system.
Data storage estimate
Assumptions:
- Each sensor record ≈ 1 KB
- 100,000 sensors × 288 updates/day ≈ 28.8M records/day
Daily storage:
28.8M × 1 KB ≈ 28.8 GB/day
Yearly storage:
28.8 GB × 365 ≈ ~10 TB/year
This does not include:
- Aggregated summaries
- Forecast data
- Derived analytics
Total storage would realistically be multiple tens of terabytes per year.
For tips on estimating unknowns, check out our Estimation Strategies and Tricks lesson.
Step 2: Design a high-level system
Design the APIs
Once the high-level responsibilities of the weather platform are clear, the next step is to define the APIs that expose weather data to clients and coordinate data flow between internal services. These APIs act as the contract between end-user applications, edge infrastructure (CDN), and backend services, so they must be predictable, cache-friendly, and optimized for read-heavy workloads.
Unlike transactional systems, a weather platform is dominated by read traffic, with most users repeatedly requesting current conditions and short-term forecasts for the same locations. As a result, the API layer is designed to maximize cacheability, minimize backend fan-out, and clearly separate real-time data from historical and predictive workloads.
Rather than exposing a single monolithic API, the system is decomposed into domain-oriented services, each aligned with a distinct access pattern: current weather, forecasts, historical data, and analytics-driven insights.
Current weather service
The Current Weather Service is responsible for serving real-time or near real-time weather conditions for a given location. This includes temperature, humidity, wind speed, precipitation, and alert flags.
This service sits directly behind the CDN and is heavily cached, since many users query the same city or coordinates repeatedly within short time windows. Internally, it reads from an in-memory cache first and falls back to a time-series store only on cache misses.
APIs
GET /weather/current?lat=&lng=GET /weather/current/city/{city_id}
These APIs are intentionally simple and idempotent, making them ideal for aggressive CDN caching. Responses typically include a short TTL to balance freshness with performance.
Forecast service
The Forecast Service provides short-term and long-term weather predictions, such as hourly forecasts for the next 24 hours or daily forecasts for the next 7–10 days.
Unlike current conditions, forecasts change less frequently and are usually generated in batches using predictive models or external weather providers. This makes forecast data highly cacheable and suitable for serving directly from edge locations.
APIs
GET /weather/forecast/hourly?lat=&lng=&hours=GET /weather/forecast/daily?lat=&lng=&days=
Internally, this service reads from a forecast database populated by offline or nearline computation jobs. Because forecasts are precomputed, the service prioritizes low latency reads over real-time accuracy, accepting that predictions may be updated periodically rather than continuously.
Historical weather service
The Historical Weather Service allows users and internal systems to query past weather data for analytics, comparisons, and trend analysis. Typical use cases include viewing last week’s temperatures, comparing seasonal patterns, or supporting downstream data science workflows.
This service is backed by a time-series database optimized for range queries over time windows.
APIs
GET /weather/history?lat=&lng=&from=&to=GET /weather/history/city/{city_id}?from=&to=
Because historical queries can span large time ranges, this service enforces stricter limits on query size and latency expectations. It is not placed directly behind the CDN and is primarily consumed by power users, internal dashboards, or analytics systems.
Sensor ingestion API (Internal)
Weather data ingestion is handled through a dedicated internal API that receives telemetry from physical sensors, third-party providers, or IoT pipelines.
These APIs are write-heavy and not exposed to end users. They prioritize throughput and durability over latency.
APIs
POST /ingest/weather/readingPOST /ingest/weather/batch
Incoming data is validated, normalized, and forwarded to the ingestion pipeline, which persists it into the time-series database and asynchronously updates derived views such as current conditions and aggregates.
Forecast intelligence / LLM service (Optional)
For advanced use cases such as natural-language summaries, weather explanations, or impact analysis (e.g., “Will it rain during my commute?”), the system exposes a higher-level API powered by analytical models or LLM-based services.
This service reads from the data lake and forecast stores rather than real-time systems.
APIs
GET /weather/insights?lat=&lng=&query=
Because these requests are computationally expensive and non-critical, they are rate-limited and often processed asynchronously.
Design the data model (core entities)
Once the system responsibilities and high-level architecture are clear, the next step is to define a data model that supports the weather platform’s access patterns. Unlike transactional systems, a weather application is fundamentally read-heavy, time-series driven, and append-only in nature. Most data is written once and read many times, often across different time windows and aggregations.
At a high level, the system manages three primary categories of data: real-time sensor observations, historical weather data, and forecast data. Each category has different latency, retention, and query requirements, which strongly influences how and where the data is stored.
Real-time weather data
Real-time weather data originates from physical sensors such as weather stations, satellites, and IoT devices. These sensors continuously stream observations like temperature, humidity, wind speed, and precipitation.
This data is high-write, time-ordered, and immutable. Once a reading is recorded, it is never updated—only new data points are appended. Because of this access pattern, real-time weather data is best stored in a time-series database, which is optimized for sequential writes, time-based queries, and down-sampling.
Each record represents a single observation at a specific timestamp and location. Queries typically ask for “latest weather at a location” or “weather in the last X minutes,” both of which are efficiently supported by time-series storage.
Historical weather data
Historical weather data is derived from the same sensor streams but is accessed very differently. Users and internal analytics systems often request data across long time ranges—days, months, or even years.
While recent historical data remains in the time-series database for fast access, older data is gradually moved into a data lake. The data lake serves as a low-cost, highly durable storage layer for long-term retention, analytics, and machine learning training.
This separation allows the system to keep hot data fast and cold data cheap, without compromising query flexibility for advanced use cases like climate trend analysis.
Forecast data
Forecast data is produced by prediction pipelines that combine historical data, real-time observations, and machine learning models (including the Forecast LLM shown in the architecture).
Forecasts differ from raw sensor data in two key ways. First, they are derived data, not direct observations. Second, they are periodically recomputed as new data arrives and models improve.
Forecast results are stored in a dedicated database optimized for read-heavy access, since forecast data is frequently requested by users but updated relatively infrequently (for example, every hour).
Core entities (Logical schema)
At a conceptual level, the system works with the following entities:
- Location: id, latitude, longitude, region, timezone
- WeatherObservation: location_id, timestamp, temperature, humidity, wind_speed, precipitation, pressure, source
- Forecast: location_id, forecast_time, target_time, temperature, precipitation, confidence_score, model_version
- Sensor: id, type, location_id, status, metadata
- Alert (optional): location_id, alert_type, severity, start_time, end_time, description
This data model reflects the system’s core principle: time is the primary dimension, and almost all queries are scoped by location and time range.
High-level architecture
At a high level, the weather system is designed as a globally distributed, read-heavy platform optimized for low latency and high availability.
All user traffic—whether from mobile apps, web clients, or third-party integrations—first flows through a CDN, which caches static assets and frequently accessed responses at edge locations. From there, requests enter the system through a load balancer, which distributes traffic across healthy backend services.
Behind the load balancer, traffic is routed to specialized services based on request type: current weather, forecast data, or historical queries. On the ingestion side, sensor data flows through AWS IoT and ingestion pipelines into time-series storage and long-term data lakes.
This clear separation between read paths and write paths allows the system to scale independently in each dimension.

High-level request flows
Current weather flow
When a user opens the weather app and requests the current conditions for a location, the request first hits the CDN. If the data is already cached and still fresh, the response is served immediately, resulting in extremely low latency.
If the request is not served from cache, it flows through the load balancer to the Current Weather Service. This service is optimized for fast reads and first checks an in-memory cache that stores the most recent observation per location.
If a cache hit occurs, the service returns the response immediately. On a cache miss, the service queries the time-series database for the latest data point for that location, returns the result to the client, and updates the cache for future requests.
This flow ensures that the most common queries—“What’s the weather right now?”—are served quickly and efficiently, even under heavy load.
Forecast flow
Forecast requests follow a similar path but rely on different storage. Requests pass through the CDN and load balancer before reaching the Forecast Service.
The Forecast Service reads precomputed forecast data from a forecast database, which is populated by offline and near-real-time prediction pipelines. These pipelines consume historical data from the data lake and recent observations from the time-series database, then generate updated forecasts using statistical models and LLM-based predictors.
Because forecast data is read-heavy and changes at predictable intervals, it is highly cacheable at both the CDN and service layer. Slight staleness is acceptable, as forecasts are inherently probabilistic.
Past weather flow
When users request historical weather—for example, last week’s rainfall or last year’s temperature trends—the request is routed to the Past Weather Service.
For recent history (such as the last few days), the service queries the time-series database directly. For older ranges, it transparently falls back to the data lake, which stores long-term historical data in a query-friendly format.
This tiered access pattern allows the system to deliver both fast recent queries and deep historical analysis without overloading a single storage system.
Sensor ingestion flow
On the write side, sensors continuously push data into AWS IoT, which authenticates devices and manages connectivity at scale. From there, data flows into an ingestion pipeline that validates, normalizes, and enriches incoming readings.
Validated observations are written to the time-series database for immediate availability. In parallel, the same data is streamed into the data lake for long-term storage and analytics.
This dual-write pattern is intentional: the time-series database powers real-time experiences, while the data lake supports offline processing and model training.
Step 3: Deep dive and trade-offs
Why time-series databases for weather data?
Weather data is inherently sequential and time-indexed. Each observation is immutable, ordered, and queried primarily by time range.
Time-series databases are designed for exactly this workload. They support high write throughput, efficient compression, and fast time-based queries. Compared to relational databases, they significantly reduce storage overhead and improve query performance for time-based aggregations.
The trade-off is flexibility. Time-series databases are not ideal for complex joins or transactional updates. However, since weather data rarely requires updates or relational queries, this trade-off is well aligned with the domain.
Why aggressive caching and CDN usage?
The vast majority of weather queries are reads, and many users request the same data for popular locations. Serving all of these requests directly from backend services would be wasteful and expensive.
By using CDNs and in-memory caches, the system reduces backend load, lowers latency, and improves global performance. The trade-off is potential staleness, but in practice, weather data tolerates small delays without harming user trust.
Why separate forecast generation from serving?
Forecast computation is computationally expensive and often involves large datasets and machine learning models. Serving user requests should never depend on running these models synchronously.
By precomputing forecasts and storing the results in a read-optimized database, the system decouples heavy computation from low-latency serving. This improves reliability and allows forecast models to evolve independently of the serving layer.
Step 4: Scaling considerations
As usage grows, the primary scaling pressure comes from read traffic rather than writes. Popular cities can generate massive request volumes during extreme weather events.
The system mitigates this by scaling horizontally at multiple layers: CDN edges, stateless backend services, and replicated read stores. Write scaling is handled through partitioned time-series storage and parallel ingestion pipelines.
Because each location’s data is largely independent, the system naturally supports sharding by geographic region, further improving scalability and fault isolation.
Final summary
This weather system architecture is designed to deliver fast, reliable, and globally scalable weather data by aligning storage and services with real-world access patterns.
Real-time data flows efficiently from sensors to users, forecasts are computed offline and served at scale, and historical data is retained for deep analysis—all while maintaining low latency and high availability.
By prioritizing read performance, embracing eventual consistency where appropriate, and leveraging time-series and data lake storage, the system achieves a practical and production-ready balance suitable for a large-scale weather platform.