Galahad ← Blogue
Retour au blogue

Les pièges du serverless pour les applications IA

Déployer une application IA en serverless paraît simple au départ. En pratique, l’environnement serverless impose des contraintes qui ne se manifestent pas en développement local et qui peuvent causer des bugs silencieux difficiles à diagnostiquer.

Voici les pièges que j’ai rencontrés en construisant Galahad.

Piège 1 : les dépendances qui supposent un navigateur

Le plus insidieux. Certaines librairies Node.js supposent l’existence d’APIs navigateur — DOMMatrix, window, document — même quand elles s’exécutent côté serveur. En développement local, ces APIs peuvent être polyfillées automatiquement. En serverless avec Turbopack, le module crashe au chargement.

Dans mon cas : pdf-parse, la librairie standard pour lire des PDF en Node.js, dépend de pdfjs-dist qui référence DOMMatrix à l’initialisation du module. Le crash se produisait avant même que la fonction soit appelée — ce qui rendait toute la route inutilisable.

Solution : remplacer par unpdf, une alternative conçue spécifiquement pour les environnements sans navigateur.

Règle à retenir : avant d’ajouter une dépendance à une fonction serverless, vérifier si elle a des dépendances implicites sur des APIs navigateur.

Piège 2 : les promesses fire-and-forget qui ne s’exécutent pas

En serverless, la fonction s’arrête dès que la réponse HTTP est envoyée. Une promesse lancée avec void (sans await) peut ne jamais s’exécuter si la fonction se termine avant qu’elle soit résolue.

Dans Galahad : le message de l’utilisateur était sauvegardé en base de données de façon fire-and-forget pour ne pas bloquer le stream de réponse. En production, les messages utilisateurs n’apparaissaient pas dans l’historique des conversations — la promesse ne s’exécutait pas.

Solution : utiliser after() de Next.js 15, qui garantit l’exécution après la réponse HTTP, ou simplement await les opérations critiques.

Règle à retenir : void est dangereux en serverless pour les opérations qui doivent absolument se terminer.

Piège 3 : les timeouts sur les opérations longues

Les fonctions serverless ont des timeouts. Une opération d’indexation de document — parsing PDF, génération d’embeddings par batch, insertion en base — peut facilement dépasser 30 secondes pour un document de taille moyenne.

Solution : ne jamais faire d’indexation synchrone dans une réponse HTTP. Utiliser after() pour l’indexation post-upload, ou un système de queue pour les opérations longues.

Règle à retenir : toute opération qui dépasse 10 secondes doit être asynchrone.

Piège 4 : le stockage privé Supabase

Supabase Storage avec un bucket privé ne peut pas être accédé via l’URL publique — elle retourne 400. En développement, si le bucket était public pendant les tests, le problème ne se manifeste qu’en production après le passage en privé.

Solution : toujours utiliser createSignedUrl() pour générer une URL temporaire (60 secondes suffit), puis fetch() avec cette URL signée.

Règle à retenir : ne jamais stocker l’URL publique d’un bucket privé en base de données. Elle sera invalide.

Ce que j’en retiens

Le serverless est excellent pour les opérations stateless et rapides. Pour les applications IA — qui impliquent des appels API externes, des opérations longues et des dépendances complexes — chaque déploiement révèle des comportements inattendus.

La stratégie la plus efficace : tester le build de production localement (vercel dev) avant de déployer, et ne jamais supposer que “ça marche en dev donc ça marchera en prod”.