PollStream is a real-time, microservices-based polling application designed for scalability, responsiveness, and fault-tolerance. It allows users to vote on active polls and see updates instantly as others vote — all without needing to refresh the page.

Figure: Real-time poll updates in action
PollStream is architected around microservices, each with a clearly defined responsibility:
- Manages creation and listing of polls.
- Stores poll metadata and vote counts in PostgreSQL.
- Runs a Celery worker that periodically disables expired polls (
is_active = False). - Listens to messages from RabbitMQ to update vote tallies in the DB.
- Implements API Throttling to limit request rates and protect the service.
- Supports API Pagination on poll listing endpoints for performance and scalability.
- Accepts and verifies votes from users.
- Pushes valid votes as tasks to Celery, decoupling request handling from heavy processing.
- Sends vote events to RabbitMQ to inform Poll Service about new votes.
- Uses Django Channels to maintain persistent WebSocket connections with clients.
- Subscribes to Redis pub/sub channels for new vote events.
- Notifies all connected clients in real time when someone votes on a poll.
Here’s a simplified version of how real-time updates happen:
- A user votes → Vote Service verifies and queues the task via Celery.
- Celery worker updates Vote DB and publishes vote event to RabbitMQ.
- Poll Service (subscriber) receives message and updates poll vote counts in PostgreSQL.
- After DB update, Poll Service publishes the event to Redis pub/sub.
- WebSocket Service receives it and broadcasts the latest poll data to all connected users.

Figure: PollStream Microservices Architecture
| Component | Technology |
|---|---|
| Backend Framework | Django, Django REST |
| Realtime Layer | Django Channels + Redis |
| Queue/Async Tasks | Celery + RabbitMQ |
| Databases | PostgreSQL |
| Pub/Sub | Redis Channels |
| Containerization | Docker + Docker Compose |
| Frontend | React.js |
- 🛠️ Microservices architecture with independent scaling
- 📊 Real-time vote updates via WebSocket
- ⏱️ Auto-disabling of expired polls via Celery tasks
- 📤 Vote processing via background workers
- ⚡ Instant client updates through Redis pub/sub and Channels
- 🧪 Production-ready Docker setup for all services
- 🔒 API Throttling to prevent abuse and ensure fair usage
- 📃 API Pagination on poll listings for optimized performance
- Endpoints:
GET /polls/,POST /polls/ - Celery Task: Auto-disable expired polls
- RabbitMQ Listener: Update vote counts from vote service
- Redis Publisher: Publishes vote updates to WebSocket service
- Extras:
- ⏳ Throttling enabled (e.g., rate-limited access)
- 📄 Pagination on poll listing for better client performance
- Endpoints:
POST /votes/ - Celery Task: Validate and process vote
- RabbitMQ Publisher: Notifies Poll Service of new vote
- Endpoint:
ws://.../ws/polls/{poll_id}/ - Redis Subscriber: Listens to poll updates
- Real-Time Updates: Broadcasts to all users in a room
sequenceDiagram
participant User
participant VoteService
participant CeleryWorker
participant RabbitMQ
participant PollService
participant Redis
participant WebSocketService
User->>VoteService: Submit Vote
VoteService->>CeleryWorker: Queue vote task
CeleryWorker->>RabbitMQ: Publish vote message
RabbitMQ->>PollService: Deliver vote message
PollService->>PollService: Update DB
PollService->>Redis: Publish vote update
Redis->>WebSocketService: Deliver update
WebSocketService->>User: Notify clients via WebSocket