A developer I know built a live chat feature with raw WebSockets. It worked great with 10 users. At 1,000 users, messages started dropping. At 10,000, the server crashed. He switched to Ably — it handles millions of concurrent connections without breaking a sweat.
What Ably Offers for Free
Ably free tier:
- 6 million messages/month
- 200 peak connections
- 200 peak channels
- Pub/Sub messaging with guaranteed delivery
- Presence — who's online in a channel
- Message history and persistence
- WebSocket, SSE, MQTT, REST protocols
- 99.999% uptime SLA (even on free tier)
Quick Start
npm install ably
const Ably = require('ably');
// Real-time client
const ably = new Ably.Realtime(process.env.ABLY_API_KEY);
const channel = ably.channels.get('chat');
// Subscribe to messages
channel.subscribe('message', (msg) => {
console.log(`${msg.data.user}: ${msg.data.text}`);
});
// Publish a message
channel.publish('message', { user: 'Alice', text: 'Hello, world!' });
Live Chat Room
// Server-side: token auth (secure)
const Ably = require('ably');
const rest = new Ably.Rest(process.env.ABLY_API_KEY);
app.get('/api/ably-token', async (req, res) => {
const tokenRequest = await rest.auth.createTokenRequest({
clientId: req.user.id,
capability: { 'chat:*': ['publish', 'subscribe', 'presence'] }
});
res.json(tokenRequest);
});
// Client-side
const ably = new Ably.Realtime({ authUrl: '/api/ably-token' });
const chatRoom = ably.channels.get('chat:room-123');
// Send message
function sendMessage(text) {
chatRoom.publish('message', {
user: currentUser.name,
text,
timestamp: Date.now()
});
}
// Receive messages
chatRoom.subscribe('message', (msg) => {
appendToChat(msg.data);
});
Presence (Who's Online)
const channel = ably.channels.get('chat:room-123');
// Enter presence
channel.presence.enter({ name: 'Alice', avatar: 'https://...' });
// Get all present members
const members = await channel.presence.get();
console.log(`${members.length} users online`);
// Track presence changes
channel.presence.subscribe('enter', (member) => {
console.log(`${member.data.name} joined`);
});
channel.presence.subscribe('leave', (member) => {
console.log(`${member.data.name} left`);
});
REST API
# Publish a message
curl -X POST 'https://rest.ably.io/channels/my-channel/messages' \
-u 'YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{"name": "greeting", "data": "Hello from REST!"}'
# Get channel history
curl 'https://rest.ably.io/channels/my-channel/messages?limit=10' \
-u 'YOUR_API_KEY'
# Get presence members
curl 'https://rest.ably.io/channels/my-channel/presence' \
-u 'YOUR_API_KEY'
# Get channel stats
curl 'https://rest.ably.io/stats?unit=hour&limit=24' \
-u 'YOUR_API_KEY'
Use Cases
- Live chat — 1-on-1, group, support chat
- Live updates — sports scores, stock prices, delivery tracking
- Collaborative editing — multiplayer cursors, shared whiteboards
- IoT — device-to-cloud messaging via MQTT
- Gaming — real-time game state synchronization
- Notifications — instant push to connected clients
Why Ably Over Raw WebSockets
| Ably | Raw WebSockets |
|---|---|
| Guaranteed message delivery | Messages can drop |
| Auto-reconnection | Build reconnection logic |
| Message history | Build persistence layer |
| Scales to millions | Scale server infrastructure |
| Presence built in | Build presence system |
| Global edge network | Single server location |
Need real-time web data? Check out my web scraping actors on Apify — monitor websites in real-time.
Need a real-time data pipeline? Email me at spinov001@gmail.com.
Top comments (0)