# Menskalakan WebSocket dengan Redis Pub/Sub: Dari Satu Server ke Banyak

> Cara menskalakan server WebSocket secara horizontal menggunakan Redis Pub/Sub dan Socket.IO — mencakup masalah sticky session, pengaturan adapter Redis, dan apa yang terjadi ketika Redis menjadi bottleneck.

URL: https://www.matthewswong.com/id/blog/websocket-scaling-redis-pubsub/

- Author: Matthews Wong (https://www.matthewswong.com/id/about/)
- Published: 2025-06-10
- Updated: 2025-06-10
- Category: DevOps

Satu server Node.js dapat menangani 500.000+ koneksi WebSocket idle dengan tuning yang tepat. Namun saat Anda menambahkan instansi server kedua, Anda menghadapi masalah penskalaan WebSocket yang mendasar: klien yang terhubung ke Server 1 tidak dapat menerima pesan dari Server 2 karena soket mereka hidup di proses yang berbeda. Redis Pub/Sub memecahkan ini dengan bertindak sebagai backplane pesan antara instansi server.

## Masalah Penskalaan WebSocket

WebSocket bersifat stateful — tidak seperti permintaan HTTP, mereka mempertahankan koneksi persisten ke instansi server tertentu. Dalam deployment multi-server di belakang load balancer, klien terhubung ke tepat satu server. Ketika Anda ingin mengirim pesan ke pengguna yang mungkin terhubung ke server mana pun, Anda membutuhkan backplane yang mengkoordinasikan antar server — persis seperti yang diaktifkan Redis Pub/Sub.

### Sticky Session: Solusi Parsial

Sticky session mengonfigurasi load balancer untuk merutekan klien yang sama ke server yang sama berdasarkan IP atau cookie mereka. Ini menghindari persyaratan backplane untuk komunikasi klien langsung, tetapi tidak memecahkan kasus di mana satu server perlu mengirim pesan ke klien di server lain. Sticky session juga rusak ketika instansi server di-restart — klien harus terhubung ulang dan mungkin mengenai server yang berbeda.

> Dari membangun fitur notifikasi real-time: gunakan Socket.IO rooms untuk mengelompokkan klien berdasarkan ID pengguna. Ketika Anda perlu mengirim notifikasi ke pengguna tertentu, emit ke room mereka (io.to(userId).emit(...)) daripada melacak ID soket. Adapter Redis memastikan keanggotaan room direplikasi di semua instansi server, sehingga emit ke room bekerja terlepas dari server mana soket pengguna berada.

## Adapter Redis Pub/Sub untuk Socket.IO

Paket @socket.io/redis-adapter Socket.IO menggantikan adapter in-memory default dengan yang didukung Redis. Semua instansi server terhubung ke instansi Redis yang sama dan berlangganan ke saluran bersama. Ketika Server 1 emit ke room atau siaran, ia menerbitkan ke Redis. Semua server menerima publikasi dan fan-out ke klien yang terhubung secara lokal di room tersebut.

### Pengaturan NestJS WebSocket Gateway

Di NestJS, server WebSocket diimplementasikan sebagai Gateway — kelas yang didekorasi dengan @WebSocketGateway. Gateway menggunakan Socket.IO di bawah kapuk secara default. Untuk menambahkan adapter Redis, timpa hook afterInit di gateway Anda dan atur adapter secara programatik, atau konfigurasikan di tingkat aplikasi di main.ts.

> **Redis Pub/Sub tidak terbatas — ia memiliki batas throughput**

> Redis Pub/Sub bukan keajaiban. Ketika Anda mulai menyiarkan jutaan pesan per detik di 100K+ soket, Redis dapat menjadi bottleneck. Setiap pesan yang diterbitkan ke saluran dikirimkan ke setiap subscriber (semua instansi server Anda) — biaya fan-out per subscriber bertambah dengan jumlah server. Pada skala yang sangat tinggi, beralih ke Redis Cluster, gunakan NATS JetStream, atau Kafka untuk backplane.

## Manajemen Koneksi dan Reconeksi

Koneksi WebSocket terputus — pengguna mobile beralih antara WiFi dan seluler, tab browser tertidur, server di-restart. Bangun logika reconeksi ke dalam klien Anda. Pada reconeksi, server harus memutar ulang pesan yang terlewat. Implementasikan kursor 'last seen': ketika klien terhubung kembali, ia mengirim timestamp pesan terakhir yang diterima, dan server mengkueri notifikasi yang terlewat dari database.

## Penskalaan Horizontal dalam Praktik

Arsitektur deployment untuk server WebSocket yang diskalakan secara horizontal: load balancer (Nginx atau cloud LB) → beberapa instansi NestJS Gateway → backplane Redis Pub/Sub bersama. Konfigurasi load balancer untuk sticky session sebagai jaring pengaman. Jalankan Redis dalam konfigurasi High Availability (Sentinel atau Cluster) — jika Redis down, semua komunikasi WebSocket rusak.

## Alternatif Redis untuk Penskalaan WebSocket

Redis Pub/Sub bekerja dengan baik untuk skala sedang (puluhan ribu koneksi bersamaan, jutaan pesan per hari). Untuk skala yang lebih tinggi, pertimbangkan: NATS (sistem pesan yang dibuat khusus dengan overhead lebih rendah dari Redis untuk Pub/Sub), Kafka (untuk throughput sangat tinggi dengan riwayat pesan yang tahan lama), atau layanan WebSocket managed seperti Ably atau Pusher.

## Sumber & Bacaan Lebih Lanjut

- Socket.IO Docs — Redis Adapter
- Ably — Scaling Pub/Sub with WebSockets and Redis
- WebSocket.org — WebSockets at Scale: Architecture for Millions of Connections

## Source links

- https://socket.io/docs/v4/redis-adapter/
- https://ably.com/blog/scaling-pub-sub-with-websockets-and-redis
- https://websocket.org/guides/websockets-at-scale/

## FAQ

### Kenapa sticky session saja tidak cukup untuk menskalakan WebSocket?

Sticky session mengonfigurasi load balancer agar merutekan klien yang sama ke server yang sama, sehingga menghindari kebutuhan backplane untuk komunikasi langsung. Namun, sticky session rusak ketika instansi server di-restart — klien harus terhubung ulang dan bisa mengenai server yang berbeda. Sticky session juga tidak menyelesaikan kasus di mana satu server perlu mengirim pesan ke klien yang terhubung di server lain, yang terjadi dalam skenario kolaborasi multi-pengguna atau siaran.

### Bagaimana cara kerja adapter Redis Pub/Sub di Socket.IO?

Paket @socket.io/redis-adapter menggantikan adapter in-memory default Socket.IO dengan yang didukung Redis. Setiap instansi server terhubung ke instansi Redis yang sama dan berlangganan ke saluran bersama. Ketika server mana pun emit ke room atau menyiarkan pesan, ia menerbitkan ke Redis, dan semua instansi server menerima publikasi tersebut lalu fan-out ke klien yang terhubung secara lokal di room yang relevan.

### Apa yang terjadi pada pesan WebSocket jika Redis mati?

Redis Pub/Sub bersifat fire-and-forget — pesan yang diterbitkan saat subscriber terputus akan hilang. Jika Redis mati sepenuhnya, semua komunikasi WebSocket lintas server akan rusak. Post ini merekomendasikan menjalankan Redis dalam konfigurasi High Availability (Sentinel atau Cluster) dan menjadikan sticky session hanya sebagai jaring pengaman saat Redis gagal, bukan strategi utama.

### Bagaimana cara menangani notifikasi yang tidak boleh terlewat ketika koneksi WebSocket terputus?

Karena koneksi WebSocket bisa terputus kapan saja — pengguna mobile beralih jaringan, tab browser tertidur, atau server di-restart — post ini merekomendasikan menyimpan notifikasi di database. Saat terhubung kembali, klien mengirim timestamp pesan terakhir yang diterima, lalu server mengkueri notifikasi yang terlewat dari database sebelum melanjutkan event live. Pola ini disebut kursor 'last seen'.

### Kapan Redis Pub/Sub tidak lagi menjadi backplane yang tepat untuk penskalaan WebSocket?

Redis Pub/Sub bekerja baik untuk skala sedang — puluhan ribu koneksi bersamaan dan jutaan pesan per hari. Pada throughput sangat tinggi (jutaan pesan per detik di 100K+ soket), setiap pesan yang diterbitkan dikirim ke semua subscriber sehingga biaya fan-out bertambah seiring jumlah server dan Redis menjadi bottleneck. Pada titik itu, post ini menyarankan beralih ke Redis Cluster, NATS JetStream, atau Kafka.

---

- HTML version: https://www.matthewswong.com/id/blog/websocket-scaling-redis-pubsub/
- English: https://www.matthewswong.com/en/blog/websocket-scaling-redis-pubsub/
- Site index for agents: https://www.matthewswong.com/llms.txt
- Sitemap: https://www.matthewswong.com/sitemap.xml
- API description (OpenAPI): https://www.matthewswong.com/openapi.json
