social
Notifications Feed
A per-user feed read a page at a time, with unread as a sparse marker.
A feed is an item collection that never stops growing, so it is never read whole. This model is about the cursor: a page of notifications, a key to resume from, and an unread marker that only unread items carry.
The model
Notification
One notification, newest sorting last.
- pk
- USER#<userId>
- sk
- NOTIF#<createdOn>#<notificationId>
Attributes: kind (S), actor (S), createdAt (N), unread (S), GSI1PK (S), GSI1SK (S)
Access patterns
- QueryRead a page of the feed
One user's notifications, newest first, a page at a time.
- Query · GSI1Count what is unread
Only the unread notifications, from an index that holds nothing else.
Design notes
The cursor is a key, not an offsetwhy
A page comes back with a LastEvaluatedKey, and the next request passes it as ExclusiveStartKey. There is no page number and no OFFSET: the read resumes at an exact position in the collection, so page fifty costs what page one costs. A relational offset walks and discards everything before it, which is why deep pagination gets slower there and does not here.
Unread is absent, not falsewhy
Read notifications carry neither the unread attribute nor the index keys. That is what makes GSI1 sparse: an item with no GSI1PK is simply not in the index, so the index holds only unread notifications and the badge count is a read of something small rather than a walk of the whole feed. Marking one read means removing its index keys, and it leaves the index on its own - no delete, no sweep.
The page size is the request's businesstrade-off
Limit belongs to the read, not to the table, so the same collection serves a panel showing five and a full page showing fifty. The preview console reads the collection without a Limit, so it returns every notification rather than the first page of one.
Taught in the course
- One query, a whole collection - Items that share a partition key are read together in one Query.
- Read a page, keep the bookmark - Limit caps a page; LastEvaluatedKey is the bookmark you feed back to resume.
One user's notifications, newest first, a page at a time.
Run an operation to see the raw engine response.
The in-browser engine is a preview build. Transactions, vector search, streams, tags and TTL are among the operations it doesn't implement yet.