Regarde ben. Tu construis une app qui doit se mettre à jour en direct : un outil collaboratif, un tableau de bord live, un chat, un système de notifications. Tu regardes Convex et Supabase. Les deux promettent du temps réel. Les deux ont une belle DX. Les deux ont des plans gratuits pour commencer. Sauf que les deux ne font pas la même affaire sous le capot, et choisir le mauvais dès le départ va te coûter soit une migration douloureuse, soit une facture qui grimpe à un rythme que t’as pas anticipé. Ce que tu vas apprendre :

  • Comment Convex et Supabase gèrent le temps réel à un niveau architectural (et pourquoi c’est pas la même chose)
  • Ce que le passage de Convex en open source en février 2025 change concrètement pour toi
  • Quand PostgreSQL complet est un avantage réel vs quand le modèle de documents de Convex gagne
  • Comment les coûts divergent à mesure que ton volume monte
  • Quel outil choisir selon le type exact d’app que tu construis

Ce que fait chaque plateforme, en deux minutes

Supabase a été fondé en 2020 par Paul Copplestone et Ant Wilson, passé par Y Combinator W21. Le pitch est simple : PostgreSQL en tant que service, avec une couche d’API auto-générée, de l’auth, du stockage fichier, et des Edge Functions. Tout est bâti sur Postgres et publié en open source sous licence Apache 2.0. Si tu connais SQL, tu es à la maison. Convex, c’est une approche différente. C’est un backend-as-a-service centré sur la réactivité native. Ton état d’application vit dans une base de documents sur le serveur, et tes composants React (ou autre) s’y abonnent automatiquement via des queries déclaratives. Quand les données changent, les composants se re-rendent. Sans polling. Sans WebSocket géré manuellement. Le tout avec des transactions ACID.

Diagramme comparatif de deux architectures temps réel : Convex avec un moteur réactif central et flèches bidirectionnelles vers les clients, Supabase avec PostgreSQL au centre et canaux WebSocket distincts.
Deux philosophies du temps réel — chez Convex, un moteur réactif unique orchestre requêtes et mutations dans les deux sens ; chez Supabase, PostgreSQL reste souverain et le Realtime se greffe canal par canal via WebSocket au-dessus du WAL.

Le truc c’est que les deux ont l’air pareils en surface : tu fais des queries, tu écris des données, ça se propage aux clients. Mais la mécanique interne est fondamentalement différente. Et cette différence a des conséquences concrètes sur la façon dont tu écris ton code, sur ce que tu paies, et sur jusqu’où tu peux scaler.

Architecture temps réel : comment les deux gèrent les mises à jour en direct

Convex : réactivité comme primitive

Dans Convex, une query n’est pas juste un fetch ponctuel. C’est un abonnement déclaratif. Tu définis ta query côté serveur en TypeScript, le runtime de Convex l’exécute, et quand n’importe quelle donnée sous-jacente change, la query se re-exécute automatiquement. Les clients reçoivent le nouvel état sans que tu aies besoin de configurer quoi que ce soit.

Schéma annoté du cycle de vie d'une query Convex, de sa définition TypeScript au push vers les clients abonnés, avec boucle de re-exécution via mutation.
Une query Convex n'est pas une requête ponctuelle : c'est un abonnement. Le runtime trace les dépendances de lecture pendant l'exécution serveur, compare le résultat au précédent (diff), pousse la mise à jour aux clients concernés — puis toute mutation touchant ces dépendances relance automatiquement le cycle.

La latence mesurée en benchmark atteint moins de 50 ms sous une charge de 5 000 connexions simultanées. C’est pas un chiffre marketing : c’est le résultat d’une architecture où la réactivité est au cœur du runtime, pas une couche ajoutée par-dessus. Le modèle mental est proche de ce que React fait côté UI : tu déclares l’état que tu veux, le système s’occupe de synchroniser. Sauf que là c’est côté serveur, pour toutes les données partagées entre tes utilisateurs.

Supabase Realtime : WebSockets sur PostgreSQL

