Crosshire
← Databricks Audit
— Crosshire / Learn · Tech · Databricks · Audit

Jobs & Pipelines

The reliability, ownership, timeout hygiene and cost of Jobs and Lakeflow pipelines. Failures and wasted DBUs, all-purpose placement, missing timeouts, queueing, cold starts, retries and orphans.

21 queriesbuilt on system.*
War storyThe nightly job that paid the interactive rateA jobs bill up a third month-over-month, and nobody added a job.

System tables used

system.lakeflow.jobs

The catalog of Jobs (workflow definitions), one SCD2 change-history table.

  • Grain: one row per *version* of a job — i.e. one row per (workspace_id, job_id) per configuration change. You must dedupe to the latest row with QUALIFY ROW_NUMBER() OVER (PARTITION BY workspace_id, job_id ORDER BY change_time DESC) = 1 or job counts inflate.
  • Key columns used: workspace_id, job_id (unique only *within* a workspace), name, change_time (SCD2 ordering key), delete_time (non-NULL = user-deleted; filter IS NULL for active jobs), timeout_seconds (job-level timeout), paused, create_time, creator_user_name / run_as_user_name (identity), run_as, creator_id, health_rules (array/struct of configured health rules).
  • Availability: GA, Unity Catalog required. Needs SELECT on the system catalog (an admin must GRANT access to the system.lakeflow schema). Several columns are late-populated: creator_user_name, run_as_user_name, health_rules not populated before ~late-Nov-2025; timeout_seconds not before ~early-Dec-2025 — so on short-history accounts these are NULL for every job and must degrade to "not assessed," never read as a finding. FedRAMP/redacted workspaces emit __REDACTED__ for identities.

system.lakeflow.job_tasks

The per-task definition within each job, also SCD2.

  • Grain: one row per *version* of a task — (workspace_id, job_id, task_key) per change. task_key is unique only within a job. Dedupe to latest by change_time.
  • Key columns used: workspace_id, job_id, task_key, timeout_seconds (task-level timeout), change_time, delete_time.
  • Availability: GA, UC required, SELECT on system needed. timeout_seconds late-populated (~early-Dec-2025) → NULL degrades to "not assessed."

system.lakeflow.job_run_timeline

The run-level execution log — the reliability workhorse of this domain.

  • Grain: one row per run *state slice*. A run that exceeds one hour is sliced hourly, so COUNT(*)COUNT(DISTINCT run_id). The end row (final slice) is the only one carrying result_state, termination_code, and the final durations — every reliability query filters result_state IS NOT NULL to isolate it. Retries reuse the same run_id, appearing as extra end rows.
  • Key columns used: workspace_id, job_id, run_id, run_type (JOB_RUN / SUBMIT_RUN / WORKFLOW_RUN), trigger_type (incl. RETRY_ON_FAILURE), result_state (SUCCEEDED / FAILED / ERROR / TIMED_OUT / SKIPPED / CANCELLED / BLOCKED), termination_code (root-cause code, e.g. WORKSPACE_RUN_LIMIT_EXCEEDED, MAX_JOB_QUEUE_SIZE_EXCEEDED, CLUSTER_ERROR, STORAGE_ACCESS_ERROR), termination_type (coarser class — value enum unverified), period_start_time / period_end_time (equal when a run never began executing), and phase durations queue_duration_seconds, setup_duration_seconds, execution_duration_seconds, cleanup_duration_seconds, run_duration_seconds.
  • Availability: GA, UC required. termination_code not populated before ~Aug-2024; queue_duration_seconds, the phase *_duration_seconds, and termination_type not before ~late-Nov/early-Dec-2025. queue_duration_seconds exists only here, not on job_task_run_timeline. Empty if the account runs no jobs.

system.lakeflow.job_task_run_timeline

Task-level execution log, one grain finer than job_run_timeline.

  • Grain: one row per task *state slice* per run; hourly-sliced like the run timeline. End row (result_state IS NOT NULL) carries final task state and execution_duration_seconds. Joins up to the run via job_run_id = job_run_timeline.run_id (+ workspace_id).
  • Key columns used: workspace_id, job_id, run_id / job_run_id, task_key, result_state, execution_duration_seconds, compute_ids (array of cluster ids the task ran on), period_start_time / period_end_time.
  • Availability: GA, UC required. execution_duration_seconds late-populated (~late-Nov-2025). compute_ids may be empty on older rows; EXPLODE silently drops NULL/empty arrays (report as a separate "not assessed" bucket).

