Dans l'article sur l'architecture Snowflake, on a vu que la plateforme repose sur trois couches ( le storage, le compute et le Cloud Services ).

Et dans l'article FinOps, on a vu comment surveiller et contrôler les coûts liés au compute (resource monitors, budgets, auto-suspend, etc...).

Ici, on va bien faire un focus sur le warehouse lui-même donc savoir comment il fonctionne, comment le dimensionner, comment gérer la montée en charge avec le multi-cluster, et comment bien piloter la concurrence.

C'est quoi concrètement un virtual warehouse

Un virtual warehouse, c'est tout simplement un cluster de serveurs mis à ta disposition par Snowflake pour exécuter tes requêtes SQL, tes chargements de données, et tes transformations.

Ne pas oublier que le warehouse ne stocke rien de manière permanente. Les données restent dans la couche storage (S3, Azure Blob, GCS). Donc le warehouse se contente de lire les données, les traiter, et renvoyer le résultat. Et c'est justement ce que permet la séparation stockage/compute car tu peux avoir 1, 5 ou 20 warehouses qui tournent en parallèle, chacun dédié à un usage différent, et tous accèdent à la même donnée sans se marcher dessus.

CREATE WAREHOUSE wh_analytics
  WAREHOUSE_SIZE = 'MEDIUM'
  AUTO_SUSPEND = 300
  AUTO_RESUME = TRUE;

Sizing : la logique t-shirt

Snowflake classe les warehouses avec une logique très simple, façon t-shirt : X-Small, Small, Medium, Large, X-Large, 2X-Large, 3X-Large, 4X-Large, 5X-Large et 6X-Large.

La règle est facile à retenir :

À chaque taille au-dessus, tu doubles la puissance de calcul et la consommation de crédits.
Taille Crédits / heure Nœuds (serveurs)
X-Small (XS) 1 1
Small (S) 2 2
Medium (M) 4 4
Large (L) 8 8
X-Large (XL) 16 16
2X-Large 32 32
3X-Large 64 64
4X-Large 128 128
5X-Large 256 256
6X-Large 512 512

Concrètement, un Medium consomme 4 crédits par heure. Si tu le laisses tourner 15 minutes, tu paies 1 crédit (4 × 0.25). Si tu passes en Large, les mêmes 15 minutes te coûtent 2 crédits.

Quand monter en taille (et quand c'est inutile)

La question à se poser n'est pas "quelle est la plus grosse taille ?", mais plutôt :

Est-ce que doubler la taille divise le temps d'exécution par deux ?

Sur des requêtes qui scannent beaucoup de données (agrégations, jointures sur de grosses tables), la réponse est souvent oui. Snowflake parallélise le travail sur plus de nœuds, et le gain est quasi linéaire.

Mais dans certains cas, un warehouse plus gros ne changera rien :

  • Requête avec peu de données à scanner : si ta requête filtre sur un WHERE très sélectif et touche 3 micro-partitions, un X-Large ne sera pas plus rapide qu'un Small. Il aura juste 15 nœuds qui attendent sans rien faire.
  • Requête séquentielle : certaines opérations ne se parallélisent pas bien
  • Résultat déjà en cache : si le result cache s'applique, le warehouse n'est même pas sollicité, quelle que soit sa taille.

C'est pour ça que le Query Profile est essentiel. Avant de monter en taille, regarde ce que la requête fait réellement. Si le problème est lié à la mémoire du disque, un warehouse plus gros peut aider. Si c'est un mauvais plan d'exécution ou un manque de clustering, augmenter la taille ne résoudra pas grand chose mais te fera payer quand même plus cher.

Changer la taille à la volée

Tu peux modifier la taille d'un warehouse à tout moment sans le recréer. Le changement prend effet immédiatement pour les nouvelles requêtes mais les requêtes déjà en cours continuent avec l'ancienne taille.

-- Pipeline compliqué ? On passe en X-Large
ALTER WAREHOUSE wh_etl SET WAREHOUSE_SIZE = 'X-LARGE';

-- Pipeline terminé, on redescend
ALTER WAREHOUSE wh_etl SET WAREHOUSE_SIZE = 'LARGE';

C'est ce qu'on appelle le scale up / scale down. L'idée est de ne pas payer un gros warehouse en permanence, mais de le muscler ponctuellement quand tu en as besoin.

Auto-suspend et auto-resume

On a déjà vu l'auto-suspend et l'auto-resume en détail dans l'article FinOps (avec les recommandations par cas d'usage). Ici, je veux juste parler sur un point qu'on n'avait pas creusé et c'est le lien entre l'auto-suspend et le warehouse cache.