Supabase s’appuie sur son moteur Realtime, qui écoute le Write-Ahead Log (WAL) de PostgreSQL et propage les changements via WebSockets. C’est puissant, et ça marche. Mais c’est une couche distincte de ton modèle de données principal.

Schéma du flux Supabase Realtime : du WAL PostgreSQL vers le serveur Realtime, puis diffusion aux clients via WebSocket sur trois canaux — Postgres Changes, Broadcast et Presence.
Anatomie de Supabase Realtime — le WAL PostgreSQL est répliqué vers un serveur Elixir qui multiplexe trois canaux distincts sur un même WebSocket : Postgres Changes (événements de lignes issus du log), Broadcast (messages éphémères de client à client) et Presence (état partagé des connexions).

Tu as trois modes : Postgres Changes (écoute les changements d’une table), Broadcast (messages éphémères entre clients), et Presence (qui est connecté). Chacun a un cas d’usage. Mais tu dois choisir lequel utiliser selon ce que tu veux faire, et les configurer explicitement. Sauf qu’en pratique, le Realtime de Supabase est excellent pour des cas ciblés : notifications en direct, feeds d’activité, curseurs collaboratifs simples. Pour une app où l’état global change fréquemment et doit se propager à tous les composants automatiquement, tu vas écrire plus de code de synchronisation que tu ne le voudrais.

Modèle de données : documents vs PostgreSQL relationnel

Le modèle de documents de Convex

Convex stocke tes données dans des tables de documents typées, définies en TypeScript avec son schéma maison. Tu n’écris pas de SQL. Tu définis tes types, tu requêtes avec l’API JavaScript de Convex, et le runtime gère la cohérence des transactions.

Schéma Convex en TypeScript montrant deux tables users et messages liées par un champ authorId typé v.id("users").
Dans Convex, les relations se déclarent avec v.id("table") : le lien entre messages.authorId et users est vérifié par TypeScript à la compilation, sans clé étrangère au sens SQL.

L’avantage : cohérence des types de bout en bout. Ton schéma TypeScript côté serveur correspond exactement à ce que tu reçois côté client. Zéro désynchronisation. L’inconvénient : tu perds la puissance de SQL. Les jointures complexes, les agrégations sophistiquées, les requêtes analytiques qui exploitent toute la surface de PostgreSQL, c’est soit impossible soit lourd à reproduire avec l’API Convex. Pour la majorité des apps CRUD-avec-temps-réel, le modèle de Convex est suffisant. Et il est souvent plus rapide à prendre en main parce que tu restes en TypeScript du début à la fin.

PostgreSQL complet dans Supabase

Supabase te donne PostgreSQL complet. Toutes les extensions, toutes les fonctions d’agrégation, les vues matérialisées, les triggers, les procédures stockées, les politiques de sécurité au niveau des lignes (Row Level Security). Si tu peux l’écrire en SQL standard ou avec des extensions Postgres populaires comme pgvector ou PostGIS, tu peux le faire dans Supabase.

Reproduction stylisée de l'interface Supabase avec le Table Editor à gauche listant les tables users, orders, products, et l'éditeur SQL affichant une requête avec JOIN et agrégation, suivie du panneau de résultats.
Supabase reste fidèle au terrain familier de SQL : Table Editor pour parcourir le schéma, éditeur ouvert sur une requête avec JOIN, GROUP BY et HAVING, résultats en dessous. Tout ce que Postgres sait faire, tu le fais ici.

C’est un avantage réel pour les apps avec des données relationnelles complexes : systèmes de facturation, gestion de stock, analytics, tout ce qui bénéficie de la puissance déclarative de SQL. Et si ton équipe connaît déjà Postgres, la courbe d’apprentissage est quasi nulle. Le plan Pro de Supabase coûte 25 $US/mois et inclut 8 GB de base de données. C’est le point d’entrée payant. Le plan Free est gratuit (0 $US/mois), avec des limites sur les ressources qui sont suffisantes pour prototyper ou pour des projets à faible trafic.

