Introduction
Live coding battles require real-time communication between participants and judges. Choosing between WebSockets and REST APIs impacts latency, scalability, and user experience significantly.
This guide explores when to use each protocol with practical examples and performance analysis.
Protocol Comparison
REST API - Request/Response
// REST Example - Code Submission
POST /api/submissions
{
"problem_id": 123,
"code": "def solve(): return result",
"language": "python"
}
// Response
{
"submission_id": 456,
"status": "pending"
}
WebSocket - Real-time Bidirectional
// WebSocket Example - Live Updates
// Client sends
{
"type": "code_update",
"room_id": "battle_123",
"code": "def solve(): # typing..."
}
// Server broadcasts instantly
{
"type": "participant_typing",
"user_id": "user_456",
"timestamp": 1642248600000
}
Performance Analysis
| Metric | REST API | WebSocket | Winner |
| Initial Setup | 50ms | 100ms | REST |
| Message Latency | 50ms each | 5ms each | WebSocket (10x) |
| Real-time Updates | 1-5s polling | 5ms instant | WebSocket (200x) |
| Bandwidth | High (headers) | Low (frames) | WebSocket (60% less) |
Scalability Test (1000 users)
REST API (2s polling):
- CPU: 85% | Memory: 2.1GB | Network: 45MB/s
WebSocket:
- CPU: 35% | Memory: 1.2GB | Network: 18MB/s
Implementation Examples
REST API for Code Execution
// Express.js REST endpoint
app.post("/api/submit", async (req, res) => {
const { code, language } = req.body;
const submission = await executeCode(code, language);
await cacheResult(submission.id, submission);
res.json({
submissionId: submission.id,
status: "processing"
});
});
// Polling endpoint
app.get("/api/status/:id", async (req, res) => {
const result = await getCachedResult(req.params.id);
res.json(result || { status: "processing" });
});
WebSocket for Live Updates
// Socket.IO server
io.on("connection", (socket) => {
socket.on("join_battle", (battleId) => {
socket.join(`battle_${battleId}`);
socket.broadcast.to(`battle_${battleId}`)
.emit("participant_joined", socket.userId);
});
socket.on("code_change", (data) => {
socket.broadcast.to(`battle_${data.battleId}`)
.emit("live_coding", {
userId: socket.userId,
preview: data.code.substring(0, 50)
});
});
});
Decision Framework
Use REST APIs For:
- Authentication - Stateless, cacheable tokens
- File Operations - Uploads, downloads with progress
- CRUD Operations - User profiles, problem management
- Public APIs - Third-party integrations
- Heavy Processing - Code execution, analysis
Use WebSockets For:
- Real-time Updates - Live rankings, notifications
- Collaboration - Code sharing, pair programming
- Live Events - Contest announcements, chat
- Presence - Online status, typing indicators
- Gaming Elements - Live battles, instant feedback
Common Mistakes
❌ Wrong: WebSocket for File Upload
// Inefficient - no progress tracking
socket.emit("upload_file", largeFileData);
// Correct - use REST with progress
fetch("/api/upload", {
method: "POST",
body: formData
}).then(response => response.json());
❌ Wrong: Aggressive REST Polling
// Wasteful - polls every second
setInterval(() => {
fetch("/api/leaderboard").then(updateUI);
}, 1000);
// Efficient - WebSocket updates
socket.on("leaderboard_update", updateUI);
Hybrid Architecture
// Best of both worlds
class CodingPlatform {
// REST for heavy operations
async submitCode(code) {
const result = await fetch("/api/submit", {
method: "POST",
body: JSON.stringify({ code })
});
return result.json();
}
// WebSocket for real-time features
setupRealTime() {
this.socket.on("submission_complete", (data) => {
this.updateLeaderboard(data.rankings);
this.showNotification(data.message);
});
}
}
Performance Optimization
WebSocket Optimizations
// Rate limiting and connection pooling
class OptimizedWebSocket {
constructor() {
this.rateLimiter = new Map();
}
handleMessage(socket, data) {
// Rate limit: 10 messages per second
const userId = socket.userId;
const now = Date.now();
const userLimits = this.rateLimiter.get(userId) || [];
// Clean old timestamps
const recent = userLimits.filter(t => now - t < 1000);
if (recent.length >= 10) {
socket.emit("rate_limited");
return;
}
recent.push(now);
this.rateLimiter.set(userId, recent);
// Process message
this.processMessage(data);
}
}
Conclusion
Choose the right protocol for each feature:
WebSockets Excel At:
- Real-time updates (10x faster)
- Low bandwidth usage (60% less)
- Bidirectional communication
REST APIs Excel At:
- Stateless operations
- Caching and CDN support
- File handling and uploads
Best Practice: Use hybrid architecture - REST for data operations, WebSockets for real-time features.
Try These Challenges:
Master real-time web development with our system design challenges!