---
term: 'SSE vs. WebSockets vs. Polling'
seoTitle: 'SSE vs. WebSockets vs. Polling : choisir un transport temps réel'
headline: 'Server-Sent Events vs. WebSockets vs. Polling : lequel devriez-vous utiliser ?'
slug: sse-vs-websockets-vs-polling
category: api-realtime
shortDefinition: "Le polling est un modèle de pull où le client demande en boucle ; SSE et WebSockets gardent une connexion ouverte pour que le serveur pousse en temps réel."
relatedTerms:
  - websockets-real-time-sync
  - real-time-live-queries
  - pub-sub-pattern
  - api-payload-optimization
contrastsWith:
  - websockets-real-time-sync
aboutTerms:
  - 'Server-Sent Events (SSE)'
  - 'WebSockets'
  - 'Long Polling'
  - 'Short Polling'
faq:
  - question: 'Que vaut-il mieux, SSE ou WebSockets ?'
    answer: "Ni l'un ni l'autre universellement — la vraie question est la direction. SSE est l'outil le plus simple quand les données circulent dans un seul sens, du serveur vers le client : du HTTP ordinaire, une reconnexion automatique, un passage sans heurt par les proxies. Les WebSockets méritent leur complexité supplémentaire dès que le client doit lui aussi émettre en temps réel — chat, jeux, édition collaborative."
  - question: 'SSE est-il plus rapide que le polling ?'
    answer: "Pour la latence de livraison, sans hésiter : les événements arrivent au moment où ils surviennent, tandis que le polling coûte en moyenne la moitié de l'intervalle plus un aller-retour. C'est aussi moins cher — une connexion maintenue au lieu d'une série de cycles requête/réponse le plus souvent vides, chacun payant le prix fort en headers HTTP."
  - question: 'Quand faut-il utiliser le long polling ?'
    answer: "Comme repli, pas comme premier choix : il existe pour les environnements où les connexions persistantes échouent — intermédiaires legacy, proxies qui suppriment les upgrades WebSocket ou qui mettent les flux en tampon. Le serveur garde chaque requête ouverte jusqu'à l'arrivée de données, ce qui approxime le push au prix d'un va-et-vient de reconnexions et de headers payés à chaque requête."
  - question: 'Combien de connexions SSE un navigateur peut-il ouvrir ?'
    answer: "En HTTP/1.1, six par origine — et la limite est partagée entre les onglets, un piège bien documenté où un dashboard ouvert dans sept onglets se retrouve silencieusement affamé. En HTTP/2, la contrainte se déplace vers les streams concurrents multiplexés sur une seule connexion (environ cent par défaut), ce qui règle le problème pour de bon."
  - question: 'SSE se reconnecte-t-il automatiquement ?'
    answer: "Oui — c'est la caractéristique qui le distingue le plus des WebSockets bruts. EventSource réessaie tout seul les connexions coupées, respecte l'intervalle de retry fixé par le serveur et renvoie l'ID du dernier événement reçu dans un header Last-Event-ID, pour que le serveur reprenne le flux sans trou. La reconnexion WebSocket, elle, est du code que vous écrivez."
  - question: 'SSE peut-il envoyer des données binaires ?'
    answer: "Non — le flux est du texte UTF-8 par spécification ; les payloads binaires doivent être encodés, avec environ un tiers de surcoût de taille. Les WebSockets transportent nativement des frames binaires, ce qui compte pour l'audio, les protocol buffers et tout ce qui est déjà compact."
  - question: "Qu'utilisent les applications de chat IA pour diffuser leurs réponses ?"
    answer: "Server-Sent Events, presque universellement : la génération token par token est du texte diffusé dans un seul sens, ce qui est exactement la forme de SSE — du HTTP ordinaire en sortie, aucune négociation d'upgrade, une reprise automatique. Les WebSockets n'apparaissent dans les produits IA que lorsque le client doit interrompre ou parler en plein flux, comme dans les interfaces vocales."
  - question: "Quel est l'ordre de repli pour les fonctionnalités temps réel ?"
    answer: "Détectez les capacités et dégradez : WebSocket là où le chemin réseau le supporte, SSE là où seul le push serveur est nécessaire ou là où les upgrades échouent, long polling comme plus petit dénominateur commun. Les bibliothèques temps réel matures négocient cette échelle automatiquement — une raison de plus pour laquelle les sockets bruts sont rarement utilisés nus en production."