Quand un warehouse tourne, il garde en cache local les données qu'il a récemment lues depuis le storage distant. C'est le warehouse cache. Si un analyste lance une requête similaire juste après, le warehouse peut lire depuis son cache local au lieu de retourner chercher les données. C'est beaucoup plus rapide.

Le problème c'est quand un warehouse est suspendu puis redémarré, il perd son cache. Les premières requêtes après un redémarrage seront plus lentes car Snowflake devra tout relire depuis le storage distant.

C'est un vrai compromis :

Auto-suspend court (60s)
  ✅ Tu économises des crédits
  ❌ Tu perds le cache souvent → requêtes plus lentes après chaque redémarrage

Auto-suspend long (600s+)
  ✅ Tu gardes le cache chaud → requêtes rapides
  ❌ Tu paies du compute "idle" pendant que personne ne requête

C'est pour ça que l'auto-suspend optimal n'est pas le même partout. Un warehouse ETL batch qui tourne une fois par nuit peut être suspendu très vite (60-120s). Un warehouse BI avec des analystes qui enchaînent les requêtes toute la journée mérite un auto-suspend plus long (300-600s) pour profiter du cache.

Bien organiser ses warehouses

C'est un point qu'on a déjà abordé dans l'article FinOps comme levier d'optimisation des coûts. Mais au-delà du FinOps, l'isolation des traitements est aussi une question de performance.

Par exemple, si ton pipeline ETL du matin et les dashboards Qlik sense tournent sur le même warehouse, les deux se partagent les mêmes ressources. Quand l'ETL lance un gros traitement sur les 500 millions de lignes, il monopolise le compute et donc les dashboards risquent de ramer.

La règle simple :

Un type d'usage = un warehouse dédié.
-- ETL batch (lourd, nuit/matin, on suspend vite après)
CREATE WAREHOUSE wh_etl
  WAREHOUSE_SIZE = 'LARGE'
  AUTO_SUSPEND = 120
  AUTO_RESUME = TRUE;

-- BI / dashboards (utilisateurs concurrents, on garde le cache)
CREATE WAREHOUSE wh_bi
  WAREHOUSE_SIZE = 'MEDIUM'
  AUTO_SUSPEND = 600
  AUTO_RESUME = TRUE;

-- Dev / demo (petit, on suspend vite)
CREATE WAREHOUSE wh_dev
  WAREHOUSE_SIZE = 'X-SMALL'
  AUTO_SUSPEND = 60
  AUTO_RESUME = TRUE;

Chaque warehouse a sa taille, son auto-suspend, et surtout ses crédits isolés. Pour contrôler les coûts de chacun, tu assignes un resource monitor par warehouse.

Scale up vs scale out

Pour gérer la montée en charge, Snowflake te donne deux leviers bien distincts :

Scale up : tu augmentes la taille du warehouse (de Medium à Large, par exemple). Ça donne plus de puissance par requête. Utile quand les requêtes sont lourdes mais pas forcément nombreuses.

Scale out : tu multiplies le nombre de clusters derrière le même warehouse. Ça donne plus de capacité pour absorber beaucoup de requêtes en parallèle. Utile quand tu as beaucoup d'utilisateurs simultanés.

Situation Levier Exemple
Requêtes lourdes (gros scans, jointures lourdes) Scale up Passer de Medium à X-Large
Beaucoup d'utilisateurs simultanés (Dashboards) Scale out Activer le multi-cluster (1 → 5 clusters)
Requêtes lourdes ET beaucoup d'utilisateurs Les deux X-Large en multi-cluster