À retenir : si ton app a besoin de requêtes relationnelles sophistiquées, de rapports ou d’une migration depuis une base Postgres existante, Supabase gagne clairement sur ce terrain. Si tu construis une app principalement guidée par des mutations et des lectures réactives simples, Convex est plus direct.


Fonctions serveur et logique métier

Convex : queries, mutations et actions

Convex organise ta logique serveur en trois types de fonctions. Les queries lisent les données de façon réactive (et peuvent être mises en cache). Les mutations écrivent des données dans des transactions ACID automatiques. Les actions appellent des services externes ou font des opérations non déterministes (appels API tiers, génération IA, etc.).

Schéma éditorial en trois panneaux comparant les fonctions Convex : query, mutation et action, avec leurs contraintes respectives.
Trois fonctions, trois contrats. Les queries lisent et se souscrivent (cachables, déterministes). Les mutations écrivent dans une transaction atomique. Les actions ouvrent la porte au monde extérieur — au prix du déterminisme et du cache.

Tout ça s’écrit en TypeScript, dans des fichiers qui vivent dans ton repo. Tu déploies avec la CLI de Convex. La séparation entre ces trois types n’est pas juste cosmétique : elle permet au runtime de Convex de garantir des propriétés transactionnelles sur les mutations et de propager les changements aux queries abonnées sans que tu aies à y penser. Le hic : tu es dans l’écosystème Convex. Tu n’as pas accès à node_modules arbitraires dans les queries et mutations (seulement dans les actions). Et si tu veux faire des opérations complexes qui mélangent lecture, écriture et appels externes dans une seule unité logique, la séparation devient parfois contraignante.

Supabase : Edge Functions et PostgreSQL Functions

Supabase a deux options pour la logique serveur. Les Edge Functions sont des fonctions Deno déployées sur un CDN distribué : tu écris du TypeScript ou du JavaScript, tu les déploies, elles tournent près de tes utilisateurs. Les PostgreSQL Functions (en SQL ou en PL/pgSQL) vivent directement dans ta base.

Maquette éditoriale au trait d'un tableau Supabase Edge Functions listant six fonctions déployées avec régions et statuts, reliée par une flèche à un terminal exécutant la commande supabase functions deploy.
À gauche, la console Supabase affiche les Edge Functions déployées, leur région (us-east-1, eu-west-3, ap-south-1) et leur statut. À droite, le terminal exécute `supabase functions deploy` : une seule commande suffit à propager la fonction jusqu'à la région choisie.

Les Edge Functions sont flexibles. Tu peux importer des packages npm compatibles Deno, appeler des APIs externes, structurer ta logique comme tu veux. Le trade-off : elles sont stateless et sans accès réactif aux données. Tu dois gérer toi-même la synchronisation entre une mutation dans une Edge Function et la mise à jour des clients temps réel. Pour la logique métier purement relationnelle (contraintes, triggers, agrégations), les fonctions PostgreSQL sont plus directes et plus performantes que passer par une Edge Function. Mais elles requièrent de maîtriser PL/pgSQL ou SQL avancé.

Authentification, permissions et sécurité

Comment Convex gère l’auth

Convex ne fournit pas son propre système d’auth. Il s’intègre avec des providers externes : Clerk, Auth0, ou un système custom via JWT. Dans tes fonctions Convex, tu récupères le contexte utilisateur depuis le JWT validé, et tu l’utilises pour filtrer tes queries ou autoriser tes mutations.

Schéma en trois étapes du flux d'authentification Convex : Clerk émet un JWT, le runtime Convex le valide, et l'identité est injectée dans le contexte des fonctions serveur pour filtrer les données.
Trois maillons, un seul jeton. Clerk signe le JWT côté provider, Convex vérifie la signature et expose <code>ctx.auth.getUserIdentity()</code> dans chaque query — le filtrage par utilisateur devient une propriété du contexte, pas une vérification à refaire à chaque requête.

