Build a scalable real-time notification system in Node.js with Socket.io — rooms, targeted delivery, persistence, and horizontal scaling.

Abdur Razzak
Full-Stack Web Developer
A production notification system has multiple layers: the event source (a user action or server event that triggers the notification), the notification service (creates and stores the notification in the database), the delivery layer (sends the notification to connected clients via WebSocket), and the client UI (receives the notification and updates the badge count and notification list).
Create an HTTP server with http.createServer(app) and pass it to Socket.io: new Server(httpServer, { cors: { origin: process.env.CLIENT_URL } }). Emit events to specific users using Socket.io rooms — each user joins a room named by their user ID upon connection. Your event handlers can emit to any user's room: io.to(userId).emit('notification', notificationData).
Persist notifications to MongoDB so users who were offline receive them on next login. Create a Notification schema with fields: recipient (user ID), type (string enum), message, link, isRead (boolean), and createdAt. When a notification event occurs, save to MongoDB AND emit via Socket.io simultaneously. On login, fetch unread notifications from the database to populate the notification center.
On the React client, connect to Socket.io on app load (or after login). Listen for notification events and append them to local state. Display a notification bell icon with an unread count badge. Clicking the bell opens a dropdown showing recent notifications. Mark notifications as read when the user opens the dropdown (send a markAllRead event to the server, which updates MongoDB and resets the badge).
Support multiple notification types: follow, like, comment, mention, order_update. Each type has a message template and a destination link. In the React client, clicking a notification navigates to the relevant content (a post, an order, a user profile) using the link field. Mark the notification as read when navigating. Group similar notifications: '3 people liked your post' instead of three separate notifications.
When you scale to multiple Socket.io server instances, a notification emitted on server A won't reach users connected to server B. Use @socket.io/redis-adapter to broadcast across instances via Redis Pub/Sub. All servers subscribe to the same Redis channel; when one server emits an event, Redis broadcasts it to all other servers, which then emit it to their connected clients. This enables horizontal scaling with minimal complexity.