C'est sur le scale out qu'on va maintenant zoomer, parce que c'est là que le multi-cluster entre en jeu.

Multi-Cluster Warehouses (scale out)

Un multi-cluster warehouse, c'est un warehouse qui peut automatiquement lancer plusieurs copies identiques de lui-même quand la demande augmente, puis les fermer quand la pression retombe.

Côté utilisateur, tout le monde voit un seul warehouse avec un seul nom. Mais derrière, Snowflake peut ouvrir 2, 3, 5 ou 10 clusters identiques et répartir les requêtes entre eux.

CREATE WAREHOUSE wh_bi_multicluster
  WAREHOUSE_SIZE = 'MEDIUM'
  MIN_CLUSTER_COUNT = 1
  MAX_CLUSTER_COUNT = 5
  SCALING_POLICY = 'STANDARD'
  AUTO_SUSPEND = 300
  AUTO_RESUME = TRUE;

Les paramètres clés

MIN_CLUSTER_COUNT : le nombre minimum de clusters toujours actifs. Si tu mets 1, Snowflake démarre avec un seul cluster et en ajoute d'autres seulement quand c'est nécessaire. Si tu mets 2, tu auras toujours au minimum 2 clusters qui tournent (et qui consomment des crédits).

MAX_CLUSTER_COUNT : le plafond. Snowflake ne dépassera jamais ce nombre de clusters, même si la demande est forte. C'est la protection contre l'explosion de la facture.

⚠️
Nb : Chaque cluster supplémentaire consomme le même nombre de crédits que le premier. Un warehouse Medium en 3 clusters = 3 × 4 = 12 crédits/heure.

Scaling policies : Standard vs Economy

La scaling policy détermine quand Snowflake ajoute ou retire des clusters :

STANDARD (par défaut) :

  • Snowflake ajoute un cluster dès qu'une requête est mise en file d'attente (queued) ou qu'il détecte beaucoup de charge.
  • Il retire un cluster après 2 à 3 checks consécutifs de sous-utilisation (toutes les 20 à 30 secondes).
  • Priorité : c'est la performance avant tout.

ECONOMY :

  • Snowflake attend plus longtemps avant d'ajouter un cluster. Il ne le fait que si la charge justifie que le nouveau cluster soit occupé au moins 6 minutes.
  • Il retire un cluster plus agressivement quand la charge baisse.
  • Priorité : l'économie avant tout. ( il faut accepter un peu de queuing pour payer moins)
Scaling policy Quand ça scale Quand ça descale Priorité
STANDARD Dès qu'une requête est en attente Après 2-3 checks de sous-utilisation Performance
ECONOMY Quand le cluster sera utilisé ≥ 6 min Dès que le cluster est sous-utilisé Coûts

Faire le choix entre l'un et l'autre est à gerer cas par cas

-- Warehouse BI avec beaucoup d'utilisateurs ==> Standard
-- Les dashboards doivent répondre vite et pas de queuing
ALTER WAREHOUSE wh_bi SET SCALING_POLICY = 'STANDARD';

-- Warehouse de requêtes ponctuelle => Economy
-- On accepte d'attendre un peu pour payer moins
ALTER WAREHOUSE wh_adhoc SET SCALING_POLICY = 'ECONOMY';

Mode Maximized vs mode Auto-scale

Si tu configures MIN_CLUSTER_COUNT = MAX_CLUSTER_COUNT (par exemple, les deux à 3), Snowflake lance les 3 clusters en permanence. C'est le mode Maximized. Utile quand tu sais à l'avance que la charge sera constante et élevée.

Sinon, si tu configures MIN_CLUSTER_COUNT < MAX_CLUSTER_COUNT, alors Snowflake va gérer le scaling automatiquement en mode Auto-scale.