C’est flexible, mais ça veut dire une dépendance externe supplémentaire. Si tu utilises déjà Clerk ou Auth0, l’intégration est bien documentée et rapide. Si tu pars de zéro et que tu veux tout-en-un, c’est un point de friction. Les permissions dans Convex se font par code : tu écris explicitement les vérifications dans tes mutations et queries. C’est lisible et testable, mais moins déclaratif que RLS.

Row Level Security dans Supabase

Supabase a une auth intégrée, bâtie sur GoTrue. Tu configures des providers OAuth (Google, GitHub, etc.), des magic links, ou email/password directement dans le tableau de bord. Pas de dépendance externe requise pour les cas courants.

La vraie force de Supabase côté sécurité : PostgreSQL Row Level Security. Tu définis des politiques SQL qui s’appliquent directement au niveau de la base de données. Même si ton Edge Function a un bug, une politique RLS mal configurée est la seule façon pour un utilisateur d’accéder à des données qui ne lui appartiennent pas. C’est du défense-en-profondeur natif.

Schéma éditorial d'une interface Supabase : table messages avec toggle RLS activé, politique SQL utilisant auth.uid() extrait du JWT, et évaluation ligne par ligne montrant les lignes acceptées ou rejetées.
L'éditeur de politiques Supabase : le toggle RLS · ON verrouille la table messages, la policy select_own_messages compare user_id à auth.uid() extrait du JWT, et Postgres filtre les lignes avant même que le client n'y accède.

La configuration de RLS peut être complexe pour des modèles de permissions sophistiqués. Mais une fois en place, c’est déclaratif, centralisé, et auditable en SQL.

Performance et scalabilité : ce que les benchmarks montrent vraiment

Soyons clairs sur une chose : comparer des benchmarks entre deux systèmes d’architecture fondamentalement différente, c’est souvent comparer des pommes et des oranges. Convex a mesuré moins de 50 ms de latence sur les mises à jour réactives avec 5 000 connexions simultanées. C’est un résultat solide pour une charge que beaucoup d’apps n’atteignent pas avant d’avoir trouvé leur product-market fit.

Supabase, côté Realtime, performerait bien à l’échelle sur des cas d’usage ciblés comme le Broadcast et le Presence. Pour des changements Postgres intensifs propagés via le WAL, la latence dépend de la charge sur ta base de données principale et de la configuration de ton plan. Ce sont des variables que tu contrôles partiellement.

Graphique comparant deux courbes de latence sous charge croissante : Convex reste plate, Supabase Realtime devient irrégulière.
Sous charge croissante, la réactivité native de Convex maintient une latence quasi constante, tandis que Supabase Realtime hérite des variations de la couche PostgreSQL sous-jacente — écritures, index, contention. Représentation qualitative, sans chiffres.

La vraie question de scalabilité, c’est surtout une question de modèle de facturation. Convex facture à la lecture réactive. Supabase facture à la connexion Realtime, au stockage, et aux ressources compute. Selon ton pattern d’usage, l’un peut devenir significativement plus coûteux que l’autre à mesure que tu grossis. On en parle dans la section pricing. Pour les apps qui ont besoin de queries analytiques lourdes en lecture, PostgreSQL de Supabase peut être optimisé avec des index, des vues matérialisées et des connexions en lecture seule sur des réplicas. Convex n’a pas d’équivalent natif pour ce type de charge analytique.

Pricing : ce que tu paies réellement à volume croissant

Plan Convex Supabase
Gratuit Oui (limites sur appels et stockage) Oui, 0 $US/mois
Entrée payante ~ 25 $/mois Pro : 25 $US/mois, inclut 8 GB base de données
Équipe / Scale À vérifier dans la doc selon usage Team : 599 $US/mois
Entreprise Contrat négocié Contrat négocié (0 $US affiché, contact sales)

