Retour au blog
BigQuery

Anatomie d'une facture BigQuery à 50k€/mois

Décomposition détaillée d'une facture BigQuery typique d'une scale-up. Où part l'argent, qui consomme quoi, et où se cachent les optimisations.

15 janvier 202515 min de lecture

Anatomie d'une facture BigQuery à 50k€/mois

Je vois régulièrement des factures BigQuery de scale-ups en croissance. Le pattern est souvent le même : une facture qui a explosé sans que personne ne comprenne vraiment pourquoi.

Dans 90% des cas que j'audite, la facture a triplé en moins d'un an — et l'équipe data découvre le problème quand le CFO débarque avec des questions.

Dans cet article, je décompose une facture typique de 50k€/mois pour montrer où part l'argent — et où se cachent les optimisations.


Le profil type

Imaginons une scale-up e-commerce classique :

  • Taille : 200 employés, 50 utilisateurs BigQuery
  • Data team : 8 personnes (2 Data Engineers, 4 Analysts, 2 Data Scientists)
  • Volume : 2 TB de nouvelles données par jour
  • Stack : BigQuery + dbt + Looker
  • Historique : 3 ans de données, ~500 TB total

La facture mensuelle vient de passer de 15k€ à 50k€ en 8 mois. Personne ne sait exactement pourquoi.

J'ai vu chez un client cette exact situation : le Data Lead était persuadé que c'était le volume de données qui avait explosé. En réalité, 60% de l'augmentation venait d'un seul dashboard Looker mal configuré, rafraîchi toutes les 15 minutes par 30 utilisateurs.


Décomposition de la facture

Vue d'ensemble

TOTAL MENSUEL : 52 340€

├── BigQuery Analysis (Queries)    35 200€   67%
│   ├── On-demand queries          28 000€
│   └── BI Engine                   7 200€
│
├── BigQuery Storage               8 500€    16%
│   ├── Active storage             6 200€
│   └── Long-term storage          2 300€
│
├── Dataflow                       4 800€     9%
│
├── Cloud Storage (GCS)            2 400€     5%
│
└── Autres (Pub/Sub, etc.)         1 440€     3%

Premier constat : 67% des coûts viennent des requêtes. C'est là qu'il faut creuser.


Analyse du compute (35k€)

Qui consomme ?

-- Top 10 des consommateurs (30 derniers jours)
SELECT
  user_email,
  COUNT(*) as query_count,
  SUM(total_bytes_billed) / POW(1024, 4) AS tb_scanned,
  ROUND(SUM(total_bytes_billed) / POW(1024, 4) * 5.75, 2) AS cost_eur
FROM `region-eu`.INFORMATION_SCHEMA.JOBS
WHERE creation_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY)
  AND job_type = 'QUERY'
GROUP BY user_email
ORDER BY cost_eur DESC
LIMIT 10;

Résultat typique :

UtilisateurRequêtesTB scannésCoût
scheduler@projet.iam45 0002 10012 075€
looker@projet.iam128 0001 4508 337€
analyst-marie@3 2008905 117€
analyst-paul@2 8006203 565€
dbt-prod@1 2004802 760€

Insights :

  • Le scheduler (Airflow/dbt) représente 35% des coûts → pipelines à auditer
  • Looker fait 128k requêtes → beaucoup de cache miss, dashboards mal optimisés
  • 2 analysts consomment autant que le reste de l'équipe → requêtes exploratoires non optimisées

Quelles requêtes coûtent le plus ?

-- Top 20 requêtes les plus chères
SELECT
  job_id,
  user_email,
  ROUND(total_bytes_billed / POW(1024, 4) * 5.75, 2) AS cost_eur,
  ROUND(total_bytes_billed / POW(1024, 3), 1) AS gb_scanned,
  SUBSTR(query, 1, 200) AS query_preview
FROM `region-eu`.INFORMATION_SCHEMA.JOBS
WHERE creation_time > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
  AND job_type = 'QUERY'
