Skip to main content

Overview

Build a real-time chat app using FastAPI (Python) for the backend, PostgreSQL to store messages, Redis for realtime fan-out (pub/sub), and a simple React frontend.

Python code editor showing chat app backend

FastAPI Backend

Async Python framework with WebSocket support for real-time messaging.

Computer screen displaying database schema

PostgreSQL + Redis

Reliable message storage with real-time pub/sub for instant delivery.

React frontend code for chat interface

React Frontend

Simple, responsive interface that connects via WebSocket for live chat.

Architecture

High-level system design with scalable components for real-time messaging.

Client Layer

Web/Mobile clients connect via WebSocket and REST APIs for seamless real-time communication.

Application Layer

FastAPI handles WebSocket connections, message routing, and business logic with async performance.

Data Layer

PostgreSQL stores messages reliably while Redis enables real-time pub/sub message distribution.

Developer workspace with multiple screens showing chat application architecture Modern coding workspace with RGB lighting for chat app development Software developer working on chat application with multiple monitors

Why These Choices?

In plain words - why we picked these technologies for your chat app.

FastAPI code editor workspace

FastAPI

Fast to write, supports async code and WebSockets for real-time connections.

PostgreSQL database workspace

PostgreSQL

Reliable storage for user data and complete message history with ACID compliance.

Redis real-time messaging workspace

Redis

Quick message passing between server instances with pub/sub for real-time delivery.

📁

S3/MinIO

Store files like images safely with signed URLs for secure access.

Simple Roadmap

Easy steps to build your chat app from start to finish.

Development planning abstract art
1

Create Environment

Set up project with poetry/venv and install dependencies

Mountain road journey
2-3

User Auth + WebSocket

Implement signup/login and real-time messaging endpoints

Tree-lined development path
4-6

Database + Frontend

Save messages to Postgres and build React chat interface

Commands to Set Up

Copy-and-paste commands to get your chat app running in minutes.

Create Project

poetry init -n
poetry add fastapi "uvicorn[standard]" sqlalchemy asyncpg redis[async] passlib[bcrypt] python-jose
poetry add -D pytest pytest-asyncio

Run Locally

uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
docker-compose up --build
Terminal setup showing Python code Code displayed on computer screen Developer working at computer monitor

Minimal Docker Compose

For local development with Postgres + Redis + App.

version: "3.8"
services:
  postgres:
    image: postgres:15
    environment:
      POSTGRES_USER: chatuser
      POSTGRES_PASSWORD: chatpass
      POSTGRES_DB: chatdb
    ports:
      - "5432:5432"
  redis:
    image: redis:7
    ports:
      - "6379:6379"
  backend:
    build: .
    command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
    volumes:
      - ./:/code
    ports:
      - "8000:8000"
    depends_on:
      - postgres
      - redis
Docker compose code editor Dark theme code editor with Docker Lines of code in dark theme editor

Tiny FastAPI WebSocket Skeleton

Drop this into app/main.py - very minimal but functional.

from fastapi import FastAPI, WebSocket, WebSocketDisconnect
import json

app = FastAPI()

class ConnectionManager:
    def __init__(self):
        self.active_connections: dict[int, WebSocket] = {}
    
    async def connect(self, user_id: int, websocket: WebSocket):
        await websocket.accept()
        self.active_connections[user_id] = websocket
    
    async def disconnect(self, user_id: int):
        self.active_connections.pop(user_id, None)
    
    async def send_personal_message(self, user_id: int, message: dict):
        ws = self.active_connections.get(user_id)
        if ws:
            await ws.send_text(json.dumps(message))

manager = ConnectionManager()

@app.websocket('/ws')
async def websocket_endpoint(websocket: WebSocket, token: str = None):
    user_id = 1  # validate token -> get user_id
    await manager.connect(user_id, websocket)
    try:
        while True:
            data = await websocket.receive_text()
            print('received:', data)
    except WebSocketDisconnect:
        await manager.disconnect(user_id)
Python code screen showing FastAPI skeleton FastAPI code editor workspace Python development screen with WebSocket code

Simple SQLAlchemy Models

Clean and concise models for your chat app with SQLAlchemy ORM.

User Model

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    username = Column(Text, unique=True)
    password_hash = Column(Text)

Message Model

class Message(Base):
    __tablename__ = 'messages'
    id = Column(Integer, primary_key=True)
    sender_id = Column(Integer, ForeignKey('users.id'))
    recipient_id = Column(Integer, ForeignKey('users.id'))
    content = Column(Text)
    created_at = Column(DateTime, default=datetime.datetime.utcnow)
    delivered = Column(Boolean, default=False)

How Messages Flow

Step-by-step journey of a message from sender to recipient

Message Flow Steps

1

Client A Sends Message

User sends message via WebSocket to server instance

2

Server Saves to Database

Message stored in PostgreSQL for durability

3

Redis Pub/Sub Event

Server publishes event to Redis channel for recipient

4

Broadcast to Instances

All servers receive event and forward if recipient online

5

Client Receives Message

Recipient client receives message and sends ACK

Code flow diagram on screen 3D render diagram City lights at night

Flow Benefits

Durability

Messages saved to PostgreSQL before broadcasting ensures no data loss

Real-time

Redis pub/sub provides sub-millisecond message delivery

Scalability

Multiple server instances can handle thousands of concurrent users