-- Mode Auto-scale (recommandé dans la plupart des cas)
ALTER WAREHOUSE wh_bi SET
  MIN_CLUSTER_COUNT = 1,
  MAX_CLUSTER_COUNT = 4;

-- Mode Maximized (charge constante et prévisible)
ALTER WAREHOUSE wh_batch SET
  MIN_CLUSTER_COUNT = 3,
  MAX_CLUSTER_COUNT = 3;
💡
Nb : le multi-cluster warehouse est disponible uniquement à partir de l'édition Enterprise et au-dessus.

Concurrence et queuing

Quand un warehouse reçoit plus de requêtes qu'il ne peut en traiter simultanément, les requêtes supplémentaires sont mises en file d'attente (queue).

Il n'y a pas de nombre fixe magique de requêtes simultanées car ça dépend de la taille du warehouse et des ressources consommées par chaque requête. Mais Snowflake utilise un paramètre appelé MAX_CONCURRENCY_LEVEL (par défaut à 8) pour définir le seuil à partir duquel les nouvelles requêtes sont mises en attente.

C'est précisément là que le multi-cluster prend tout son sens car au lieu de mettre les requêtes en queue, Snowflake lance un nouveau cluster pour absorber la charge.

Protéger les warehouses avec des timeouts

Deux paramètres très utiles pour éviter les requêtes qui partent en vrille :

STATEMENT_QUEUED_TIMEOUT_IN_SECONDS : combien de temps une requête peut rester en file d'attente avant d'être annulée. Par défaut : 0 (pas de limite). C'est risqué, parce qu'une requête peut attendre indéfiniment si le warehouse est surchargé.

STATEMENT_TIMEOUT_IN_SECONDS : combien de temps une requête peut tourner au total. Par défaut : 172 800 secondes (48 heures). Un SELECT * sans WHERE sur une table de 2 milliards de lignes peut facilement tourner pendant des heures si personne ne le coupe.

-- Timeout en queue : 5 minutes max
-- Timeout d'exécution : 30 minutes max
ALTER WAREHOUSE wh_bi SET
  STATEMENT_QUEUED_TIMEOUT_IN_SECONDS = 300,
  STATEMENT_TIMEOUT_IN_SECONDS = 1800;

Ces timeouts sont complémentaires aux resource monitors (qui eux surveillent les crédits globaux). Ici on protège le warehouse contre les requêtes qui peuvent déraper et faire exploser la facture.

Notions à retenir

Concept Ce qu'il faut retenir
Virtual warehouse Cluster de serveurs pour le compute. Ne stocke rien. Consomme des crédits quand il tourne.
Sizing (XS → 6XL) Chaque taille au-dessus = 2× la puissance et 2× les crédits. Vérifier avec le Query Profile avant de monter.
Auto-suspend Suspend après X secondes d'inactivité. Court = économies mais perte du cache. Long = cache chaud mais crédits idle.
Scale up Augmenter la taille pour des requêtes lourdes.
Scale out (multi-cluster) Multiplier les clusters pour absorber beaucoup d'utilisateurs. Enterprise+ uniquement.
Scaling policy Standard = performance avant tout. Economy = coûts avant tout.
Maximized vs Auto-scale MIN = MAX → Maximized. MIN < MAX → Auto-scale.
Concurrence MAX_CONCURRENCY_LEVEL (défaut 8). Au-delà, les requêtes sont mises en queue ou le multi-cluster scale.
Timeouts STATEMENT_QUEUED_TIMEOUT et STATEMENT_TIMEOUT pour couper les requêtes qui déraillent.

Pour aller plus loin sur les coûts liés aux warehouses (resource monitors, budgets, tags, détection d'anomalies, coût idle), tout est dans l'article FinOps Snowflake.

Aller plus loin : Formation Snowflake

J'ai regroupé tous mes articles Snowflake dans un parcours complet.

👉 Explorer le parcours Snowflake

Vous voulez que je vous accompagne sur votre projet data (Snowflake, ingestion, modélisation, performance, coûts, gouvernance) ?

👉 Réserver un appel de 30 minutes