codeLanguages: [javascript, dart, swift, kotlin]
externalAuthorities:
  - name: 'Server-sent events — WHATWG HTML Living Standard'
    url: 'https://html.spec.whatwg.org/multipage/server-sent-events.html'
  - name: 'RFC 6455 — The WebSocket Protocol'
    url: 'https://datatracker.ietf.org/doc/html/rfc6455'
  - name: 'Using server-sent events — MDN Web Docs'
    url: 'https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events'
  - name: 'RFC 6202 — Known Issues with Long Polling and HTTP Streaming'
    url: 'https://datatracker.ietf.org/doc/html/rfc6202'
cta:
  title: 'Épargnez-vous la décision de transport'
  text: "Les Live Queries de Back4app livrent les mises à jour en temps réel sur une flotte de WebSockets gérée — abonnez-vous à la requête que vous avez déjà et laissez la plateforme prendre en charge les connexions, les reconnexions et le fan-out."
  linkText: 'Commencez gratuitement'
  linkUrl: 'https://www.back4app.com/signup'
author: 'Back4app Engineering'
publishedDate: '2026-09-10'
translationKey: sse-vs-websockets-vs-polling
---

**Le polling est un modèle de pull où le client demande en boucle ; SSE et WebSockets gardent une connexion ouverte pour que le serveur pousse en temps réel.** Choisir entre les trois revient en fait à trois questions — dans quel sens circulent les données, à quelle fréquence elles changent, et quelle infrastructure se trouve au milieu — et la réponse honnête diffère par fonctionnalité, pas par application.

## Points clés

| Question | Réponse |
| --- | --- |
| Short polling | Demander à intervalle fixe — simple, compatible avec le cache, requêtes majoritairement gaspillées |
| Long polling | Le serveur garde la requête jusqu'à l'arrivée des données — du push simulé sur du HTTP ordinaire |
| SSE | Un flux HTTP, des événements texte serveur → client, reconnexion automatique intégrée |
| WebSockets | Un socket, full-duplex, capable de binaire — le protocole vous appartient |
| La règle empirique | Sens unique → SSE · deux sens → WebSockets · changements rares → le polling suffit |

## Le code, côte à côte

```js
// 1 · Short polling — demander à intervalle fixe
setInterval(async () => {
  const res = await fetch('/api/messages?since=' + lastId);
  render(await res.json());              // le plus souvent vide — les headers sont payés quand même
}, 2000);

// 2 · Server-Sent Events — un flux HTTP, le serveur pousse des événements texte
const events = new EventSource('/api/stream');
events.onmessage = (e) => render(JSON.parse(e.data));   // se reconnecte tout seul

// 3 · WebSocket — un socket, les deux sens
const ws = new WebSocket('wss://api.example.com/live');
ws.onmessage = (e) => render(JSON.parse(e.data));
ws.send(JSON.stringify({ type: 'typing' }));            // le client pousse aussi
```

Ce que la plupart des applications livrent réellement — une couche d'abonnement qui possède le transport à votre place :

**JavaScript:**

```javascript
// JavaScript / Node.js — Back4app JS SDK
// The polling replacement: subscribe once, receive pushes
const query = new Parse.Query('Message');
query.equalTo('room', 'general');
const subscription = await query.subscribe();    // WebSocket under the hood
subscription.on('create', (msg) => render(msg)); // pushed, not polled
// subscription.unsubscribe() when the screen closes
```

**Flutter:**

```dart
// Flutter / Dart — Back4app Flutter SDK
// The polling replacement: subscribe once, receive pushes
final liveQuery = LiveQuery();
final query = QueryBuilder<ParseObject>(ParseObject('Message'))
  ..whereEqualTo('room', 'general');
final subscription = await liveQuery.client.subscribe(query); // WebSocket under the hood
subscription.on(LiveQueryEvent.create, (msg) => render(msg)); // pushed, not polled
```

