ob / ouahabi-benhenni EN

Article ·

Tenir 218 000 requêtes sur 2 vCPU : l'architecture backend sous contrainte

Quand le matériel est limité, l'architecture ne peut plus se cacher derrière des serveurs supplémentaires. Retour sur une plateforme temps réel avec voix qui a tenu la charge sur un très petit serveur.

Le contexte

Le projet : un jeu multijoueur en temps réel, organisé en salles, avec un chat vocal intégré et des permissions vocales qui changent selon le rôle de chaque joueur. L'infrastructure : un VPS de 2 vCPU et 2 Go de RAM. Le résultat : 218 000 requêtes traitées en 3 heures.

En moyenne, cela représente une vingtaine de requêtes par seconde — mais la moyenne cache l'essentiel. Dans un jeu en temps réel, la charge arrive par vagues : tout le monde rejoint une salle en même temps, tout le monde parle au même moment. C'est pour ces pics qu'il faut concevoir.

Décision 1 : séparer la signalisation du transport média

Un système de voix sur le web fait deux choses très différentes. La signalisation — qui rejoint quelle salle, qui a le droit de parler, qui quitte — consiste en petits messages fréquents. Le média — les flux audio eux-mêmes — représente un volume continu et lourd.

Les mélanger, c'est obliger chaque composant à être bon dans les deux rôles. Je les ai séparés : la signalisation passe par Socket.io, et les flux audio par WebRTC, relayés par un SFU (Selective Forwarding Unit) mediasoup. Chaque couche se dimensionne alors pour ce qu'elle fait réellement.

Décision 2 : relayer plutôt que mixer

Un SFU ne décode pas et ne mixe pas l'audio : il transmet sélectivement les flux aux participants concernés. Le serveur fait donc beaucoup moins de calcul qu'une architecture qui mélangerait toutes les voix côté serveur. Sur 2 vCPU, cette différence est décisive.

Décision 3 : la salle comme unité d'isolation

Chaque salle est un périmètre indépendant : ses participants, ses flux, ses permissions. Un pic d'activité dans une salle ne se propage pas aux autres, et l'état à gérer reste petit et local.

Les permissions vocales (RBAC) jouent aussi un rôle de performance : seuls les joueurs autorisés à parler produisent un flux audio. Moins de flux produits, c'est moins de flux à relayer.

Décision 4 : la frugalité partout ailleurs

Sur 2 Go de RAM, chaque connexion et chaque octet comptent. Nginx en frontal, des processus Node.js supervisés par PM2, et une règle simple : ne rien faire côté serveur qui puisse être évité — pas de traitement inutile, pas d'état superflu, pas de message envoyé à ceux qui n'en ont pas besoin.

Ce qui se transpose à d'autres systèmes

  • Les contraintes sont la spécification. Le matériel disponible n'est pas un obstacle à contourner, c'est une donnée d'entrée de l'architecture.
  • Séparer ce qui a des profils de charge différents. Messages courts et flux lourds, lectures et écritures, synchrone et asynchrone.
  • Isoler pour contenir. Un découpage en unités indépendantes limite la propagation des pics et des pannes.
  • Concevoir pour les pics, pas pour la moyenne.
  • Mesurer. Une architecture se juge à ce qu'elle supporte en vrai, pas sur un schéma.

Ces principes valent autant pour un SaaS multi-tenant ou un service d'inférence IA que pour un jeu. Une infrastructure modeste oblige simplement à les appliquer plus tôt — et c'est souvent une bonne chose.

Pour aller plus loin : mon travail d'architecte backend et le schéma de cette architecture.

Un projet de transformation, une architecture à concevoir ?

Entreprises, startups, institutions : décrivez-moi votre contexte en quelques lignes. Je réponds personnellement, avec un premier avis sur la faisabilité et la démarche.

Proposer une mission LinkedIn ↗ GitHub ↗

Missions en Algérie, en France, en Europe, au Maghreb et à distance · Arabe, français, anglais · contact@ouahabi-benhenni.com