Patterns Architecturaux Cost-Aware

La majorité des coûts data se décide au moment du design, pas après. Un pipeline full-refresh sur une table de 500 GB coûtera 10 à 100x plus cher qu'un pipeline incrémental bien conçu.

Une architecture medallion mal calibrée peut doubler le storage sans bénéfice réel. Les patterns décrits ici sont ceux que j'applique systématiquement sur les missions d'optimisation. Ils ont un impact structurel et durable sur la facture.

Principe fondamental : Process Once, Query Many

C'est la règle numéro un de l'architecture cost-aware. Chaque donnée ne devrait être transformée qu'une seule fois, puis stockée dans un format optimisé pour la lecture. Toutes les requêtes analytiques consomment ensuite cette donnée pré-traitée.

-- ANTI-PATTERN : Chaque analyst refait le même calcul
-- Analyst A (coûte 2 GB à chaque exécution)
SELECT customer_id, SUM(amount) as total
FROM raw_transactions
WHERE date >= '2025-01-01'
GROUP BY customer_id;

-- Analyst B (refait le même scan, 2 GB de plus)
SELECT customer_id, SUM(amount) as total
FROM raw_transactions
WHERE date >= '2025-01-01'
GROUP BY customer_id;

-- PATTERN : Matérialiser une fois, lire N fois
-- Pipeline (exécuté 1x/jour, coûte 2 GB)
CREATE OR REPLACE TABLE gold.customer_totals AS
SELECT customer_id, SUM(amount) as total, MAX(date) as last_date
FROM raw_transactions
GROUP BY customer_id;

-- Analyst A (coûte 0.01 GB - table pré-agrégée)
SELECT * FROM gold.customer_totals WHERE total > 1000;

-- Analyst B (coûte 0.01 GB - même table)
SELECT * FROM gold.customer_totals;

Succes

Impact réel : sur un cas client avec 15 analysts qui interrogeaient les mêmes tables raw, la matérialisation d'une couche gold a réduit les coûts de requêtes analytiques de 85%. L'investissement en compute d'écriture est amorti dès le deuxième jour.

Décision concrète

Identifiez vos 5 requêtes ad-hoc les plus exécutées (via INFORMATION_SCHEMA). Si elles scannent les mêmes tables avec les mêmes filtres, créez une table matérialisée. Critère : si une requête est exécutée plus de 3 fois par jour par différentes personnes, matérialisez.

Medallion Architecture et coûts

L'architecture medallion (Bronze → Silver → Gold) est le standard de facto pour les plateformes data modernes. Mais chaque couche a un profil de coût différent, et mal calibrer les couches revient à payer pour du storage et du compute inutiles.

┌──────────────────────────────────────────────────────────────┐
│                   MEDALLION ARCHITECTURE                      │
│                  Profil de coût par couche                    │
├──────────────────────────────────────────────────────────────┤
│                                                               │
│  BRONZE (Raw)          SILVER (Clean)        GOLD (Business) │
│  ─────────────         ──────────────        ─────────────── │
│  Storage: $$$          Storage: $$           Storage: $       │
│  Write: $              Write: $$             Write: $$$       │
│  Read: $$$             Read: $$              Read: $          │
│                                                               │
│  • Append-only         • Dédupliqué          • Pré-agrégé    │
│  • Partitionné         • Typé et validé      • Matérialisé   │
│  • Pas d'index         • Clusteré            • Cache-friendly│
│  • TTL agressif        • Incrémental         • Requêtes fast │
│                                                               │
└──────────────────────────────────────────────────────────────┘

Optimiser chaque couche

CoucheLevier principalAction concrète
BronzeRéduire le storageTTL 90 jours, compression, partitionnement par date
SilverRéduire le compute d'écritureIncremental processing, merge au lieu de full-refresh
GoldRéduire le compute de lecturePré-agrégation, clustering aligné sur les filtres

Erreur fréquente

Garder les données Bronze indéfiniment « au cas où ». En réalité, une fois les données nettoyées en Silver, le Bronze ne sert que pour le replay. Un TTL de 30-90 jours sur le Bronze peut réduire le storage de 40-60%.

À retenir

Le vrai coût du Bronze n'est pas le storage, c'est le scan. Chaque requête sur Bronze scanne des données non optimisées. Investissez dans votre couche Silver : c'est elle qui doit être bien partitionnée, clusterisée et accessible.

Incremental-first : le pattern le plus impactant

