Real-time features feel like magic to users but the implementation is surprisingly straightforward once you understand the architecture. Here's exactly how I built the notification system powering SyntaxAndStories.
The Problem
Most social platforms need to tell you things instantly — someone liked your post, someone followed you, you got a new comment. Polling the server every few seconds is wasteful and slow. WebSockets solve this by keeping a persistent connection open between the browser and server.
The Stack
- Django Channels — extends Django to handle WebSockets
- Redis — acts as the channel layer, routing messages between consumers
- Vanilla JavaScript — on the frontend
The Architecture
When a user logs in, the browser opens a WebSocket connection to a NotificationConsumer. This consumer joins a group named after the user — notifications_jay for example. When any part of the application needs to notify Jay, it sends a message to that group. Redis routes it to the right consumer, which pushes it to the browser instantly.
class NotificationConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.user = self.scope['user']
self.group_name = f'notifications_{self.user.id}'
await self.channel_layer.group_add(
self.group_name,
self.channel_name
)
await self.accept()
async def notify(self, event):
await self.send(text_data=json.dumps(event['data']))
Sending Notifications
From anywhere in the codebase — a view, a signal, a Celery task:
channel_layer = get_channel_layer()
async_to_sync(channel_layer.group_send)(
f'notifications_{user.id}',
{
'type': 'notify',
'data': {
'message': 'Someone liked your post',
'type': 'LIKE'
}
}
)
The Frontend
const socket = new WebSocket(`wss://syntaxandstories.dev/ws/notifications/`);
socket.onmessage = (e) => {
const data = JSON.parse(e.data);
showToast(data.message);
updateUnreadCount();
};
What I Learned
The hardest part wasn't the WebSocket code — it was handling disconnections gracefully and making sure the channel layer stayed in sync across multiple server instances. Redis solves the multi-instance problem elegantly.
If you're building any kind of social or collaborative feature, Django Channels is worth the learning curve.
Loading thoughts...