cancel
Showing results for 
Search instead for 
Did you mean: 
Community Articles
Dive into a collaborative space where members like YOU can exchange knowledge, tips, and best practices. Join the conversation today and unlock a wealth of collective wisdom to enhance your experience and drive success.
cancel
Showing results for 
Search instead for 
Did you mean: 

Turning Lakeflow Jobs into an SLO Dashboard with System Tables

rishav_sharma
New Contributor III

Lakeflow Jobs give teams a strong operational surface for individual workflows, but platform teams often need a different view: Which jobs are missing their reliability target? Which pipelines are getting slower? Which failures are concentrated in one owner, workspace, task, or schedule? Which successful jobs are becoming expensive?

System tables make it possible to answer these questions at account scope. The system.lakeflow tables record job and task activity, while the billing tables let you connect operational behavior to cost for jobs compute and serverless jobs.

This post walks through a simple service-level objective, or SLO, dashboard pattern for Lakeflow Jobs. The goal is not to replace the Jobs UI. The goal is to create a shared operational view that platform teams and data product owners can review every week.

Why SLOs belong next to job metadata

Most data teams already have informal expectations:

  • The daily finance load should finish before 7:00 AM.
  • The customer 360 pipeline should succeed at least 99 percent of the time.
  • A warehouse refresh should not suddenly cost twice as much.
  • Critical jobs should have an owner and a run-as identity that is not a personal user.

These expectations often live in chat threads, runbooks, or tribal knowledge. That makes them hard to audit and hard to improve.

An SLO dashboard gives you a practical middle ground. It does not need to be perfect on day one. It needs to show the jobs that deserve attention, explain why they are flagged, and give owners enough context to act.

What system tables give you

The Lakeflow jobs system tables are available under system.lakeflow. They include account-level records for jobs, tasks, job runs, task runs, pipelines, and pipeline updates in the current cloud region.

For this pattern, the most useful tables are:

  • system.lakeflow.jobs: job definitions and metadata.
  • system.lakeflow.job_tasks: job task definitions.
  • system.lakeflow.job_run_timeline: job run history and state.
  • system.lakeflow.job_task_run_timeline: task run history and state.
  • system.billing.usage: billable usage records.
  • system.billing.list_prices: pricing records used to estimate list cost.

There are two important boundaries:

  • System table access requires the right account and schema permissions.
  • Job records are regional. To monitor workspaces in another cloud region, run the queries from a workspace in that region.

Define the first SLOs

Start with a small set of SLOs that a platform team can explain:

SLO Why it matters Example threshold

Success rateReliability of scheduled work98 percent success over 30 days
P95 durationDetects jobs that are getting slowerLess than 1.5x the agreed target
FreshnessDetects jobs that stopped runningLast successful run within expected schedule
Cost per successful runFinds inefficient or runaway jobsWithin expected range for the job class
Ownership coverageEnsures accountabilityOwner tag and non-personal run-as for critical jobs

You can store formal thresholds in a small reference table. That keeps the dashboard logic clean and lets each domain tune its own targets.

CREATE TABLE IF NOT EXISTS ops_reference.job_slo_targets (
  workspace_id STRING,
  job_id STRING,
  owner_team STRING,
  criticality STRING,
  min_success_rate_30d DOUBLE,
  max_p95_duration_minutes DOUBLE,
  max_hours_since_success DOUBLE,
  max_cost_per_successful_run DOUBLE
);

For an initial rollout, populate only the most important production jobs. Jobs without a target can still appear in discovery panels, but they should not create false SLO breaches.

Build the operational view

The following view summarizes 30-day job reliability and duration. Adjust the catalog and schema names to match your workspace.

CREATE OR REPLACE VIEW ops_observability.lakeflow_job_slo_30d AS
WITH latest_jobs AS (
  SELECT
    workspace_id,
    job_id,
    name AS job_name,
    creator_id,
    run_as,
    tags,
    ROW_NUMBER() OVER (
      PARTITION BY workspace_id, job_id
      ORDER BY change_time DESC
    ) AS rn
  FROM system.lakeflow.jobs
  QUALIFY rn = 1
),
runs AS (
  SELECT
    workspace_id,
    job_id,
    run_id,
    period_start_time,
    period_end_time,
    result_state,
    (unix_timestamp(period_end_time) - unix_timestamp(period_start_time)) / 60.0
      AS duration_minutes
  FROM system.lakeflow.job_run_timeline
  WHERE period_start_time >= current_timestamp() - INTERVAL 30 DAYS
    AND result_state IS NOT NULL
),
run_summary AS (
  SELECT
    workspace_id,
    job_id,
    count(*) AS total_runs_30d,
    count_if(result_state = 'SUCCEEDED') AS successful_runs_30d,
    count_if(result_state <> 'SUCCEEDED') AS failed_runs_30d,
    count_if(result_state = 'SUCCEEDED') / nullif(count(*), 0) AS success_rate_30d,
    percentile_approx(duration_minutes, 0.95) AS p95_duration_minutes,
    max(CASE WHEN result_state = 'SUCCEEDED' THEN period_end_time END) AS last_success_time
  FROM runs
  GROUP BY workspace_id, job_id
)
SELECT
  j.workspace_id,
  j.job_id,
  j.job_name,
  j.run_as,
  j.creator_id,
  j.tags,
  s.total_runs_30d,
  s.successful_runs_30d,
  s.failed_runs_30d,
  s.success_rate_30d,
  s.p95_duration_minutes,
  s.last_success_time,
  timestampdiff(HOUR, s.last_success_time, current_timestamp()) AS hours_since_success
