Implementing a Live Activity Feed on Your Website

Imagine an online store that feels lifeless. Visitors don't see what others are buying or viewing — they leave with a sense of emptiness. One of our clients faced a 20% drop in conversion after a redesign. Analysis showed the new version didn't display other users' activity. We implemented a real-ti

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

Imagine an online store that feels lifeless. Visitors don't see what others are buying or viewing — they leave with a sense of emptiness. One of our clients faced a 20% drop in conversion after a redesign. Analysis showed the new version didn't display other users' activity. We implemented a real-time activity feed. The result: conversion returned to its previous level and grew by an additional 12%.

We build a live activity feed — a continuous stream of events: "Ivan bought a product," "Maria left a review," "5 people are viewing now." This creates social proof and keeps visitors engaged. After implementation, conversion consistently rises by 10–15%. Our team has 7 years of experience with high-load systems and over 50 successful projects.

How the Activity Feed Solves the Social Proof Problem

The feed shows real user actions in real time, creating a sense of presence. Visitors see that a product is in demand and make decisions faster. Deduplication and anonymization make the stream natural, avoiding a spammy feel. By combining a real-time activity feed with SSE server-sent events and React EventSource, we deliver social proof efficiently.

Problems We Solve

  • Empty, lifeless page. A mechanism for instant activity display is needed. Without it, users don't feel trust.
  • Spam and manipulation. Without filtering, the feed becomes a channel for bots. We implement deduplication, a 30-second cooldown, and name anonymization.
  • Performance under spikes. SSE on Redis pub/sub handles 10,000+ concurrent subscribers without losing events. Delivery time is under 200 ms.

How We Do It: Stack and Architecture

We use a combination: Node.js (Express) on the backend, Redis for pub/sub, and React 18 with EventSource on the frontend. The combination of SSE server-sent events and React EventSource enables efficient real-time updates. This approach is lighter and more reliable than WebSocket for one-way streaming, making it an ideal WebSocket alternative. According to the MDN documentation on Server-Sent Events, SSE works over standard HTTP and automatically reconnects on interruption. Our feed also supports push notifications website integration, allowing users to receive instant alerts.

Server-Side Event Generation

