- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
3 weeks ago
Hey droid,
First — your analysis is correct and still current. I re-checked the docs: a ForEach task takes exactly one nested task (you can't even nest another ForEach), and the dependency scope sits at the ForEach level, so you can't fan out a heterogeneous sub-graph inside the loop. You're not missing an option — the trade-off you laid out is real.
That said, before resigning yourself to the trade-off: the run_job_task-per-iteration path is cheaper than it used to be, and for a lot of metadata-driven fan-outs the compute-acquisition penalty is mostly solvable today.
- Serverless jobs compute for the child job. There's no cluster to acquire per item in the classic sense — startup is fast and you're not amortizing a warm cluster. For many fan-outs this alone neutralizes most of the "each item pays its own acquisition" cost. Benchmark it on your actual item profile rather than trusting a blanket claim, but it's usually the biggest lever.
- Instance pools if you're on classic compute. Pre-warmed nodes mean each child run grabs a ready node instead of provisioning cold — the classic amortization trick for many short child jobs.
- Concurrency. ForEach runs iterations concurrently (up to your configured concurrency), so wall-clock for run_job_task-per-item often isn't worse than serialized steps collapsed into one task.
Net: run_job_task per item keeps your real multi-task graph — per-step status, retry, condition_task, repair-from-failed-step — and with serverless or pools the cost gap narrows a lot. I'd measure that before collapsing anything.
The collapsed-single-notebook route can claw back some observability (sub-notebooks via dbutils.notebook.run, your own per-step try/except and logging), but as you already know it does NOT give you scheduler-native per-step status, repair-from-failed-step, or condition_task. Partial workaround, not a substitute — I wouldn't take it if per-step repair matters.
On the request itself: it's a good one, and worth filing properly — account team plus the Ideas/feature-request portal, not the forum (the forum won't route it to the Jobs PM reliably). One tip to make it land: frame it around what serverless does NOT solve, because that's the first thing Databricks will point to. Even with serverless, run_job_task-per-item still means N separate child runs — N run pages, no single iteration-scoped sub-DAG view, and clumsier task-value/context sharing within an item. A true in-iteration sub-DAG (depends_on / run_if / condition_task scoped to the iteration, sharing that iteration's context) is about orchestration fidelity and a unified run view, not just cost. Leading with that makes the ask much harder to wave off as "just use serverless."
Principal Data & AI — CI&T
thomazn@ciandt.com
linkedin.com/in/thomaz-antonio-rossito-neto