Signed-in pages stop counting from the beginning
Every page you load used to regroup your whole notification history just to number the unread badge. Now it starts at your oldest unread one, and pages come back in a fraction of the time.

Sign in and click your own profile. The page used to hang while the server recounted a year of notifications for the number in the corner. Now the badge is there almost before the avatar is, and the log, follower lists, saved posts, and moderation queue all snap the same way.
Credit goes to HelgeSverre, who taught the count to start late. It looks up the timestamp of your oldest unread notification, then groups only from there, with a new index that holds just the unread rows. With nothing unread, it stops after one query. His stress rig builds 50,000 developers, 600,000 commits, 400,000 replies, and 1.5 million notifications, and on it a busy profile drops from 1399 milliseconds to 345.
He also stopped walking reply chains to the top of a thread. Every reply already records the commit that started its thread, so a reply or mention now finds its group with one join instead of a recursive scan over every commit, twice. A busy thread page falls from 1330 milliseconds to 120. The bot that greets hello-world commits now records its thread too, so its greeting counts toward that thread's trending score.
One catch. The count still begins at your oldest unread notification, so the shortcut pays off only if you read. Let thousands pile up unread and every page regroups them all. The badge is cheap because you keep up, not because the work is gone.
Also in this story
Key files · #264
- app/
Queries/ NotificationGroupsQuery.php - database/
migrations/ 2026_10_16_200000_add_unread_index_to_notifications_table.php - app/
Actions/ CreateWorldReply.php - config/
database.php - database/
seeders/ StressSeeder.php - app/
Http/ HandleInertiaRequests.phpMiddleware/ - app/
Queries/ NotificationBuilder.php - tests/
Unit/ NotificationGroupsQueryTest.phpQueries/