FROM latest_jobs j
LEFT JOIN run_summary s
  ON j.workspace_id = s.workspace_id
 AND j.job_id = s.job_id;

This view is intentionally simple. It gives you a stable base for dashboards and alerts before adding task-level detail.

Add cost context

Cost is most useful when it is shown beside operational behavior. A job that fails often and costs little may need code cleanup. A job that succeeds but doubles its cost every week may need a compute or data layout review.

The query below estimates list cost for jobs usage over the last 30 days and joins it to the SLO view.

CREATE OR REPLACE VIEW ops_observability.lakeflow_job_slo_30d_with_cost AS
WITH job_usage AS (
  SELECT
    u.workspace_id,
    u.usage_metadata.job_id AS job_id,
    sum(u.usage_quantity * p.pricing.default) AS list_cost_30d
  FROM system.billing.usage u
  INNER JOIN system.billing.list_prices p
    ON u.cloud = p.cloud
   AND u.sku_name = p.sku_name
   AND u.usage_start_time >= p.price_start_time
   AND (u.usage_end_time <= p.price_end_time OR p.price_end_time IS NULL)
  WHERE u.billing_origin_product = 'JOBS'
    AND u.usage_date >= current_date() - INTERVAL 30 DAYS
  GROUP BY u.workspace_id, u.usage_metadata.job_id
)
SELECT
  s.*,
  c.list_cost_30d,
  c.list_cost_30d / nullif(s.successful_runs_30d, 0) AS list_cost_per_successful_run
FROM ops_observability.lakeflow_job_slo_30d s
LEFT JOIN job_usage c
  ON s.workspace_id = c.workspace_id
 AND s.job_id = c.job_id;

This pattern follows a key FinOps rule: use billing records as the cost source, and use job metadata as enrichment.

One limitation to communicate clearly: job cost attribution queries based on billing_origin_product = 'JOBS' focus on jobs compute and serverless jobs. Jobs that run work on SQL warehouses or all-purpose compute need separate attribution logic.

Flag SLO breaches

Once you have the SLO base view, create a focused view for breaches.

CREATE OR REPLACE VIEW ops_observability.lakeflow_job_slo_breaches AS
SELECT
  s.workspace_id,
  s.job_id,
  s.job_name,
  t.owner_team,
  t.criticality,
  s.success_rate_30d,
  t.min_success_rate_30d,
  s.p95_duration_minutes,
  t.max_p95_duration_minutes,
  s.hours_since_success,
  t.max_hours_since_success,
  s.list_cost_per_successful_run,
  t.max_cost_per_successful_run,
  CASE
    WHEN s.success_rate_30d < t.min_success_rate_30d THEN 'SUCCESS_RATE'
    WHEN s.p95_duration_minutes > t.max_p95_duration_minutes THEN 'DURATION'
    WHEN s.hours_since_success > t.max_hours_since_success THEN 'FRESHNESS'
    WHEN s.list_cost_per_successful_run > t.max_cost_per_successful_run THEN 'COST'
    ELSE 'OK'
  END AS breach_reason
FROM ops_observability.lakeflow_job_slo_30d_with_cost s
INNER JOIN ops_reference.job_slo_targets t
  ON s.workspace_id = t.workspace_id
 AND s.job_id = t.job_id
WHERE s.success_rate_30d < t.min_success_rate_30d
   OR s.p95_duration_minutes > t.max_p95_duration_minutes
   OR s.hours_since_success > t.max_hours_since_success
   OR s.list_cost_per_successful_run > t.max_cost_per_successful_run;

This view can drive a Databricks SQL dashboard and alert. The alert should route to the owning team, not only to the platform team.

I usually split the dashboard into four sections:

  1. Executive operational summary: total critical jobs, breached jobs, average success rate, total 30-day jobs list cost.
  2. Breach list: job name, owner team, breach reason, current value, target value, last success time.
  3. Reliability trends: success rate and failure count by week.
  4. Cost and duration outliers: p95 duration, cost per successful run, and failed runs by owner team.

The dashboard should answer "what changed?" before "show me everything."

Task-level drilldown

After the job-level view is trusted, add task-level analysis with system.lakeflow.job_task_run_timeline. This helps answer whether a job is slow because every task is slower, one task is retrying, or a downstream task is waiting on upstream work.

Useful panels include:

  • Top failing tasks in critical jobs.
  • Tasks with the largest p95 duration increase.
  • Tasks that recently started failing after a job definition change.
  • Tasks with retries concentrated in one workspace or owner.

Keep this drilldown separate from the first dashboard page. Platform users need the summary first, then the evidence.

Lessons learned

Do not set SLOs for every job immediately. Start with production jobs that have a clear business owner.

Do not treat missing targets as breaches. Missing targets are an adoption backlog item.

Do not calculate cost from job metadata alone. Start from system.billing.usage, join to prices, and enrich with job metadata.

Do not forget the region boundary. If your Databricks account spans regions, plan for one dashboard per region or a consolidation process.

Do not make the alert too noisy. A weekly review dashboard often creates better behavior than a chat alert for every failed development job.

Conclusion

Lakeflow Jobs already expose operational detail. System tables let you turn that detail into an account-level management view. By defining a small set of SLOs, joining run metadata with billing records, and routing breaches to owners, you can move from reactive job debugging to a repeatable operating rhythm.

Start with the 20 jobs that matter most. Once those owners trust the dashboard, expand the target table and add task-level drilldowns.

0 REPLIES 0