Temps réel
Le temps réel pousse des messages à vos utilisateurs connectés sans qu'ils interrogent le serveur : la diffusion de client à client, la présence (qui est en ligne), et la diffusion des changements d'une table. Il parle le protocole de supabase-js. Cette page dit comment l'activer, comment s'en servir, ce qui n'est pas servi, et les quotas de chaque palier.
Ce qui est servi
- La diffusion (
broadcast) : un client envoie un message sur un canal, les autres abonnés le reçoivent. Elle passe par la WebSocket, ou par REST (POST /realtime/v1/api/broadcast), le repli desupabase-js. - La présence (
presence) : chaque client annonce son état, et tous voient qui est là. - La diffusion depuis la base : une fonction pose un déclencheur sur une table, et chaque insertion, modification ou suppression part en diffusion sur un canal.
- Les canaux privés, jugés par les politiques que vous écrivez sur
realtime.messages.
La WebSocket est wss://<identifiant>.donnees.bastide.app/realtime/v1/websocket, protocoles 1.0.0 et 2.0.0 (voir Base de données pour l'adresse).
Attention. L'écoute des changements de la base par
postgres_changesn'est pas servie : un tel abonnement est refusé à la jonction du canal (statuterror), et le refus nomme la diffusion depuis la base (LIM-08). Aucune réplication logique n'est exposée.
Activer le temps réel
Le temps réel est désactivé par défaut. Tant qu'il l'est, /realtime/v1 répond 403, code temps_reel_inactif.
- Console : ouvrez Données, section « Temps réel », puis « Activer le temps réel ». La carte affiche les quotas de votre palier.
- Agent :
backend_realtime_configureavecactive: true(rangmaintainer, portéedb:write). - Ligne de commande :
bastide backend realtime configure --project-id <projet> --active true. - API :
PUT /v1/projects/{projectId}/backend/realtime.
{
"projectId": "prj_01JQ8ZK4M7NP2RSTVWXYZ34567",
"active": true,
"idempotencyKey": "temps-reel-2026-10-28"
}
L'activation et la désactivation prennent effet en moins de 30 secondes. Désactiver ferme les connexions ouvertes du projet, sans toucher aux autres projets. L'état et les quotas se relisent par backend_read (champ tempsReel).
Diffuser et suivre la présence
const canal = supabase.channel("salon-42");
canal
.on("broadcast", { event: "curseur" }, ({ payload }) => afficher(payload))
.on("presence", { event: "sync" }, () => console.log(canal.presenceState()))
.subscribe(async (statut) => {
if (statut === "SUBSCRIBED") await canal.track({ nom: "Léa" });
});
await canal.send({ type: "broadcast", event: "curseur", payload: { x: 10, y: 20 } });
Un sujet de canal commence par realtime: dans le protocole ; supabase-js l'ajoute pour vous.
Diffuser les changements d'une table
À la place de postgres_changes, posez le déclencheur une fois, dans une migration ou l'éditeur SQL :
select realtime.diffuser_les_changements('public.messages');
Le canal public:messages reçoit alors chaque insertion, modification et suppression de la table, en diffusion. Les messages venus de la base comptent dans le quota de messages par seconde du projet ; au-delà, ils sont écartés.
Les canaux privés
Un canal privé n'admet que les clients que vos politiques admettent. Écrivez-les sur la table realtime.messages, avec realtime.topic() (le sujet du canal) et auth.uid() :
- la politique
SELECTdécide qui peut rejoindre et lire le canal ; - la politique
INSERTdécide qui peut y envoyer.
La plateforme éprouve la politique dans une transaction toujours annulée, sous le rôle de l'appelant : c'est PostgreSQL qui juge, telle que vous l'avez écrite. Voir Sécurité des données.
Les quotas par palier
| Palier | Messages par seconde | Connexions simultanées |
|---|---|---|
| Découverte | 100 | 200 |
| Standard | 500 | 2 000 |
| Pro | 2 500 | 10 000 |
| Souverain | négociés, sans plafond opposé | négociées, sans plafond opposé |
Sur tous les paliers : 100 canaux par connexion, une charge utile de 3 000 Ko au plus par message, et 5 appels de présence par client par tranche de 30 secondes.
- Connexions : la place est réservée avant la poignée de main. Au-delà du quota, la WebSocket reçoit 429, code
connexions_simultanees_depassees, sans qu'aucune connexion s'ouvre. - Messages : le quota se compte par seconde pleine, pour tout le projet (diffusions, présence et messages de la base). Au-delà, l'envoi reçoit une erreur qui nomme le quota ; par REST, 429.
- Canaux : au-delà de 100 sur une même connexion, la jonction est refusée ; quittez-en un, ou ouvrez une autre connexion.
Note. Le temps réel tient, par instance de la plateforme, une connexion en mode session à votre base tant qu'un client est branché. Elle compte dans le plafond de connexions serveur de votre palier (trois en Découverte ; voir Base de données).
Erreurs fréquentes
- **403
temps_reel_inactif** : activez le temps réel du projet. - Abonnement refusé, raison citant la diffusion depuis la base : vous avez demandé
postgres_changes; employezrealtime.diffuser_les_changements. - **429
connexions_simultanees_depassees** : fermez les connexions inutilisées, ou changez de palier. - « jeton d'accès refusé » à la jonction : le jeton de session a expiré ; reconnectez le client.
- Rien n'arrive sur un canal privé : la politique
SELECTderealtime.messagesn'admet pas cet utilisateur.