Adil AmeeqFull-Stack Developer
Real-time system

Real-Time Chat Application

Messaging with presence, media and delivery states

A messaging application built on Socket.IO and Redis with one-to-one and group conversations, media messages, presence, typing indicators and delivery and read states.

Abstract mockup of a chat interface showing a conversation list, message bubbles and a presence indicator
Representative interface mockup — this system cannot be shown publicly.
Overview

What this system is

Chat looks simple until the network misbehaves. This project focused on the parts users notice when it goes wrong: whether a message was actually delivered, whether the other person is online, what happens when the connection drops mid-send, and whether the conversation looks the same after a reload.

Category
Real-time system
Technologies
Socket.IONode.jsRedisMongoDBMedia storage
Client
Client details withheld
The challenge

What was actually wrong

  • Messages must not be silently lost when a connection drops between send and acknowledgement.
  • Presence held in the memory of a single server process cannot survive a restart or scale to more than one instance.
  • Media messages need upload, storage and delivery that do not block the message channel or bloat the database.
  • Conversation history has to be consistent across devices and after reconnection, without re-sending everything.
The solution

How it was solved

  • A message lifecycle with explicit states — sending, sent, delivered, read — acknowledged by the server so the client can retry rather than assume.
  • Presence and socket session state stored in Redis, making the socket layer restart-safe and horizontally scalable.
  • Rooms per conversation, with authentication and membership checked when joining rather than trusted from the client.
  • Media uploaded separately to object storage, with only references travelling through the message channel.
  • Reconnection logic that requests missed events since the last known message, instead of reloading whole conversations.
  • Persistence in MongoDB with indexes shaped around the two queries that matter: recent messages in a conversation, and a user's conversation list.
Architecture

How the system is put together

The parts, and why each one is there.

  1. 01Node.js server with a Socket.IO gateway and REST endpoints for history and uploads.
  2. 02Redis for presence, socket sessions, typing state and unread counters.
  3. 03MongoDB for messages, conversations and membership.
  4. 04Object storage (S3-compatible / MinIO) for media, referenced by key from messages.
  5. 05Token authentication verified on socket connection, not only on HTTP.
Key features

What it does

The functionality that carries the system, described from the user's point of view.

  • One-to-one and group chat

    Conversations with membership rules and per-room event routing.

  • Media messages

    Images, documents and other attachments uploaded to object storage and referenced from the message.

  • Presence and typing

    Online state and typing indicators backed by Redis with expiry, so stale state clears itself.

  • Delivery and read receipts

    Per-message states acknowledged by the server and reflected in the UI.

  • Notifications

    Unread counts and alerts for conversations the user is not currently viewing.

  • Reconnection handling

    Missed events replayed on reconnect without reloading entire conversations.

Technology

Stack

  • Real-time

    • Socket.IO
    • WebSockets
  • Backend

    • Node.js
    • REST APIs
  • Data

    • MongoDB
    • Redis
  • Storage

    • S3-compatible object storage
    • MinIO
Engineering

Development highlights

  • Message state is server-acknowledged, so the client never shows "sent" for something the server never received.

  • Presence keys carry a TTL, which means a crashed client cannot leave a user permanently shown as online.

  • Socket authentication and room membership are enforced server-side on every join.

  • Indexes designed for the actual access patterns, which is what keeps a chat list fast as history grows.

Outcome

Where it ended up

Described in terms of what the system now does. No invented metrics.

  • A messaging layer that behaves predictably on unreliable mobile connections.

  • A socket architecture that can run more than one instance because no critical state lives in process memory.

  • Patterns — presence, delivery states, reconnection — reused directly in later real-time work.

Contact

Building something like this?

Tell me where your situation is similar and where it differs. The differences are usually where the real work is.

Typical first reply within one business day · Lahore, PKT (UTC+5)