← Learning Hub Lesson 10 Duration: ~14 min Topic: Production Operations

Cost, Performance & Operations

This final lesson covers the operational realities: controlling cloud spend, optimising Delta table performance, sizing clusters efficiently, and establishing runbooks for your production weather-to-power platform. As Tech Lead, cost accountability and operational health are your responsibility.

Cost Model — Where the Money Goes

Databricks cost has two components: compute (DBUs) and cloud infrastructure (VMs + storage).[1]

ComponentCost DriverYour Pipeline
Job clusters (DBUs) VM size × hours × DBU rate ~0.5–2h compute/day across 4 runs. Primary cost centre.
SQL Warehouse Warehouse size × active hours Analyst queries + downstream reads. Serverless auto-scales to zero.
Storage GB stored (cloud blob pricing) Delta tables + checkpoints. Grows with retention policy.
Networking Egress (data leaving region) Small unless serving cross-region consumers.

Estimated monthly cost (illustrative)

WorkloadConfigDaily Runtime~Monthly Cost
Ingestion (4× daily) Single-node E4s (0.5 DBU/h) 4 × 10 min = 40 min ~$50–80
Silver transforms (4×) 2-worker D4s (1.5 DBU/h) 4 × 8 min = 32 min ~$60–100
Feature + ML inference (4×) 1-worker E8s (2 DBU/h) 4 × 5 min = 20 min ~$40–70
SQL Warehouse (analysts) Serverless, Small ~2h active queries/day ~$100–200
Storage (Delta tables) ~500 GB growing — ~$10–25
Total estimate ~$260–475/month

These are rough estimates for a moderate-scale fleet (~50 turbines, 10 parks, Europe region). Actual costs depend on cloud provider, DBU tier (Premium vs. Standard), and data volumes.

Cost Levers (Highest Impact First)
  1. Cluster sizing: Don't over-provision. Single-node for I/O tasks, minimum workers for transforms.
  2. Job clusters (not all-purpose): Job clusters terminate after the job. All-purpose clusters bill 24/7.
  3. Spot instances: Use for fault-tolerant worker nodes (transforms, features). 60–80% savings.
  4. Serverless SQL: Scales to zero when not queried. No idle cost for analyst workloads.
  5. Data retention: VACUUM old Bronze data. Drop partitions beyond retention window.

Delta Table Optimisation

Delta tables accumulate small files over time (from frequent appends). Unchecked, this degrades read performance.

OPTIMIZE — compact small files

-- Run weekly (or let auto-optimize handle it)
OPTIMIZE prod.silver.weather_ts;
OPTIMIZE prod.silver.power_ts;
OPTIMIZE prod.gold.forecast_ts;

-- With Z-ORDER for time-range query performance
OPTIMIZE prod.silver.weather_ts ZORDER BY (timestamp);
OPTIMIZE prod.silver.power_ts ZORDER BY (timestamp);

VACUUM — delete old file versions

-- Remove files older than retention period (default 7 days)
-- After VACUUM, time travel to those versions is no longer possible
VACUUM prod.bronze.weather_raw RETAIN 30 DAYS;
VACUUM prod.silver.weather_ts RETAIN 14 DAYS;
VACUUM prod.gold.forecast_ts RETAIN 7 DAYS;

Auto-optimize (preferred for production)

-- Enable at table creation (already in our schemas):
TBLPROPERTIES (
  'delta.autoOptimize.optimizeWrite' = 'true',  -- write larger files
  'delta.autoOptimize.autoCompact'   = 'true'   -- compact small files
);

