Design News Aggregator
Patterns, Technologies, and Concepts
Key Takeaways
Requirements
You demonstrated strong foundational thinking in this section, correctly identifying availability over consistency tradeoffs, setting concrete latency targets, and accounting for real-world traffic spikes.
-
For read-heavy systems like news feeds, favor availability over consistency using AP systems (per CAP theorem). Users tolerate slightly stale data but will abandon an app that is down or slow.
-
Always anchor latency requirements to a specific number like under 200ms for feed loads. This gives you a concrete target to justify caching strategies, CDN usage, and database indexing decisions later in your design.
-
When estimating scale, account for both steady-state daily active users and spike traffic like breaking news events. Spike traffic can be 5 to 10 times normal load and drives decisions around auto-scaling and rate limiting.
Core Entities
You demonstrated a strong grasp of core entity identification in system design, correctly naming the three key entities for a news aggregator without overcomplicating the model.
- For a news aggregator, the three core entities are Publisher, Article, and User. Publisher creates content, Article is the content itself, and User consumes it. Keeping entities lean like this avoids over-engineering your data model early in the design.
API
You demonstrated a strong grasp of feed API design, handling pagination, filtering, and content scoping well, with only a minor gap around making region an explicit and testable query parameter.
- When a parameter like region influences API behavior, expose it as an explicit query parameter even if you also support implicit fallback derivation from IP or user profile. Explicit parameters make the API easier to test, debug, and reason about because callers can override the derived value directly in the request without needing to fake an IP or change profile settings.
High Level Design
You demonstrated solid ingestion and serving fundamentals across your attempts, and you improved by adding regional database separation, but you consistently left out the concrete details of how region gets attached to data and how a request gets routed to the right regional store.
-
When designing a regional feed, region needs to live explicitly on your data model, either on the Article or Publisher table. Without it, your query has nothing to filter on. A simple ‘region: string’ field on Article lets the feed service do ‘WHERE region = X ORDER BY publishedAt DESC’ to serve the right content.
-
In a multi-region database setup, you need a routing layer that decides which regional database to write to and read from. The region for a request typically comes from user profile data or request context like IP or a header. Without this routing logic, a database-per-region design has no way to direct traffic correctly.
-
When polling RSS feeds repeatedly, you need a uniqueness key like a guid or source article URL to deduplicate articles. Without it, every poll cycle risks inserting duplicate records for the same article. Store the original feed guid as a unique constraint in your articles table and use an upsert to skip or update existing entries.
-
In a news feed schema, storing a thumbnail as a URL string pointing to S3 is the right pattern. The collection service downloads the image, uploads it to object storage, and then saves the resulting S3 URL in the database. This keeps large binary data out of Postgres while still making the URL easily queryable and returnable in API responses.
Deep Dives
You demonstrated strong instincts across most of this section, but had two recurring gaps that needed multiple attempts to close: using atomic database primitives for deduplication and handling replica lag during traffic spikes.
-
For deduplication during ingestion, never use a check-then-write pattern because two concurrent requests can both pass the ‘not exists’ check before either insert completes. Instead, add a unique constraint on the hash column and use a single conditional write like INSERT … ON CONFLICT DO NOTHING. This is atomic in one round-trip, so it is both correct and fast. Also hash only stable fields like title, publisher, and originUrl so minor edits to an article do not create false duplicates.
-
When scaling a Redis read tier during a traffic spike, round-robin across replicas is a good baseline but is not enough on its own. During a breaking news event, a replica can fall behind and serve a stale top of feed. The fix is lag-aware routing where the load balancer tracks replication lag per replica and removes stale replicas from rotation, redirecting those reads to the primary or a fresher replica until the lagging one catches up.
-
For a regional news feed cache, sharding Redis is unnecessary because the hot feed for a region fits on a single node (around 2000 articles). Instead, use one Redis primary that receives writes and multiple read replicas that serve feed reads. This is much simpler to operate than partitioning the feed across nodes, and it scales read throughput linearly by just adding more replicas.
-
For thumbnail image delivery, use a hybrid pre-generate vs on-demand strategy. Pre-generate a small fixed set of resolutions tied to common device classes because CDN cache hit rates are highest with a small number of well-known variants. For rare cases like unusual aspect ratios or test devices, generate on demand and then cache the result at the CDN edge. This keeps storage costs bounded while still handling long-tail cases without pre-computing every possible size.