Paths Subjects Questions Quizzes Pricing Search
Intermediate Open Free

Choosing a Store for a Notifications Service

You are designing a notifications service: 200 million users, each user accumulates up to a few thousand notifications (read/unread), the dominant query is "give me this user's latest 50 notifications", writes arrive from many producers (likes, comments, follows) at ~30,000/s peak, and there is no requirement for joins or ad-hoc analytical queries on this data.

  1. Which storage model best fits this workload, and why?
  2. Design the partition key and sort key (or equivalent) for the dominant query.
  3. What is the one requirement that, if added later, would force you to reconsider the choice?
Solution

1. Storage model

A wide-column store (Cassandra/ScyllaDB) or a key-value/document store with a partition+sort model (DynamoDB) fits well. The access pattern is entirely "per user, most recent N, ordered" — no joins, no ad-hoc queries, high write volume from many independent producers. That is exactly the shape wide-column and DynamoDB are built for: LSM-based write paths absorb 30k/s comfortably, and the query is a single partition range scan. A relational database could serve this too (a notifications table indexed on (user_id, created_at DESC)), but at this write rate and with no relational requirement, it would need sharding by user_id to keep up — which is exactly what the wide-column store gives you for free.

2. Key design

Partition key: user_id. Sort key: a time-ordered value, e.g. created_at or a Snowflake-style ID that sorts by time (notification_id). The dominant query becomes: read the partition for user_id, scan the sort key in descending order, limit 50 — a single efficient range read with no fan-out. Mark read/unread as an attribute on the item (or a separate unread_count counter item) rather than a separate table, since it is always read alongside the notification.

3. What would force reconsideration

A requirement like "notify a user's manager whenever 3+ unread HR notifications accumulate across the org" or any cross-user, ad-hoc, relational query (joins across users, arbitrary filtering not keyed by user_id) would not be servable by this model without scatter-gather or a secondary system. At that point you would keep the wide-column store for the hot per-user read path and add a relational or search store fed by CDC for the cross-cutting query — polyglot persistence, justified by a specific new access pattern rather than adopted upfront.

Share this question

← Back to SQL vs NoSQL & Data Modeling for Scale practice

We use cookies for product analytics to improve OmniAtlas. See our Privacy Policy.