ORDER BY total_bytes_billed DESC
LIMIT 20;

Patterns récurrents :

  1. SELECT * sur tables non partitionnées — Une requête, 2 TB scannés, 12€
  2. Dashboards sans filtre date — Chaque refresh scanne tout l'historique
  3. JOINs mal ordonnés — Explosion combinatoire
  4. Requêtes récurrentes identiques — Même requête 50x/jour sans cache

Opinion tranchée : Je déconseille fortement le mode on-demand au-delà de 10k€/mois de consommation. À ce stade, passez aux slots réservés ou flex slots. Le on-demand, c'est confortable mais c'est un chèque en blanc — et j'ai vu trop d'équipes se faire surprendre par une facture x3 après un incident de pipeline ou un stagiaire un peu trop curieux.


Analyse du storage (8.5k€)

Répartition active vs long-term

Problèmes typiques :

DatasetActiveLong-termProblème
raw_events180 TB20 TBPas de lifecycle
staging45 TB0 TBTables temporaires jamais supprimées
snapshots80 TB10 TBSnapshots gardés indéfiniment

Le ratio Active/Long-term devrait être ~30/70, ici c'est l'inverse.

La dernière fois que j'ai vu ce pattern, le client payait 3 000€/mois pour des tables de staging créées par un ancien employé parti depuis 18 mois. Personne n'osait les supprimer "au cas où".


Les 6 quick wins

1. Activer require_partition_filter (économie : ~8k€/mois)

ALTER TABLE `project.dataset.events`
SET OPTIONS (require_partition_filter = TRUE);

Ce que les gens comprennent mal : beaucoup pensent que le partitioning suffit. Non. Sans require_partition_filter, vos utilisateurs peuvent toujours scanner la table entière — ils le feront par paresse ou par erreur. Forcez la contrainte, sinon elle n'existe pas.

2. Réparer les dashboards Looker (économie : ~4k€/mois)

  • Filtres date obligatoires
  • Materialized Views pour agrégations communes
  • BI Engine sur tables fréquentes

3. Optimiser les pipelines dbt (économie : ~3k€/mois)

# dbt_project.yml
models:
  +partition_by:
    field: event_date
    data_type: date
  +cluster_by: ["country", "event_type"]

4. Nettoyer le staging (économie : ~1.5k€/mois)

ALTER TABLE `project.staging.temp_table`
SET OPTIONS (expiration_timestamp = TIMESTAMP_ADD(CURRENT_TIMESTAMP(), INTERVAL 7 DAY));

5. Lifecycle policy sur raw_events (économie : ~2k€/mois)

ALTER TABLE `project.raw.events`
SET OPTIONS (partition_expiration_days = 730);

6. Former les équipes (économie : ~3k€/mois)

  • Pas de SELECT *
  • Toujours filtrer sur la partition
  • Dry run avant exécution

Plan d'action

SemaineActionÉconomie estimée
1Partition filters8 000€
2Top 5 dashboards4 000€
3Pipelines dbt3 000€
4Cleanup + lifecycle3 500€
5Formation équipe3 000€

Total : ~21 500€/mois = 41% de réduction


Conclusion

Une facture BigQuery à 50k€, c'est rarement une fatalité. 30-50% peuvent être économisés avec :

  1. Forcer les bonnes pratiques (partition filters)
  2. Optimiser les gros consommateurs (dashboards, pipelines)
  3. Nettoyer le storage (lifecycle, tables zombies)
  4. Former les équipes (culture cost-aware)

Le plus dur n'est pas technique — c'est de maintenir ces pratiques dans le temps. J'ai vu des équipes faire le ménage une fois, économiser 40%, puis retomber au même niveau 6 mois plus tard parce que personne ne surveillait.

Si ce type de contenu t'aide, je partage régulièrement des analyses et des retours d'expérience sur l'optimisation des coûts data. Tu peux me suivre sur LinkedIn ou t'inscrire à ma newsletter pour ne rien rater.

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.