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 :
| Utilisateur | Requêtes | TB scannés | Coût |
|---|---|---|---|
| scheduler@projet.iam | 45 000 | 2 100 | 12 075€ |
| looker@projet.iam | 128 000 | 1 450 | 8 337€ |
| analyst-marie@ | 3 200 | 890 | 5 117€ |
| analyst-paul@ | 2 800 | 620 | 3 565€ |
| dbt-prod@ | 1 200 | 480 | 2 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 :
- SELECT * sur tables non partitionnées — Une requête, 2 TB scannés, 12€
- Dashboards sans filtre date — Chaque refresh scanne tout l'historique
- JOINs mal ordonnés — Explosion combinatoire
- 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 :
| Dataset | Active | Long-term | Problème |
|---|---|---|---|
| raw_events | 180 TB | 20 TB | Pas de lifecycle |
| staging | 45 TB | 0 TB | Tables temporaires jamais supprimées |
| snapshots | 80 TB | 10 TB | Snapshots 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
| Semaine | Action | Économie estimée |
|---|---|---|
| 1 | Partition filters | 8 000€ |
| 2 | Top 5 dashboards | 4 000€ |
| 3 | Pipelines dbt | 3 000€ |
| 4 | Cleanup + lifecycle | 3 500€ |
| 5 | Formation équipe | 3 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 :
- Forcer les bonnes pratiques (partition filters)
- Optimiser les gros consommateurs (dashboards, pipelines)
- Nettoyer le storage (lifecycle, tables zombies)
- 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.