-- These reduce the need for manual OPTIMIZE, but Z-ORDER still needs 
-- periodic explicit OPTIMIZE runs (auto-compact doesn't Z-ORDER).
Maintenance TaskFrequencyMethod
OPTIMIZE + ZORDERWeeklyScheduled maintenance job
VACUUMWeeklySame maintenance job
ANALYZE TABLE (stats)After large loadsImproves query planning
Drop old Bronze partitionsMonthlyRetention policy enforcement

Cluster Sizing Guide

TaskBottleneckRight Size
GRIB download + parse Network I/O, single-thread Python (cfgrib) Single-node, memory-optimised (16GB+ RAM)
Bronze → Silver (geo-join) Spark shuffle for join (broadcast eliminates this) 2–4 workers, general purpose. Broadcast dim_assets.
Feature computation Window functions (partition by asset) 2–4 workers. Data is partitioned by asset_id = natural parallelism.
ML inference Model predict (CPU-bound, pandas UDF) 1–2 workers, ML runtime. Or single-node if model is light (LightGBM).
Gold write + aggregate Minimal — small output volume Shared with transform cluster (reuse).
Right-Sizing Principle

Start small, measure, scale up only when tasks are too slow. A single-node cluster for ingestion and 2-worker cluster for transforms is likely sufficient for a fleet of 50–200 turbines. The cluster auto-terminates after the job — over-provisioning costs you per minute, not per month.

Data Retention Policy

-- Bronze: keep raw weather for reprocessing (30–90 days)
-- After that, Silver is the source of truth
ALTER TABLE prod.bronze.weather_raw
SET TBLPROPERTIES ('delta.deletedFileRetentionDuration' = '30 days');

-- Silver: keep indefinitely (primary analytical asset)
-- VACUUM removes only file versions, not logical data

-- Gold: keep forecast history for accuracy tracking (1–2 years)
-- Older forecasts can be archived to cold storage if needed
LayerRetentionRationale
Bronze30–90 daysReprocessing window. Beyond this, Silver is truth.
SilverIndefinite (2+ years)Core analytical asset. ML training needs history.
Gold1–2 yearsForecast accuracy tracking. Regulatory if applicable.
FeaturesSame as SilverTraining requires feature history aligned with labels.

Operational Runbook

Incident: Pipeline failure (ingestion)

  1. Check: Which source failed? (Workflow run UI → failed task)
  2. Diagnose: API timeout? Auth failure? Source downtime? (Check logs)
  3. Act: If transient → manual retry. If source down → wait, verify freshness SLA.
  4. Communicate: If SLA breached → notify downstream (trading desk uses stale forecast).

Incident: Model accuracy degradation

  1. Detect: forecast_accuracy table shows MAE rising over 7 days.
  2. Diagnose: Seasonal shift? Asset change (new turbine)? Weather model update upstream?
  3. Act: Retrain model on recent data. Validate challenger. Promote if improved.
  4. Prevent: Schedule automated retraining (monthly or on drift detection).

Incident: Slow pipeline (duration alert)

  1. Check: Which task is slow? (Workflow timeline view)
  2. Diagnose: Data volume spike? Cluster undersized? Small files (needs OPTIMIZE)?
  3. Act: Run OPTIMIZE if small-file issue. Scale cluster if data grew. Add partition pruning if missing.

Monitoring Dashboard

Key metrics to track on an operational dashboard (Databricks SQL Dashboard or external):

MetricSourceAlert Threshold
Pipeline success rateWorkflow run history< 95% over 7 days
Pipeline durationWorkflow run history> 2× median
Gold freshnessMAX(produced_at) in forecast_ts> 2 hours stale
Forecast MAE (7-day rolling)forecast_accuracy table> 20% above baseline
Park coverageDISTINCT parks in latest Gold batch< 100% expected parks
Daily DBU spendDatabricks billing API / account console> 2× daily budget
Storage growth rateDESCRIBE DETAIL on tables> 10% week-over-week unexpected growth

Check Your Understanding

Your Silver weather_ts table has degraded query performance over the past month. The table receives 4 appends daily. Most likely cause?

Correct. Each append creates new small files. Over a month, hundreds of small files accumulate. Spark must open and read each file header, degrading scan performance. OPTIMIZE compacts them into fewer, larger files. Auto-compact helps but periodic explicit OPTIMIZE + ZORDER is still needed.
Small file accumulation is the classic symptom. 4 appends/day × 30 days = 120+ small files per partition. Spark's file-listing overhead becomes significant. OPTIMIZE (compaction) + ZORDER (data skipping) restores performance.

You want to reduce compute cost for the ingestion tasks. Which change has the highest impact?

Right. cfgrib/xarray parse in the driver Python process — worker nodes sit completely idle during ingestion. Removing workers (single-node mode) eliminates wasted compute. An always-on cluster would be far more expensive (24/7 billing vs. minutes per run).
Single-node is the answer. cfgrib runs in the driver's Python process and can't distribute across workers. Paying for idle workers is pure waste. And never use always-on clusters for batch jobs — job clusters terminate after the run.

Bronze weather data is retained for 30 days. After 30 days, what happens if you need to reprocess older data?

Correct. After VACUUM removes old Bronze files, that raw data is gone from Databricks. Silver (which is retained indefinitely) becomes the source of truth. If you truly need to reprocess from scratch, re-download from the original weather API (ECMWF archives data for years). This is why Silver retention is longer.
After VACUUM, Bronze data beyond retention is gone. Silver is your durable source of truth (kept indefinitely). If you need the original raw data again, re-download from the weather provider's archive API. VACUUM does not archive — it permanently deletes.

Primary Source

📖 Recommended Reading

Delta Lake table optimization best practices — covers OPTIMIZE, VACUUM, Z-ORDER, auto-optimize, and file management. Also see Cluster configuration best practices for right-sizing guidance.

Course Summary

You've now covered the complete Databricks weather-to-power architecture:

  1. Lakehouse architecture — the mental model
  2. Asset hierarchy & time series — table design
  3. Weather ingestion — GRIB2, APIs, Bronze
  4. Bronze → Silver — geo-join, derivation, versioning
  5. Unity Catalog — governance and access control
  6. Feature engineering — Feature Store, point-in-time
  7. ML pipeline — MLflow, model registry, inference
  8. Gold layer — serving downstream, confidence intervals
  9. Workflows — orchestration, scheduling, alerting
  10. Cost & Operations — this lesson
Where to Go Next

You've completed the foundation course. Ask your teacher to dive deeper into any topic, create hands-on exercises, or explore advanced topics (streaming, real-time inference, multi-model ensembles).

Rechtliches: Impressum