Building Real-Time WebSocket Notifications for Your Website

Real-Time WebSocket Notifications for Your Website

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Our competencies:

Frequently Asked Questions

Latest works

  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1284
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1240
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    982
  • image_crm_chasseurs_493_0.webp
    CRM development for Chasseurs
    1031
  • image_website-sbh_0.webp
    Website development for SBH Partners
    1104
  • image_website-_0.webp
    Website development for Red Pear
    553

Real-Time WebSocket Notifications for Your Website

Imagine: a user places an order but doesn't receive a status update until they refresh the page. Or a moderator doesn't see a new comment until a reload. This isn't just an inconvenience — it's a loss of conversion and trust. We are a team of engineers with 5+ years of experience, developing instant notification systems using WebSocket that deliver events in milliseconds, without unnecessary server requests. Across 80+ projects, we've built a reliable architecture that withstands peak loads.

Why WebSocket Instead of Polling?

With polling, the client queries the server every N seconds. With 10,000 users requesting status every 5 seconds, the server receives 120,000 requests per minute — a huge load with up to 5 seconds of delay. WebSocket establishes a persistent connection: data arrives instantly, and traffic is reduced tenfold. We use WebSocket not only for chats but also for order status alerts, marketplace notifications, ticket systems, and any scenario requiring reactivity.

What Problems We Solve

Excessive Polling and Server Load

Switching to WebSocket cuts HTTP requests from hundreds of thousands to a few hundred per hour. On one project, after replacing polling with WebSocket, backend load dropped by 80%, and infrastructure costs halved — saving roughly $2,400 per month (based on current exchange rates).

Delivering Notifications to Offline Users

If a user closes a tab but still wants to receive notifications, we store them in the database and send them upon the next connection. Our solution uses Redis Pub/Sub with persistence. Additionally, we send push notifications via FCM/APNS. Offline delivery works with a delay of no more than 100 ms after reconnection.

Scaling to Thousands of Connections

A single application can handle tens of thousands of WebSocket connections. We scale using Redis or Kafka so connections work across multiple instances. Load testing confirms stability up to 50,000 concurrent connections.

How We Ensure Delivery to Offline Users

In a typical architecture (see code below), we store a mapping of userId → set<socketId>. When a user connects, we check for undelivered notifications in the database and deliver them. If the user is offline, the notification is saved with a pending status.

// notification-ws.service.ts class NotificationWebSocketService { private userSockets = new Map<string, Set<string>>(); async onConnect(socket: Socket, userId: string) { if (!this.userSockets.has(userId)) { this.userSockets.set(userId, new Set()); } this.userSockets.get(userId)!.add(socket.id); socket.join(`user:${userId}`); const pending = await this.notificationRepo.findUndelivered(userId); if (pending.length > 0) { socket.emit('notifications:batch', pending); await this.notificationRepo.markDelivered(pending.map(n => n.id)); } } async sendToUser(userId: string, notification: Notification): Promise<void> { const isOnline = this.userSockets.has(userId) && this.userSockets.get(userId)!.size > 0; if (isOnline) { io.to(`user:${userId}`).emit('notification:new', notification); await this.notificationRepo.markDelivered([notification.id]); } else { await this.notificationRepo.save({ ...notification, status: 'pending' }); await this.pushService.send(userId, notification); } } } 

Why the React Hook useNotifications Simplifies Integration?

On the frontend, we've prepared a React hook that subscribes to Socket.IO events. It automatically handles adding new notifications, counting unread ones, and marking as read. All a developer needs to do is call useNotifications() and render the list.

// hooks/useNotifications.ts function useNotifications() { const [notifications, setNotifications] = useState<Notification[]>([]); const [unreadCount, setUnreadCount] = useState(0); const socket = useSocket(); useEffect(() => { if (!socket) return; socket.on('notification:new', (notification: Notification) => { setNotifications(prev => [notification, ...prev]); setUnreadCount(prev => prev + 1); showToast(notification); }); socket.on('notifications:batch', (batch: Notification[]) => { setNotifications(prev => [...batch, ...prev]); setUnreadCount(prev => prev + batch.filter(n => !n.readAt).length); }); return () => { socket.off('notification:new'); socket.off('notifications:batch'); }; }, [socket]); const markAsRead = async (id: string) => { await fetch(`/api/notifications/${id}/read`, { method: 'POST' }); setNotifications(prev => prev.map(n => n.id === id ? { ...n, readAt: new Date() } : n) ); setUnreadCount(prev => Math.max(0, prev - 1)); }; const markAllAsRead = async () => { await fetch('/api/notifications/read-all', { method: 'POST' }); setNotifications(prev => prev.map(n => ({ ...n, readAt: n.readAt || new Date() }))); setUnreadCount(0); }; return { notifications, unreadCount, markAsRead, markAllAsRead }; } 

Notification Types and Their Visualization

We define typical events for a typical application:

Type Description Icon
order:status_changed Order status changed 📦
message:received New chat message 💬
mention:comment Mention in comment @
task:assigned New task assigned
payment:processed Payment processed 💳
system:alert System warning ⚠️

For each type, you can configure the display duration of the Toast and the click action.

Comparison: Polling vs WebSocket

Parameter Polling WebSocket
Latency 1–5 sec < 100 ms
Server Load High Low
Traffic ~120,000 requests/min ~1,000 messages/min
Scaling Difficult with many clients Easy with Redis/Kafka

What's Included in the Work

  • Architectural documentation: interaction scheme, stack selection (Socket.IO, Redis, PostgreSQL).
  • Backend service implementation: WebSocket handler, authorization integration, disconnect handling.
  • Frontend module: React hook, bell component, Toast notifications.
  • Push notification integration (FCM/APNS) — optional.
  • Load testing: verification up to 50,000 concurrent connections.
  • Deployment instructions and team training.

We guarantee stable operation under peak loads — 5+ years of experience in real-time solutions and 80+ completed projects speak for themselves. Contact us to discuss your project — we'll help you choose the optimal architecture and implement it turnkey. Get a consultation now.

Our Process

  1. Analysis — study the current architecture, identify notification scenarios, and assess load.
  2. Design — select protocol (WebSocket, SSE), message broker (Redis, Kafka), storage scheme.
  3. Implementation — build backend + frontend, cover with tests.
  4. Integration — connect to existing project (Laravel, Nest.js, Django, etc.).
  5. Deployment and monitoring — set up CI/CD, logging, alerts.

Estimated Timelines

Basic implementation (WebSocket + offline storage + React hook) — 7–10 days. With push notifications and load testing — 2–3 weeks. Cost is calculated individually — write to us, we'll estimate your project.

WebSocket API (MDN)