Le plan de départ payant des deux plateformes s’aligne autour de 25 $ par mois. Sauf que ce que tu obtiens pour ce 25 $ diverge. Supabase Pro te donne PostgreSQL complet avec 8 GB de base de données, l’auth, le stockage fichier, et des connexions Realtime incluses jusqu’à une certaine limite. Le modèle est relativement prévisible si ton usage est stable. Convex facture principalement en fonction du nombre de lectures réactives (chaque fois qu’une query se re-exécute côté serveur à cause d’un changement de données) et du stockage. Pour une app très collaborative où beaucoup d’utilisateurs ont des abonnements actifs à des queries qui changent fréquemment, ce compteur monte vite. La bonne nouvelle : tu peux le monitorer en temps réel dans le tableau de bord Convex.

Reconstitution éditoriale au trait d'un tableau de bord Convex : courbe des lectures réactives sur 7 jours avec pics quotidiens, et trois compteurs latéraux — stockage, appels API, fonctions actives.
Fig. 01 — Tableau de bord Convex reconstitué : la courbe ambrée trace les lectures réactives minute par minute sur sept jours. Les pics correspondent aux heures de collaboration synchrone. À droite, les compteurs de stockage (2,4 Go), d'appels API (184k/24h, en hausse notable) et de fonctions actives (42) rappellent que Convex facture l'abonnement réactif — pas seulement la requête initiale.

Le saut vers le plan Team de Supabase à 599 $US/mois est important. Il ajoute des SLA, du support prioritaire, et des features pour les équipes. Si ton app est en production avec des utilisateurs réels et que tu as besoin de garanties, ce tier existe. Chez Convex, la progression tarifaire est plus graduelle selon l’usage. La règle générale : pour un projet de démarrage ou un SaaS en phase de lancement, les deux plans gratuits te permettent de valider. Pour un projet en croissance qui commence à avoir du trafic réel, modelise ton usage estimé dans les deux calculateurs de pricing avant de t’engager.

Convex open source depuis février 2025 : ce que ça change concrètement

En février 2025, Convex a publié son code source. C’est un changement significatif dans l’équation pour les équipes qui ont une sensibilité au vendor lock-in ou qui opèrent dans des secteurs avec des contraintes de souveraineté des données.

Représentation stylisée de la page GitHub du dépôt convex-backend montrant l'arborescence du projet, les commits récents de la communauté et la licence Apache 2.0.
Depuis février 2025, Convex publie son backend en Apache 2.0 : arborescence Rust, SDKs npm, protocole de synchronisation — et une activité de commits partagée entre l'équipe cœur et la communauté.

Concrètement, ça veut dire quoi ? Que tu peux, en théorie, self-héberger Convex sur ta propre infrastructure. C’est différent de Supabase qui est Apache 2.0 depuis le début et pour qui self-héberger est une pratique courante et bien documentée. Convex n’a pas encore la même maturité d’outillage pour le self-hosting, mais la direction est claire. Pour la majorité des équipes, le self-hosting n’est pas le premier réflexe. Mais le simple fait que le code soit disponible change la dynamique de la négociation avec le fournisseur et réduit le risque perçu d’un lock-in irréversible. Tu peux auditer le code, comprendre exactement ce qui se passe avec tes données, et te préparer à une sortie si jamais le pricing devient inacceptable. Supabase est open source sous Apache 2.0 depuis sa fondation. Le self-hosting Supabase est concret et utilisé en production par des équipes qui veulent garder PostgreSQL sur leur infrastructure. La documentation de déploiement est mature.

Le verdict sur l’open source : Supabase a une longueur d’avance sur la maturité du self-hosting. Convex a fait le premier pas en février 2025, et c’est une bonne nouvelle pour l’écosystème, mais si self-héberger est un requirement non-négociable pour toi aujourd’hui, Supabase est le choix plus sûr.


Quel outil pour quel projet : tableau comparatif et scénarios types

