@van45678 -- @balajij8 's diagnosis matches what your Spark UI shows, so I will just add three things from the operational side, one for the postmortem and two for making sure the next occurrence costs you hours instead of five days.
(1) Driver logs and event logs age out, but the billing system table keeps per-cluster consumption. You can reconstruct exactly what the 149 hours cost:
```sql
SELECT usage_date, sku_name, SUM(usage_quantity) AS dbus
FROM system.billing.usage
WHERE usage_metadata.cluster_id = '<cluster_id>'
GROUP BY ALL
ORDER BY usage_date;
```
Join `system.billing.list_prices` if you want dollars instead of DBUs. We lean on these tables whenever we need measured cost rather than estimates, and for an incident writeup a dollar figure lands better than an hour count.
(2) A cluster that fails to terminate is invisible to job monitoring, because nothing is failing. The signal that does exist is consumption, an all-purpose cluster burning DBUs at 2am on a Saturday. A scheduled query or SQL alert on `system.billing.usage`, grouping all-purpose SKUs by cluster and day with a threshold just above your normal interactive usage, would have flagged this on day one.
(3) You can pin `autotermination_minutes` with a fixed or range rule so nobody quietly raises it. One thing worth noting, the cluster policies API accepts attribute keys it does not support without any validation error. The policy update succeeds, the JSON looks right, and the rule silently does nothing. So after adding any policy rule, create a throwaway cluster under that policy and confirm the setting is actually constrained before you trust it