system.lakeflow.pipelines

The catalog of Lakeflow Declarative Pipelines (DLT), SCD2.

  • Grain: one row per version of a pipeline — (workspace_id, pipeline_id) per change. Dedupe to latest by change_time.
  • Key columns used: workspace_id, pipeline_id (unique only within a workspace), name, pipeline_type, created_by, run_as, change_time, delete_time, and settings (nested: serverless, development, continuous, photon, edition [CORE/PRO/ADVANCED — the *product* edition, not the billing tier], channel).
  • Availability: Public Preview — may be disabled or empty on the metastore; a missing table yields TABLE_OR_VIEW_NOT_FOUND. UC required. Whether settings is a STRUCT (settings.serverless) or MAP (settings['serverless']) is unverified — dot-access may error on some accounts.

system.lakeflow.pipeline_update_timeline

Execution log of pipeline updates (refreshes).

  • Grain: one row per update *state slice*, hourly-sliced; end row carries result_state. request_id groups retried/restarted updates.
  • Key columns used: workspace_id, pipeline_id, update_id, request_id, update_type (FULL_REFRESH / REFRESH / VALIDATE), trigger_type (incl. RETRY_ON_FAILURE), result_state (COMPLETED / FAILED / CANCELED — one L), period_start_time / period_end_time (active-second proxy).
  • Availability: Public Preview, UC required, may be empty. Degrade gracefully if disabled.

system.billing.usage

The metered-usage fact table — used here to attach dollars/DBUs to jobs and pipelines.

  • Grain: one row per entity per usage window per SKU per record_type. record_type (ORIGINAL / RETRACTION / RESTATEMENT) already nets out to a correct total when summed.
  • Key columns used: workspace_id, usage_date, usage_unit (filter = 'DBU' so bytes/hours/tokens never blend in), usage_quantity, sku_name, cloud, usage_end_time, and the usage_metadata struct: job_id (no run_id — DBUs attribute to the job, not the individual run), dlt_pipeline_id, dlt_update_id, dlt_maintenance_id (maintenance/housekeeping DBUs, summed separately).
  • Availability: GA, UC required, SELECT on system needed. All joins use (workspace_id, job_id) or (workspace_id, dlt_pipeline_id) because those ids are unique only within a workspace.

system.billing.list_prices

