A backend system that pushes live database changes to connected clients — no polling required. Built with Python, FastAPI, PostgreSQL, and WebSockets.
Whenever a row is inserted, updated, or deleted in the orders table, every connected client is instantly notified with the new data — in real time.
PostgreSQL (trigger fires)
↓
NOTIFY on 'orders_channel'
↓
Python backend (asyncpg listens)
↓
WebSocket broadcast
↓
All connected clients receive the update
The assignment explicitly rules out polling. There are a few ways to detect database changes without it:
| Approach | How it works | Why I didn't choose it |
|---|---|---|
| Polling | Client asks repeatedly | Explicitly ruled out |
| Change Data Capture (CDC) | Reads DB transaction logs (e.g. Debezium) | Overkill for this scope |
| LISTEN/NOTIFY | DB fires a notification, backend listens | ✅ Simple, built into PostgreSQL, efficient |
PostgreSQL has a native pub/sub mechanism. A trigger on the orders table fires pg_notify() on every change, and the Python backend listens on that channel using asyncpg. No external message broker needed.
Once the backend detects a DB change, it needs to push it to clients. WebSockets provide a persistent, bidirectional connection — perfect for real-time updates. The alternative (HTTP long-polling or SSE) would be less clean for this use case.
Both are async-native. The DB listener and the WebSocket server run concurrently in the same event loop without blocking each other — no threads, no complexity.
realtime-db-updates/
├── backend/
│ ├── main.py # FastAPI app + WebSocket endpoint
│ ├── db.py # PostgreSQL LISTEN logic + client broadcasting
│ └── models.py # Order data structure
├── client/
│ └── client.py # Python WebSocket client
├── sql/
│ └── setup.sql # Table + trigger setup
├── .env # DB credentials (not committed)
├── .gitignore
├── requirements.txt
└── README.md
- Python 3.10+
- PostgreSQL (with pgAdmin or psql)
- Git
git clone https://github.com/your-username/realtime-db-updates.git
cd realtime-db-updatespython -m venv venv
# Windows
venv\Scripts\activate
# macOS/Linux
source venv/bin/activatepip install -r requirements.txtOpen pgAdmin (or psql), create a database called realtime_db, then run the setup script:
-- Run this in your query tool against realtime_db
\i sql/setup.sqlThis creates the orders table and attaches the change-notification trigger automatically.
Create a .env file in the project root:
DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=your_password_here
DB_NAME=realtime_dbuvicorn backend.main:app --reload --reload-dir backendYou should see:
[Server] Started. DB listener running in background.
[DB] Listening for changes on 'orders_channel'...
python client/client.pyYou should see:
Connecting to server...
Connected! Waiting for order updates...
Go to pgAdmin and run:
INSERT INTO orders (customer_name, product_name, status)
VALUES ('Sidharth', 'Mechanical Keyboard', 'pending');The client terminal will instantly display:
--- Order Update Received ---
Operation : INSERT
Order ID : 1
Customer : Sidharth
Product : Mechanical Keyboard
Status : pending
Updated At : 2026-05-19T10:18:15.928603
-----------------------------
| Layer | Technology |
|---|---|
| Database | PostgreSQL |
| DB Driver | asyncpg |
| Backend Framework | FastAPI |
| Server | Uvicorn |
| Real-time Transport | WebSockets |
| Client | Python (websockets library) |
| Config | python-dotenv |
- Multiple clients are supported out of the box — the backend maintains a set of connected WebSocket clients and broadcasts to all of them simultaneously.
- Single DB connection handles all notifications via
asyncpg's listener — no per-client DB connections needed. - For higher scale, the WebSocket layer could be replaced with a message broker (e.g. Redis Pub/Sub) and the backend could run as multiple instances behind a load balancer.
MIT