Find why a job got slower

Go from "this job is slower or costs more" to the cause: a change to its SQL, extra runs, queueing, or one expensive operator.

When to use: a job's runtime or cost went up and you want the cause before you change anything.

The examples use the job nightly_revenue &&& load_orders (DAG nightly_revenue, task load_orders).

1. Confirm the job is above its usual cost

Type:

Which of my jobs are above their usual cost? Use Single Origin.

The agent calls jobs_overview with lens="above_usual". Look for your job in jobs and read its reason (for example "4.1x its usual day on 2026-05-08") and lens_cost (the cost above usual). An empty list means nothing is above usual on the last loaded day.

If you already know the job, skip to step 2.

2. See what the job runs, and whether that changed

Type:

Summarize nightly_revenue &&& load_orders with Single Origin. Did its SQL change, or does it run more often?

The agent calls query_summary_for_job with job_id="nightly_revenue &&& load_orders". Look at, per statement type (job_tag):

  • statement_versions_30d: more than 1 means the SQL changed in the last 30 days;
  • redeploy_cost_30d and redeploy_episodes: runs that applied changed logic to history;
  • scheduled_runs and triggered_runs: extra runs by hand, API or script;
  • day_cost and sample_query_id: the costliest statement and a query to inspect.

3. Compare runs before and after the change

Type:

Compare nightly_revenue &&& load_orders before and after 2026-05-01 with Single Origin.

The agent calls job_run_comparison with job_id and change_date="2026-05-01". In verdict, read cost_per_run_change, runs_per_day_change and runtime_max_change. If cost per day rose but cost per run didn't, the job runs more often, not slower. If too_little_data is true, the windows are too short to call.

4. Check for queueing

Type:

Show me query <sample_query_id> with Single Origin. Was the warehouse busy?

The agent calls query_detail. Read warehouse_name, warehouse_size, max_concurrency and avg_concurrency. High concurrency points at the warehouse, not the query: the fix is the warehouse's load, not the SQL.

5. Find the expensive operator

In your agent (Snowflake only). Type:

Why is query <sample_query_id> slow? Read its Single Origin profile.

The agent calls query_profile_detail. Read the operators with the largest c= (share of the query's cost), and on scans compare partitions= scanned to total. A scan that reads nearly all partitions under a date filter is a pruning problem. Don't size a fix on a failed or cancelled query's profile; it is partial.

A good final answer

nightly_revenue &&& load_orders cost 4.1x its usual day on 2026-05-08. A new version of its INSERT first ran on 2026-05-01; since then cost per run rose 74% and runs per day stayed at 1. The profile shows the scan of analytics.orders_fact now reads 3,650 of 3,650 partitions (64% of the query's cost); the old version filtered on order_date. Restore the date filter in the INSERT. The warehouse was not the cause: average concurrency 1.2.

⚠️

Watch out for

  • More runs, not slower runs. A lower cost per run with more triggered runs means backfills or reruns, not a slower job.
  • Queueing. When queries wait longer than they run, the warehouse is the cause and the SQL needs no change.
  • Untagged jobs. Queries without a job tag are grouped by query shape under a signature (SO_SIG||<hash>), so one "job" may be several callers.
  • Short windows. Fewer than 3 days with runs on either side is too little to call.
  • Engine limits. Query profiles are Snowflake only.

Related


Did this page help you?