Critère Convex Supabase
Temps réel natif Réactivité automatique bout en bout WebSockets via Realtime, configuration manuelle
Modèle de données Documents typés TypeScript PostgreSQL complet avec SQL
Logique serveur Queries / Mutations / Actions TS Edge Functions (Deno) + PostgreSQL Functions
Auth intégrée Non (Clerk, Auth0, JWT custom) Oui (GoTrue, OAuth, email/password)
Permissions Par code dans les fonctions Row Level Security déclaratif en SQL
Self-hosting Possible depuis fév. 2025 (maturité en cours) Oui, bien documenté (Apache 2.0)
Courbe d'apprentissage Rapide si tu connais TypeScript Rapide si tu connais SQL et Postgres
Plan payant entrée ~ 25 $/mois 25 $US/mois, 8 GB base de données inclus
Adapté pour Outils collaboratifs, apps fortement réactives Apps relationnelles, données complexes, migration Postgres
Matrice 2x2 positionnant Convex en haut-gauche (haute réactivité, données simples) et Supabase en milieu-droit (données complexes, réactivité ciblée) sur les axes complexité des données et intensité temps réel.
Deux philosophies du temps réel — Convex privilégie la réactivité native sur un modèle de données direct ; Supabase capitalise sur la richesse relationnelle de Postgres avec une réactivité ciblée.

Choisir Convex si…

Tu construis un outil collaboratif où plusieurs utilisateurs modifient le même état en temps réel : un éditeur de documents, un tableau Kanban collaboratif, un whiteboard, un jeu en temps réel, ou une interface de chat avec état partagé complexe. La réactivité automatique de Convex élimine des classes entières de bugs de synchronisation. Tu travailles en TypeScript de bout en bout et tu veux que ton schéma de données soit une source de vérité unique partagée entre le front et le back. Le typage de bout en bout que Convex offre réduit le temps de débogage sur les désynchronisations de types. Tu démarres un projet sans historique de données et tu veux aller vite sur la logique métier sans configurer manuellement des WebSockets, des subscriptions ou des politiques RLS complexes.

Choisir Supabase si…

Tu as un schéma relationnel existant ou tu migres depuis une base PostgreSQL. L’import est direct, les outils Postgres que tu connais fonctionnent, et tu ne réapprends pas un modèle de données. Ton app bénéficie de la puissance SQL : rapports, dashboards analytiques, jointures multi-tables complexes, utilisation d’extensions comme pgvector pour la recherche sémantique ou PostGIS pour les données géographiques. Convex ne peut pas rivaliser ici. Tu veux une solution tout-en-un avec auth intégrée, stockage fichier, et Realtime dans un seul service, avec un plan Free solide pour prototyper et une documentation mature pour le self-hosting. Ton équipe est à l’aise avec SQL mais moins à l’aise avec les de programmation réactive. La courbe d’apprentissage de Supabase pour une équipe SQL-native est beaucoup plus douce.

Les limites que personne ne te dit d’avance

Le hic avec Convex

La dépendance à l’écosystème Convex est réelle. Tes queries et mutations s’écrivent avec l’API Convex, pas avec une librairie SQL standard ou un ORM standard. Si tu décides de migrer hors de Convex dans 18 mois, tu réécris ta couche de données complète. Le self-hosting, bien que possible depuis février 2025, n’est pas encore aussi simple qu’avec Supabase. Si tu as un requirement de souveraineté des données strict et que tu dois déployer sur ta propre infrastructure aujourd’hui, tu vas te débattre avec une documentation encore en construction. Les queries analytiques lourdes sont difficiles. Convex n’est pas une base analytique. Si ton app commence à avoir des besoins de reporting complexes, tu vas soit exporter vers un outil analytique séparé, soit souffrir avec les limitations du modèle de requêtes de Convex.

Schéma d'architecture hybride : Convex sert l'état temps réel des clients tandis qu'un pipeline ETL exporte les données vers un entrepôt analytique alimentant les rapports.
À gauche, Convex tient l'état vivant de l'app (requêtes réactives, mutations, websockets). À droite, un pipeline d'export périodique déverse les données dans un entrepôt OLAP dédié aux rapports lourds — la ligne pointillée matérialise la limite analytique de Convex.

Le hic avec Supabase

Le Realtime de Su

On continue à la Taverne ?

Un courriel par semaine. Pas de fluff.

En t'abonnant, tu reçois Le Tour de Table chaque semaine. Tu peux te désabonner en un clic. Voir notre politique de confidentialité.

Texte par David Cyr