I use a notifications
table and a subnotifications
table, and I am also using queues so it runs in the background when a user posts something. When a user has 10 followers and they create a post, the notifications
table gets a single entry which includes the post data for the notification, and the subnotifications
table gets 10 entries (one subnotification per follower, each referring to the id of the notification, so we don't have to repeat the notification data 10 times, with a read_at
to know if it was read or not by that follower).
This is quick and works great without any issues. However, when testing with 1 million followers, it takes about ~6 hours to insert the subnotifications for one post! This of course is not acceptable, as it is takes too long to insert 1 million subnotifications, one per follower. Imagine that same user posts 10 posts, that'll be like ~60 hours of inserting and 10 million subnotification rows.
I just want followers to know there is a new post if they didn't read it yet. Is there a better, more efficient way that scales?
UPDATE: Stuck with current approach see below...
If a follower $user
has 100 leaders they follow (which they followed at different created_at
timestamps of course in the followers table), what would the correct query be to know about leader new posts from the time the follower followed each leader? I get stuck at created_at
with this pseudo code:
// Assume `leader_id` is a column in the notifications table
DB::table('notifications')
->whereIn('leader_id', $leaderIds)
->where(`created_at`, '>', $whatTimestampsGoHere)
->paginate(20);
There is 100 different timestamps and I am stuck on how to solve this one correctly and efficiently. Any ideas?
As stated in the comments, you can reduce the inserts, if you only insert to the child table i.e. subnotifications
when the user reads it and not on creating it on the notification creation, which avoids that issue.
When trying to check if user has seen the notification, just check if they exist in subnotifications
for the user in question and the notification.
Also as said, when fetching notifications to show to users fetch them from notifications
but limit the notifications to the notifications created after the user started following so that new users don't get flooded with notifications.