Designing a Scalable Market Data Streaming Architecture
In my algo trading project, Growth Quantix, handling real-time market data efficiently is critical. This post details the architecture I designed to process live ticks, minimize latency, and serve data to both trading strategies and a frontend dashboard.
π οΈ Stack Used
This architecture is implemented using a modern, high-performance stack:
- Python FastAPI β Backend services and API layer
- Upstox WebSocket β Live market feed source
- Redis β In-memory cache + Pub/Sub messaging bus
- Background Workers β Data parsing and strategy execution
- Socket.IO β Real-time UI streaming to the client
- React Dashboard β Frontend consumer
π§© High-Level System Architecture
The system adheres to a strict separation of concerns: Ingest β Process β Store β Stream β Consume.
ββββββββββββββββββββββββββββ
β Upstox API β
β (Market WebSocket) β
ββββββββββββββ¬ββββββββββββββ
β Live Ticks
βΌ
ββββββββββββββββββββββββββββ
β Ingestion Service β
β (Background FastAPI Job) β
ββββββββββββββ¬ββββββββββββββ
β Raw Tokens
βΌ
ββββββββββββββββββββββββββββ
β Processing & Mapping β
β Token β Symbol mapping β
β OHLC / %Change / LTP β
ββββββββββββββ¬ββββββββββββββ
β Normalized ticks
βΌ
ββββββββββββββββββββββββββββββββββββββββ
β Redis Layer β
β β’ In-memory cache β
β β’ Pub/Sub channels β
ββββββββββββββ¬ββββββββββββββ¬ββββββββββββ
β β
β β
βΌ βΌ
ββββββββββββββββββββββββ βββββββββββββββββββββββββ
β Trading Engine β β Real-Time Dashboard β
β (Strategies) β β (React + Socket.IO) β
ββββββββββββββββββββββββ βββββββββββββββββββββββββ
This pipeline ensures that:
- Ingestion is decoupled from consumption.
- Processing normalizes data before it hits the bus.
- Redis acts as the single source of truth for live state.
π Detailed Data Flow Architecture
Below is a deeper view of the backend services interacting via the Redis bus.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β BACKEND SERVICES β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Upstox WebSocket Feed
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ticks with instrument_token
βΌ
βββββββββββββββββββββββββββββββββ
β WebSocket Ingestion Worker β
β (running in background) β
βββββββββββββββββββββββββββββββββ
β
β validate / reconnect / heartbeat
βΌ
βββββββββββββββββββββββββββββββββ
β Parsing + Mapping Layer β
β token β symbol β
β add OHLC/LTP/change% β
βββββββββββββββββββββββββββββββββ
β
β normalized structured tick
βΌ
βββββββββββββββββββββββββββββββββ
β Redis Cache + Pub/Sub β
βββββββββββββββββββββββββββββββββ
β β
β β
βΌ βΌ
ββββββββββββββββββ βββββββββββββββββββββββββββββββ
β Trading Logic β β Socket.IO Broadcast Layer β
β (strategies) β β push to connected clients β
ββββββββββββββββββ βββββββββββββββββββββββββββββββ
β
βΌ
React Frontend Dashboard
In this setup:
- Upstox feeds the background service.
- Redis acts as the central nervous system.
- Socket.IO bridges the gap to the frontend.
- The Trading Engine consumes the same data bus as the UI, ensuring consistency.
ποΈ Why I Designed It This Way
This design evolved from real constraints in my project:
"Instead of each consumer connecting to the broker, everything connects to the Redis live stream layer."
- Connection Limits: Upstox limits connection counts, so I use a single admin WebSocket.
- High Throughput: Handling thousands of ticks/sec means avoiding direct DB writes for every tick.
- Unified Data: Strategies and UI need the exact same data, making a Pub/Sub bus ideal.
- Decoupling: Independent services prevent a UI crash from stopping the trading engine.
π§ Key Components Explained
1οΈβ£ Upstox Ingestion Worker
Runs independently, connects with the admin token, and handles resubscriptions and exponential backoff strategies for robustness.
2οΈβ£ TokenβSymbol Mapping
Raw feeds often send tokens (integers) instead of symbols to save bandwidth. My instrument service loads a CSV/instrument dump on startup, builds a token β symbol dictionary, and keeps it in Redis for fast O(1) lookups during ingestion.
3οΈβ£ Redis Cache + Pub/Sub
Acts as:
- Hot Cache: Stores the latest price (LTP) for immediate access.
- Pub/Sub Bus: Distributes ticks to multiple subscribers (Strategy Engine, Dashboard).
- Buffer: Handles burst traffic without blocking.
4οΈβ£ Strategy Engine
Consumes the live feed to generate buy/sell signals, track P&L, and manage risk.
5οΈβ£ Frontend Dashboard
Built with React and Socket.IO, it receives live tick cards, scanner updates, top gainers/losers, and open position updates in real-time.
π Future Improvements
Iβm considering adding:
- Kafka for long-term scaling and log replay.
- Candlestick Aggregation Service for generating 1m, 5m bars from ticks.
- Persistence Layer (TimescaleDB) for historical analysis.
- Anomaly Detection alerts for data feed issues.
π Conclusion
This architecture now powers my algo trading experiments, live dashboard, and real-time streaming UI. It is built with FastAPI, Redis, Socket.IO, React, and Upstox WebSocket. The design is modular, fault-tolerant, and scalable β and most importantly, I built it step by step while working full-time.