La tua app web fa polling al database ogni secondo per vedere se c'è un nuovo messaggio? Ogni chiamata inutile è spreco di banda, carico sul server e lag per l'utente. Noi lo vediamo ogni settimana nei progetti che ci arrivano: chat aziendali che sembrano ferme, notifiche che arrivano dopo minuti, server che si impennano con 10 utenti online. Il problema non è la feature: è l'architettura.
Redis Pub/Sub è un pattern di messaggistica leggero, velocissimo e nativo di Redis. Ti permette di mandare un messaggio a tutti i client connessi su un canale, in tempo reale, senza dover aprire server WebSocket custom o pagare servizi esterni. Noi, di Meteora Web, lo usiamo da anni per chat, notifiche push, aggiornamenti di stato in dashboard e sincronizzazione tra microservizi. E costa poco: spesso basta un'istanza Redis già attiva per il caching.
In questa guida non trovi teoria astratta. Trovi il perché funziona, il codice per farlo funzionare, i limiti da conoscere e una strategia per integrarlo in produzione. Partiamo dal problema reale: vuoi una chat senza che il server muoia ogni volta che qualcuno scrive 'ciao'.
Cos'è Redis Pub/Sub e perché batte il polling?
Redis Pub/Sub è un sistema di messaggistica publish/subscribe. Ci sono tre attori: un publisher che manda un messaggio su un canale, un subscriber che ascolta quel canale, e Redis che fa da ponte. Il publisher non sa chi sta ascoltando; il subscriber riceve il messaggio istantaneamente, senza dover chiedere nulla.
Sponsored Protocol
Confrontalo con il polling classico: il frontend chiama l'API ogni 2 secondi 'ci sono nuovi messaggi?'. Il server interroga il database, risponde 'no' 29 volte su 30. Sprechi CPU, banda, e il delay medio è di 1 secondo (se fai polling ogni 2 secondi). Con Pub/Sub, il server spinge il messaggio solo quando c'è, e il client lo riceve in millisecondi.
Il meccanismo dei canali
Un canale è una stringa che funge da topic. I subscriber si iscrivono a uno o più canali. I publisher scrivono su un canale. Redis distribuisce il messaggio a tutti i subscriber attivi. Punto. Non c'è buffer, non c'è coda: il messaggio vive solo in volo. Se un subscriber non è connesso in quel momento, perde il messaggio. Questo è il primo limite da capire.
Differenza con WebSocket diretto
Puoi implementare un server WebSocket in Node.js o PHP e farlo parlare direttamente con i client. Ma poi devi gestire la connessione, la riconnessione, lo stato di ogni socket, la broadcast room per room. Redis Pub/Sub ti dà la broadcast già pronta: ogni subscriber su un canale riceve il messaggio. Se hai più server WebSocket (es. orizzontale), Redis Pub/Sub diventa il collante tra di loro. Un server pubblica, l'altro server, che ha i client connessi, riceve e inoltra.
Sponsored Protocol
Come implementare una chat base con Redis Pub/Sub?
Vediamo il codice. Supponiamo di avere un client Node.js (lato server) che si connette a Redis. Usiamo la libreria redis per Node.js (v4+).
Installazione dei client
npm install redisPoi creiamo due script: uno che pubblica messaggi (es. quando un utente invia un messaggio) e uno che ascolta (es. il server WebSocket che poi inoltra ai browser).
Codice publisher
import { createClient } from 'redis';
const publisher = createClient();
await publisher.connect();
// Quando un utente manda un messaggio su canale 'chat:room:123'
const messaggio = JSON.stringify({ utente: 'Mario', testo: 'Ciao!', timestamp: Date.now() });
await publisher.publish('chat:room:123', messaggio);
await publisher.quit();Codice subscriber (server websocket)
import { createClient } from 'redis';
const subscriber = createClient();
await subscriber.connect();
await subscriber.subscribe('chat:room:123', (message) => {
// message è il JSON stringifyato
const data = JSON.parse(message);
// Inoltra a tutti i client WebSocket connessi a questa room
wsRoom.send(JSON.stringify({ type: 'new_message', data }));
});
// Mantieni la connessione apertaAttenzione: il subscriber deve rimanere in ascolto, quindi non chiamare quit(). In produzione, lo avvii in un processo separato o come worker.
Sponsored Protocol
Questo è il cuore. La chat funziona: un client manda il messaggio al backend (HTTP o WebSocket), il backend lo salva nel database (opzionale) e pubblica su Redis. Il subscriber dell'altro server riceve e lo inoltra al destinatario. Tutto real-time.
Quali sono i limiti di Redis Pub/Sub e come affrontarli?
Redis Pub/Sub non garantisce persistenza dei messaggi. Se il subscriber si disconnette, il messaggio viene perso. Per una chat non critica può andare bene (se un utente si riconnette, ricarica la cronologia dal database). Ma per notifiche che devono arrivare anche a utenti offline, devi usare Redis Streams (consumer group con accuse). Noi, quando serve affidabilità, combiniamo i due: Pub/Sub per latenza minima online, Streams per messaggi differiti.
Scalabilità orizzontale con pattern fan-out
Se hai più server WebSocket, ogni server ha il suo subscriber su Redis. Quando un publisher manda un messaggio su un canale, tutti i subscriber lo ricevono. Ma questo significa che ogni server inoltra il messaggio a tutti i suoi client, inclusi quelli che non sono nella room giusta? Devi filtrare: il subscriber lato server conosce quali client sono connessi a quali room. Quindi riceve il messaggio, controlla la room e inoltra solo ai client interessati. È un pattern semplice: il subscriber fa da bridge.
Un'altra soluzione è usare Redis Cluster o Redis Sentinel per alta disponibilità. Noi abbiamo gestito carichi di centinaia di migliaia di messaggi al minuto con Pub/Sub, ma per carichi estremi conviene valutare Kafka o RabbitMQ.
Sponsored Protocol
Come integrare Redis Pub/Sub con un'app web reale (es. Laravel Reverb)?
Se usi Laravel, non devi reinventare la ruota. Laravel Reverb (WebSocket first-party) si basa su Redis Pub/Sub per il broadcasting. Definisci un evento in Laravel, lo pubblichi su un canale Redis, e Reverb lo ascolta e lo trasmette ai client via WebSocket. Esempio:
Evento Laravel
class MessageSent implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public function __construct(public string $room, public array $data) {}
public function broadcastOn(): array
{
return [new PrivateChannel('chat.'.$this->room)];
}
}Poi nel controller: event(new MessageSent('room123', $messageData));
Laravel pubblica su Redis (grazie al driver predisposto), Reverb ascolta e spinge ai client connessi. Tutto configurabile in config/broadcasting.php. Noi lo abbiamo usato per una piattaforma di prenotazioni con aggiornamenti in tempo reale: funziona senza intoppi fino a migliaia di utenti simultanei.
Per chi preferisce Node.js, abbiamo costruito una piccola piattaforma proprietaria per gestire la presenza social di più clienti: usavamo Redis Pub/Sub per sincronizzare le pubblicazioni tra server diversi. Nessun costo extra, scalabilità lineare.
Sponsored Protocol
Cosa fare adesso?
Abbiamo visto abbastanza per passare all'azione. Ecco i prossimi passi concreti:
- Verifica se hai già Redis in produzione (spesso sì, per cache). Se sì, hai già il server Pub/Sub senza costi aggiuntivi.
- Installa il client Redis nel tuo linguaggio (Node.js, PHP, Python…). La documentazione ufficiale Redis (redis.io) è il riferimento assoluto.
- Sostituisci il polling nella tua chat o notifiche con uno script subscriber che ascolti un canale. Poi aggiorna il frontend per usare WebSocket (es. Socket.io lato client) collegato al backend.
- Decidi se servono messaggi persistenti: se sì, abbina Redis Streams per i messaggi offline. Se no, Pub/Sub basta.
- Testa il carico: usa redis-cli monitor o strumenti come redis-benchmark per vedere latenza.
- Leggi la nostra guida pillar su Redis e Caching Strategies per capire come integrare Pub/Sub con caching e altri pattern.
Noi, di Meteora Web, siamo partiti da un negozio di abbigliamento dove aggiornavamo i prezzi in tempo reale su tre vetrine diverse. Oggi Pub/Sub è il nostro starter per ogni feature real-time. Se vuoi discuterne, parliamone con i numeri: quanto costa il tuo polling oggi? Quanto risparmieresti? Il resto è codice.