**Swift:**

```swift
// iOS / Swift — Back4app Swift SDK
// The polling replacement: subscribe once, receive pushes
let query = Message.query("room" == "general")
let subscription = try await query.subscribe() // WebSocket under the hood
subscription.handleEvent { _, event in
    if case .created(let msg) = event { render(msg) } // pushed, not polled
}
```

**Kotlin:**

```kotlin
// Android / Kotlin — Back4app Android SDK
// The polling replacement: subscribe once, receive pushes
val client = ParseLiveQueryClient.Factory.getClient()
val query = ParseQuery.getQuery<ParseObject>("Message")
query.whereEqualTo("room", "general")
val subscription = client.subscribe(query) // WebSocket under the hood
subscription.handleEvent(SubscriptionHandling.Event.CREATE) { _, msg ->
    render(msg) // pushed, not polled
}
```

## Comment fonctionne chaque technique

**Le short polling** est un `setInterval` autour d'un fetch : demander toutes les *n* secondes si quelque chose a changé. Chaque cycle paie une requête/réponse HTTP complète — headers, authentification, routage — le plus souvent pour s'entendre dire « rien pour l'instant », et le délai de livraison moyen vaut la moitié de l'intervalle plus un aller-retour.

**Le long polling** déplace l'attente côté serveur : le client demande, le serveur *garde la requête ouverte* jusqu'à l'arrivée de données ou l'expiration d'un timeout, le client redemande aussitôt. Il approxime le push sur du HTTP tout simple — le contournement de l'ère Comet, dont les coûts connus (va-et-vient de reconnexions, headers par requête, soin apporté à l'ordre) sont catalogués dans la [RFC 6202](https://datatracker.ietf.org/doc/html/rfc6202).

**Les Server-Sent Events** rendent permanente la réponse maintenue : une réponse HTTP avec `Content-Type: text/event-stream` qui ne se termine jamais, dans laquelle le serveur écrit des événements UTF-8 (champs `data:`, `event:`, `id:`, `retry:`, selon le [standard WHATWG](https://html.spec.whatwg.org/multipage/server-sent-events.html)). L'`EventSource` du navigateur le consomme — et se reconnecte automatiquement, en reprenant via `Last-Event-ID`.

**Les WebSockets** quittent HTTP pour de bon : un handshake fait un upgrade de la connexion (`101 Switching Protocols`, [RFC 6455](https://datatracker.ietf.org/doc/html/rfc6455)), après quoi les deux côtés échangent des frames texte ou binaires avec environ 2 à 14 octets d'overhead, en full-duplex, jusqu'à ce que quelqu'un ferme le socket. Capacité maximale — et tout ce qui se trouve au-dessus du frame (format des messages, accusés de réception, reconnexion, reprise) est à vous de le concevoir.

```mermaid
flowchart LR
  accTitle: Le pull du polling face au push de SSE et des WebSockets
  accDescr: Avec le polling, le client demande sans cesse des mises à jour au serveur et la plupart des réponses sont vides. Avec Server-Sent Events, le serveur pousse des événements vers le client sur un unique flux HTTP maintenu. Avec les WebSockets, client et serveur échangent des frames dans les deux sens sur un seul socket persistant.
  subgraph P["Polling — pull"]
    C1["Client"] -->|"demander toutes les n s (le plus souvent vide)"| S1["Serveur"]
  end
  subgraph E["SSE — push"]
    S2["Serveur"] -->|"un flux HTTP d'événements"| C2["Client<br/>(EventSource)"]
  end
  subgraph W["WebSocket — duplex"]
    C3["Client"] -->|"frames"| S3["Serveur"]
    S3 -->|"frames"| C3
  end
```

## SSE vs. WebSockets vs. long polling vs. short polling

| | Short polling | Long polling | SSE | WebSockets |
| --- | --- | --- | --- | --- |
| Direction | Pull | Push simulé | Serveur → client | Full-duplex |
| Protocole | HTTP ordinaire | HTTP ordinaire | Flux HTTP ordinaire | Protocole propre après upgrade |
| Latence de livraison | intervalle/2 + RTT | ~RTT | ~RTT | ~RTT |
| Payloads | N'importe lesquels | N'importe lesquels | Texte UTF-8 seulement | Texte + binaire |
| Reconnexion auto | Triviale (poll suivant) | Boucle de nouvelle requête | **Intégrée + Last-Event-ID** | À vous de l'écrire |
| Frictions proxy/pare-feu | Aucune | Faibles | Faibles (attention au buffering) | L'upgrade peut être supprimé |
| État serveur | Aucun | Requêtes maintenues | Flux ouverts | Sockets épinglés |
| Complexité | Triviale | Modérée | Faible | La plus élevée |
| Terrain de prédilection | Changements rares | Repli legacy | Flux, notifications, streams IA | Chat, jeux, collaboration |

## Combien coûte le polling ? Le calcul de l'overhead

La comparaison qu'aucune page de classement ne fait — 1 000 clients avec un poll de 2 secondes contre les mêmes 1 000 en push :

```text
1 000 clients, polling de 2 s             1 000 clients, push
→ 500 requêtes/seconde en continu         → 0 requête au repos
→ ~800 B de headers par cycle             → framing d'événement SSE ~5 B
→ ~0,4 Mo/s de pure taxe de headers       → overhead de frame WebSocket 2–14 B
→ quasi toutes les réponses vides         → les octets ne circulent que s'il y a des données
→ délai moyen de livraison : 1 s + RTT    → délai de livraison : ~RTT
```

La leçon coupe dans les deux sens. Le push gagne largement quand les mises à jour sont fréquentes et que la latence compte. Mais si les données changent toutes les heures, ces 500 req/s ne se matérialisent jamais — un poll doux (ou un rechargement au retour de focus) est compatible avec le cache, débogable avec curl, compatible serverless et exempt d'état de connexion. Écarter le polling en bloc relève de la mode, pas de l'ingénierie.

## La reconnexion : le différenciateur discret

Les connexions tombent — passages de cellule, portables qu'on referme, timeouts d'inactivité des proxies (souvent 30 à 120 s, ce qui explique que les flux SSE envoient des commentaires de keep-alive et que les WebSockets échangent des frames ping/pong). Ce qui se passe ensuite sépare les transports. Le contrat de SSE s'en charge : le navigateur réessaie avec le délai `retry` fixé par le serveur et présente `Last-Event-ID`, de sorte qu'un serveur qui garde un court tampon d'événements reprend le flux sans trou. Un WebSocket brut, lui, se contente de se fermer : reconnexion avec backoff exponentiel, récupération des messages manqués et protocole de reprise sont tous du code applicatif — le poste le plus sous-estimé de « on va juste utiliser des WebSockets ». Dans les deux cas, un client hors ligne pendant plusieurs minutes a besoin d'un *rattrapage* (ré-exécuter la requête de base), pas seulement d'une reconnexion — les transports push livrent des deltas, et les deltas supposent une référence.

## Pourquoi le chat IA passe par SSE

La sortie d'un modèle token par token est la charge SSE parfaite : strictement unidirectionnelle, textuelle, en rafales, sur du HTTP ordinaire que tous les proxies et CDN comprennent, avec une sémantique de reprise pour les générations interrompues. C'est pourquoi les API de LLM diffusent massivement leurs complétions en `text/event-stream` — et pourquoi le pattern mérite d'être connu au-delà des chatbots : flux de progression, logs de build et dashboards partagent la même forme. Les WebSockets entrent dans les produits IA à la couche vocale, là où l'utilisateur interrompt en plein flux — au moment où le client doit répondre, la taxe du duplex achète quelque chose.

## Faire passer le push à l'échelle : pourquoi l'état compte

Le polling et SSE sont du HTTP ordinaire pour un load balancer ; n'importe quel serveur peut répondre à n'importe quelle requête (SSE maintient un flux mais garde la sémantique HTTP, il lui faut seulement des proxies sans buffering). Les WebSockets, eux, sont de l'*état* : chaque socket épingle un client à un processus, donc la mise à l'échelle horizontale suppose une répartition consciente des connexions, une vidange lors des déploiements et un backplane [pub/sub](/glossary/fr/pattern-pub-sub/) (souvent Redis) pour qu'un message publié sur le serveur A atteigne les sockets tenus par le serveur B. En HTTP/1.1, SSE a son propre piège célèbre — six connexions par origine *partagées entre les onglets* ([l'avertissement de MDN](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events)) — retiré par HTTP/2, où les streams se multiplexent sur une seule connexion. Rien de tout cela n'est exotique ; tout cela explique l'existence des couches temps réel gérées.

## Cas d'usage courants

- **Flux de notifications et tickers** — un seul sens, du texte, fréquent : le terrain de prédilection de SSE.
- **Streaming des réponses IA** — l'usage phare actuel de SSE ; un seul sens, du texte de tokens, reprise en cas de coupure.
- **Chat et collaboration** — les messages circulent dans les deux sens avec une faible latence : [WebSockets](/glossary/fr/websockets/), généralement via une couche gérée.
- **Dashboards en direct** — push serveur de résultats de requêtes ; en pratique un abonnement [live query](/glossary/fr/live-queries-temps-reel/) plutôt qu'un transport écrit à la main.
- **Données qui changent lentement** — un inventaire mis à jour toutes les heures, des écrans de réglages : du polling ou un rechargement au retour de focus, honnêtement.

## Quel transport devriez-vous utiliser ? Matrice de décision

| Votre situation | Choisissez |
| --- | --- |
| Serveur → client seulement (flux, streams, progression) | SSE |
| Client et serveur émettent tous deux en temps réel | WebSockets |
| Des mises à jour plus rares que toutes les quelques minutes | Short polling / rechargement au retour de focus |
| Proxies hostiles, infrastructure legacy | Long polling en repli |
| Payloads binaires ou à haute fréquence | WebSockets |
| Plateforme serverless, timeouts de fonctions | Polling ou SSE via des hébergeurs capables de streaming |
| « Je veux juste des données en direct à l'écran » | Une couche de live queries qui possède le transport |

## Limites et trade-offs

- **SSE est en texte seul et à sens unique.** Le binaire doit être encodé ; tout bavardage du client vers le serveur passe par des requêtes HTTP séparées — parfait pour des accusés de réception, inadapté pour du chat.
- **Les WebSockets vous mettent dans le métier du protocole.** Framing, accusés de réception, reconnexion, reprise, backpressure : le transport est facile, le contrat au-dessus est le vrai travail.
- **La simplicité du polling cache un plancher de latence.** Aucun réglage n'échappe au délai moyen d'intervalle/2 ; réduire l'intervalle ne fait que racheter la taxe des headers.
- **Le long polling est le pire des deux à grande échelle.** Les requêtes maintenues consomment la capacité serveur comme le push, tout en payant un overhead de reconnexion par message comme le pull — d'où sa survie uniquement comme barreau de repli.
- **Tous les transports push exigent la coopération des proxies.** La mise en tampon des flux casse silencieusement SSE ; des headers d'upgrade supprimés cassent les WebSockets — testez à travers l'infrastructure réelle, pas sur localhost.

## Les transports temps réel sur Back4app

Back4app est une plateforme open-source de Backend as a Service (BaaS) qui combine une base de données gérée, des API REST et GraphQL générées automatiquement, l'authentification, le stockage de fichiers et des fonctions serverless avec Cloud Code. La décision de transport est en grande partie absorbée par les [Live Queries](/glossary/fr/live-queries-temps-reel/) : les onglets de code ci-dessus s'abonnent à une requête et reçoivent des événements poussés sur une flotte de WebSockets exploitée par la plateforme — connexions, reconnexions, vérifications de permissions et fan-out inter-serveurs compris — si bien que « SSE ou WebSockets ? » devient un détail d'implémentation dont vous héritez plutôt qu'une infrastructure à construire. Là où une cadence plus douce convient réellement, la même requête s'exécute comme un simple fetch à votre rythme ; poller une requête Parse et s'y abonner ne sont séparés que par une ligne, ce qui fait du bon transport par fonctionnalité un refactoring, pas une réécriture.