Le full-refresh est le pattern par défaut dans la plupart des projets dbt. C'est aussi le plus coûteux. Chaque exécution rescanne et réécrit l'intégralité de la table, même si seulement 0.1% des données ont changé.

-- dbt : full-refresh (défaut)
-- Rescanne et réécrit 100% de la table à chaque run
{{ config(materialized='table') }}
SELECT * FROM {{ ref('stg_events') }}

-- dbt : incremental
-- Ne traite que les nouvelles données depuis le dernier run
{{ config(
    materialized='incremental',
    incremental_strategy='merge',
    unique_key='event_id',
    partition_by={
      "field": "event_date",
      "data_type": "date",
      "granularity": "day"
    }
) }}

SELECT *
FROM {{ ref('stg_events') }}
{% if is_incremental() %}
WHERE event_date > (SELECT MAX(event_date) FROM {{ this }})
{% endif %}
MétriqueFull-refreshIncremental
Données scannées/run500 GB1-5 GB
Coût par run (on-demand)~$2.50~$0.025
Coût mensuel (1 run/jour)~$75~$0.75
Durée d'exécution10-30 min30s-2 min

À retenir

Sur une table de 500 GB avec un run quotidien, le passage de full-refresh à incrémental économise ~$900/an par modèle. Multipliez par le nombre de modèles dbt dans votre projet.

Erreur fréquente

Convertir en incrémental sans tester les edge cases. Que se passe-t-il si des données arrivent en retard ? Si une ligne est modifiée après coup ? Documentez la stratégie de late-arriving data AVANT de migrer.

Tiering du compute

Tous les workloads n'ont pas les mêmes exigences de performance. Aligner le niveau de compute sur le besoin réel est un levier majeur, en particulier sur Snowflake.

TIERING COMPUTE
│
├── TIER 1 : Interactive ($$$)
│   ├── Analyses ad-hoc des analysts
│   ├── Dashboards temps réel
│   └── Warehouse XS-S, auto-suspend 60s
│
├── TIER 2 : Scheduled ($$)
│   ├── Pipelines ETL/ELT (dbt, Airflow)
│   ├── Rapports planifiés
│   └── Warehouse S-M, auto-suspend 120s
│
└── TIER 3 : Batch ($)
    ├── Backfills, reprocessing
    ├── ML training, exports massifs
    └── Warehouse M-L, schedule nocturne, auto-suspend 300s

Note

Principe Snowflake : un warehouse dédié par tier avec des politiques d'auto-suspend différentes. Sur BigQuery en mode Editions, utilisez des réservations différentes par priorité de workload.

Anti-patterns coûteux

Ces patterns sont fréquents et coûtent cher. Je les retrouve dans quasiment chaque audit.

Anti-patternImpactSolution
Full-refresh par défaut10-100x le coût nécessaireIncrémental par défaut, full-refresh en exception
Warehouse toujours alluméPaiement 24/7 pour usage 8hAuto-suspend agressif (60-120s)
Pas de partitionnementFull-scan à chaque requêtePartition par date + require filter
Duplication Bronze inutile2-3x le storage nécessaireTTL sur Bronze, dedup en Silver
SELECT * dans les viewsColonnes inutiles scannéesProjection explicite, colonnes nommées

Framework de décision

Avant chaque décision architecturale, posez ces trois questions :

  1. Quel est le coût récurrent de cette décision ? Un pipeline qui tourne chaque heure a un coût cumulatif bien plus élevé qu'un pipeline quotidien. Calculez le coût annuel, pas le coût unitaire.
  2. Qui va consommer cette donnée, et comment ? Si 20 personnes vont interroger cette table en ad-hoc, la matérialiser coûte moins cher que de laisser chacun scanner le raw. Si une seule personne l'utilise une fois par mois, une view suffit.
  3. Quel est le volume dans 6 mois ? Un full-refresh acceptable sur 10 GB devient problématique sur 500 GB. Anticipez la croissance des données dans vos choix d'architecture.

Succes

Règle d'or : investir en compute à l'écriture pour économiser à la lecture. C'est le principe « Process Once, Query Many » appliqué à chaque couche de l'architecture.
Jonathan Kini

Jonathan Kini

J'aide les équipes data à réduire et maîtriser leurs coûts BigQuery et Snowflake, sans sacrifier la performance. 8 ans de terrain, de la startup aux environnements data à grande échelle.