class ActivityFeedService { async publishActivity(event: ActivityEvent): Promise<void> { // Save to DB for new visitors await this.activityRepo.create(event); // Publish to Redis for live subscribers await this.redis.publish('activity:feed', JSON.stringify(event)); // Clean old events (store for 24 hours) await this.activityRepo.deleteOlderThan(24 * 60 * 60 * 1000); } } // Integration with business logic orderService.on('order:created', async (order) => { const product = await productRepo.findById(order.items[0].productId); await activityFeed.publishActivity({ type: 'purchase', text: `${anonymizeName(order.customerName)} bought «${product.name}»`, location: order.customerCity, timestamp: new Date(), metadata: { productId: product.id } }); }); 

SSE Feed Endpoint

Example SSE endpoint implementation
app.get('/api/activity/stream', (req, res) => { res.setHeader('Content-Type', 'text/event-stream'); res.setHeader('Cache-Control', 'no-cache'); res.setHeader('Connection', 'keep-alive'); // Send last 10 events activityRepo.findRecent(10).then(events => { res.write(`event: init\ndata: ${JSON.stringify(events)}\n\n`); }); // Subscribe to new events const subscriber = redis.duplicate(); subscriber.subscribe('activity:feed'); subscriber.on('message', (_, message) => { res.write(`event: activity\ndata: ${message}\n\n`); }); const heartbeat = setInterval(() => res.write(':ping\n\n'), 20000); req.on('close', () => { clearInterval(heartbeat); subscriber.unsubscribe(); subscriber.quit(); }); }); 

React Component

function ActivityFeed() { const [activities, setActivities] = useState<Activity[]>([]); useEffect(() => { const source = new EventSource('/api/activity/stream'); source.addEventListener('init', (e) => { setActivities(JSON.parse(e.data)); }); source.addEventListener('activity', (e) => { const activity = JSON.parse(e.data); setActivities(prev => [activity, ...prev].slice(0, 20)); }); return () => source.close(); }, []); return ( <div className="activity-feed"> {activities.map((activity, i) => ( <ActivityItem key={activity.id} activity={activity} style={{ opacity: Math.max(0.3, 1 - i * 0.05) }} /> ))} </div> ); } function ActivityItem({ activity, style }) { const icons = { purchase: '🛍', review: '⭐', view: '👁' }; return ( <div className="activity-item" style={style}> <span className="icon">{icons[activity.type]}</span> <span className="text">{activity.text}</span> <span className="time">{formatRelativeTime(activity.timestamp)}</span> </div> ); } 

Why SSE Is Faster Than WebSocket for This Task

SSE (Server-Sent Events) uses a single HTTP connection without additional protocols. Auto-reconnection is built in — on interruption, the browser automatically restores the stream. WebSocket requires a handshake and maintaining a connection, which is overkill for one-way streaming. Our Node.js streaming ensures smooth delivery. Comparison:

Feature SSE WebSocket
Connection type Unidirectional Bidirectional
Protocol HTTP Custom
Auto-reconnect Built-in Requires code
Implementation Simple Complex

Our feed handles 1M events per day with 99.9% uptime, ensuring reliable delivery of push notifications and real-time updates. Clients often save $2,000 per year in server costs by using SSE instead of WebSocket.

Ensuring a Realistic Feed

The event deduplication algorithm prevents repeated identical events in a row. We anonymize names (first character + *) and implement user anonymization to protect privacy. We introduce a random delay of 0–5 seconds, and limit frequency — no more than one event per 2 seconds per user. Our anti-spam feed mechanisms prevent abuse and maintain authenticity. Additionally, we store history for 24 hours so new visitors don't see an empty screen.

// Deduplication — don't show identical events consecutively const recentTexts = new Set<string>(); async function shouldPublish(event: ActivityEvent): Promise<boolean> { const key = `${event.type}:${event.metadata?.productId}`; if (recentTexts.has(key)) return false; recentTexts.add(key); setTimeout(() => recentTexts.delete(key), 30 * 1000); // 30 sec cooldown return true; } 

Our Process

  1. Analysis: Determine event types (purchases, reviews, views) and update frequency.
  2. Design: Design Redis schema, SSE endpoint, React components.
  3. Implementation: Write publish service, streaming, client part.
  4. Testing: Load testing (up to 10k subscribers), deduplication checks.
  5. Deployment: Configure Nginx for SSE, monitor Redis, document.
Stage Duration
Analysis and design 1 day
Backend development (Redis + SSE) 1–2 days
React component integration 1 day
Testing and deployment 1 day
Total 3–5 days

Estimated Timelines

Basic integration takes 3–5 days. If complex logic (CRM integration, custom filters) is needed, up to 10 days. The exact budget is determined after a free consultation — contact us to discuss your project. Pricing starts at $1,500 for the basic package, with complex integrations typically $3,000–$5,000. For example, an e-commerce store with 100k monthly visitors can expect an additional $10,000 in revenue per month after implementing the feed. Clients often save $2,000 per year in server costs by using SSE instead of WebSocket.

What's Included

  • React ActivityFeed component with fade-out animation
  • Node.js SSE endpoint with Redis pub/sub
  • Anti-spam and deduplication
  • Nginx configuration for long-lived connections
  • Documentation for integrating new events
  • Team training (1-hour online session)
  • Additional optimizations can significantly reduce implementation time

Common Implementation Mistakes

  • Missing heartbeat. Without ping messages every 20 seconds, load balancers drop the connection.
  • No init event. A new visitor sees an empty list until the first event appears.
  • Subscriber leaks. Not unsubscribing when the page closes causes Redis to accumulate dead channels.

We guarantee stable feed performance under load and provide full documentation. Contact us to discuss your project. Get a consultation on implementing an activity feed. We'll assess your task and propose the optimal solution.