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 actifs (dont 8 dans l'équipe data core)
- Data team : 2 Data Engineers, 4 Analysts, 2 Data Scientists — le reste : Product, Finance, Marketing avec accès Looker
- 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.
À noter sur BI Engine : Ces 7 200€ correspondent à une réservation de 100 Go de mémoire BI Engine (~$0.0416/Go/heure × 730h × 100 Go). BI Engine accélère les requêtes Looker en gardant les données en mémoire. Le problème : beaucoup d'équipes activent BI Engine "pour la performance" sans vérifier si leurs dashboards en bénéficient vraiment. Dans ce cas, seuls 3 dashboards sur 25 utilisaient effectivement le cache BI Engine.
Analyse du compute (35k€)
Qui consomme ?
-- Top 10 des consommateurs (30 derniers jours)
-- Prix EUR : $6.25/TiB × 0.92 EUR/USD ≈ €5.75/TiB
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 BigQuery Editions (Standard ou Enterprise). 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, tu peux me suivre sur LinkedIn ou t'inscrire à la newsletter pour recevoir les prochains articles.