List (rack-rate) price reference for estimating dollars.

  • Grain: one row per (sku_name, cloud, usage_unit, currency_code) per price-effectivity window.
  • Key columns used: sku_name, cloud, currency_code, usage_unit, price_start_time, price_end_time (NULL = currently effective, open interval), and pricing.effective_list.default (the list rate — an estimate only, not the account's negotiated/discounted price).
  • Availability: GA, UC required. Joined open-interval on usage_end_time BETWEEN price_start_time AND price_end_time.

system.compute.clusters

Cluster inventory, used cross-domain to classify the compute a task ran on.

  • Grain: one row per version of a cluster — (workspace_id, cluster_id), SCD2; dedupe to latest by change_time.
  • Key columns used: workspace_id, cluster_id, cluster_source (UI / API = all-purpose, vs job-created), change_time.
  • Availability: GA, UC required. Cross-domain join to job_task_run_timeline.compute_ids; confirm compute_ids is populated on the target workspace.

Before you run these

  • Databricks system.* schemas aren’t uniformly available — several (e.g. system.query, system.lakeflow) are still in preview or must be enabled per-metastore. A query that returns nothing usually means its schema isn’t enabled for your account yet.
  • Every dollar figure is est · at list (pre-discount, DBU-only from system.billing.list_prices) unless a query explicitly joins account_prices.
  • Sample-output tables are illustrative synthetic rows, never real account data.

Queries in this domain

01Failing Jobs Ranked by Wasted DBUs lakeflow_failed_jobs_wasted_dbusOne row per job that had at least one failed run in the trailing window, with its distinct/failed run counts, the latest failure's termination code, total job DBUs, and a wasted-DBU proxy (job DBUs scaled by failed-run share).02Job Tasks On All-Purpose Compute lakeflow_jobs_on_all_purposePer-job, per-cluster task-run counts over the trailing 30 days, tagged with the cluster's source so you can spot job tasks running on all-purpose (UI/API) compute instead of cheaper job clusters.03Job Failure Breakdown by Root Causelakeflow_failed_runsA 30-day census of completed job runs bucketed by workspace, launch type, trigger, final outcome, and root-cause code, with raw-row, distinct-run, and failed-row counts for each bucket.04Job Health-Rule Coveragelakeflow_health_rule_coveragePer-workspace counts of active jobs that have a configured health rule versus none, with a separate bucket for jobs where the health_rules column has not been populated yet.05Orphaned And Handed-Off Jobslakeflow_job_ownership_orphansPer-workspace counts of active jobs whose creator or run-as identity is missing, whose creator and run-as differ (a handoff or service-principal pattern), or that look orphaned because no known identity runs them.06Jobs Stuck Waiting On Capacitylakeflow_job_queue_timePer-job queue-wait time (total seconds and approximate p95 per run) over the trailing window, with a separate counter of runs whose queue time is unknown, so admins can find jobs that sit waiting on capacity before they start.07Task-Level Timeout Coverage Gapslakeflow_job_tasks_no_timeoutPer-workspace counts of active job tasks and how many of them have no (or zero) task-level timeout configured, with a separate bucket for the "not yet populated" NULL case.08Jobs Missing a Timeoutlakeflow_jobs_no_timeoutPer-workspace counts of active jobs that have no (or zero) job-level timeout configured, alongside a separate "not yet populated" NULL bucket so the finding never over-claims.09Runs Killed Before They Launchedlakeflow_never_started_runsA per-job count of Databricks job runs that were terminated before they ever began executing, broken out by the termination reason, over the trailing 30 days.10Where Job Time Actually Goeslakeflow_phase_cold_startPer-job phase totals (setup, queue, execution, cleanup, and overall run) plus 95th-percentile setup and queue times over the trailing 30 days, so you can see how much wall-clock time is startup and wait overhead versus real work.11Per-Pipeline Cost and Over-Refreshlakeflow_pipeline_costOne row per Lakeflow (DLT) pipeline over the trailing window, showing its net DBUs billed, its maintenance DBUs broken out separately, a list-price dollar estimate, and how many times it refreshed and for how long.12Pipeline Active-Time and Idle-Tail Signallakeflow_pipeline_idle_tail_durationPer-Lakeflow-pipeline count of updates and total active run seconds over the last 30 days, tagged with each pipeline's type and its continuous/development settings so you can spot pipelines whose clusters likely linger idle between refreshes.13Pipeline Refresh Failures And Retrieslakeflow_pipeline_update_failures_retriesA 30-day breakdown of Lakeflow/DLT pipeline update outcomes, counting how many refreshes ran, how many failed, and how many were fired by retry-on-failure, sliced per workspace, pipeline, update type, trigger, and result state.14DLT Pipeline Fleet Inventorylakeflow_pipelines_inventory_tierA per-workspace census of your live Lakeflow Declarative (DLT) pipelines, counting how many run in each combination of pipeline type, serverless, development-mode, continuous, and product edition.15Flapping Jobs That Retrylakeflow_retries_repairsPer-job retry tallies over the trailing 30 days — how many runs each job had, how many extra attempts those runs racked up, and how many runs needed at least one retry.16Hunting Stale Zombie Jobslakeflow_stale_zombie_jobsEvery active (non-deleted) job definition with the timestamp its last run was last seen running and a flag marking those that haven't run in over 30 days (or ever).17Green Runs Hiding Failed Taskslakeflow_succeeded_with_failed_tasksPer job, how many runs reported overall SUCCEEDED yet actually contained at least one task that FAILED, ERROR'd, or TIMED_OUT over the trailing 30 days.18Tasks Running Near Timeoutlakeflow_tasks_near_timeoutPer-task run statistics over the lookback window flagging task runs that reached at least 80% of (or exceeded) their configured timeout, so you can tune the bound or fix the slowdown before it trips.19Job Failure Root-Cause Breakdownlakeflow_termination_taxonomyA 30-day tally, per workspace, of how many job runs ended with each termination code — the root-cause taxonomy of why runs stopped.20Discover Job Termination-Type Valueslakeflow_termination_type_probeA runtime discovery probe that lists the distinct raw `termination_type` values appearing on finished job runs per workspace over the last 30 days, with a count of how many end-of-run rows carry each value.21Daily Job Run Mix And Hourslakeflow_workload_mix_hoursA daily breakdown, per workspace, of how many distinct job runs were active and how many execution-seconds they consumed, sliced by run type and trigger type over the trailing 30 days.