<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/count-worker-crashes-as-job-exceptions-in-laravel-13-34-ry7rk9u4k" -->

---
title: Count Worker Crashes as Job Exceptions in Laravel 13.34
description: Laravel 13.34.0 ships an opt-in #[CountCrashesAsExceptions] attribute so worker crashes (OOM kills, segfaults, container stops) count toward a job's...
canonical: https://daily.dev/posts/count-worker-crashes-as-job-exceptions-in-laravel-13-34-ry7rk9u4k
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Count Worker Crashes as Job Exceptions in Laravel 13.34 | daily.dev
og:description: Laravel 13.34.0 ships an opt-in #[CountCrashesAsExceptions] attribute so worker crashes (OOM kills, segfaults, container stops) count toward a job's...
og:url: https://daily.dev/posts/count-worker-crashes-as-job-exceptions-in-laravel-13-34-ry7rk9u4k
og:image: https://api.daily.dev/og/posts/ry7rK9U4K.png
og:image:alt: Count Worker Crashes as Job Exceptions in Laravel 13.34
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Count Worker Crashes as Job Exceptions in Laravel 13.34

**[Laravel News](https://daily.dev/sources/ln)** · 7 min read · 17 upvotes · 1 comments

## Summary

Laravel 13.34.0 ships an opt-in #[CountCrashesAsExceptions] attribute so worker crashes (OOM kills, segfaults, container stops) count toward a job's maxExceptions, previously only thrown exceptions counted. Interruptible jobs now receive SIGALRM before a timeout so they can save progress, JobProcessed gains a duration property in milliseconds, queue:flush gets a --queue option to clear failures for one queue, Schema::getColumn() returns a single column's details, assertDatabaseCount() accepts an array of table/count pairs, App::environment() and scheduler environments() now accept enums, and requireMorphMap() now applies on the read side of polymorphic relations, not just writes. Dozens of additional bug fixes are included in the changelog.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://laravel-news.com/laravel-13-34-0>

## Questions this post answers

### How do I make Laravel count a worker crash as an exception toward maxExceptions?

Add the #[CountCrashesAsExceptions] attribute (or set public $countCrashesAsExceptions = true) to a queued job class in Laravel 13.34.0. Normally only thrown exceptions count toward maxExceptions, so a worker killed by an OOM error, segfault, or container stop does not count, letting a job with retryUntil() and a rate limiter crash workers repeatedly until its deadline. The worker tracks a cache key per attempt to detect crashes, at the cost of two extra cache calls per attempt, which is why it's opt-in and requires maxExceptions to be set.

_Track opt-in features like this as you plan Laravel queue reliability upgrades on daily.dev._

### How can a Laravel job save its progress before it gets killed by a timeout?

Implement the Interruptible contract in Laravel 13.34.0 and handle the SIGALRM signal in the interrupted() method. Before this release, the worker sent SIGTERM-style signals to interruptible jobs on shutdown but killed jobs on timeout without notifying them first; now the worker calls interrupted() with SIGALRM before marking the job failed, and also dispatches the JobInterrupted event added in Laravel 13.31.

_Developers hardening long-running queue jobs can watch releases like this on daily.dev._

### How do I get the execution time of a Laravel queued job without tracking it manually?

Listen for the JobProcessed event and read its new duration property, added in Laravel 13.34.0. The value is a float in milliseconds rounded to two decimal places, replacing the need to manually track a start time by listening to both JobProcessing and JobProcessed. The property is null when the event fires from somewhere other than the worker.

_Follow granular framework changes like this queue instrumentation update on daily.dev._

## Community discussion

Top comments from developers on daily.dev.

**@pdfopsdev** · 0 upvotes

> the SIGALRM-before-timeout bit is the sneaky good part here, most people don't realize their job can just get killed mid-write with zero chance to flush state. curious if this interacts cleanly with DB transactions or if you still need your own checkpointing on top.

## Similar posts on daily.dev

- [Interruptible Jobs in Laravel 13.7.0](https://daily.dev/posts/interruptible-jobs-in-laravel-13-7-0-mfdtpjnvt) · Laravel News · 53 upvotes · 4 comments
- [Queue totalSize\(\) and JobInterrupted Event in Laravel 13.31](https://daily.dev/posts/queue-totalsize-and-jobinterrupted-event-in-laravel-13-31-chrjuzcn5) · Laravel News · 0 upvotes · 0 comments
- [New Expressive Model Attributes in Laravel 13.2.0](https://daily.dev/posts/new-expressive-model-attributes-in-laravel-13-2-0-d4iyewmhw) · Laravel News · 24 upvotes · 0 comments

---

Tags: [#php](https://daily.dev/tags/php), [#laravel](https://daily.dev/tags/laravel)

[View this post on daily.dev](https://daily.dev/posts/count-worker-crashes-as-job-exceptions-in-laravel-13-34-ry7rk9u4k)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Count Worker Crashes as Job Exceptions in Laravel 13.34","url":"https://daily.dev/posts/count-worker-crashes-as-job-exceptions-in-laravel-13-34-ry7rk9u4k","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/count-worker-crashes-as-job-exceptions-in-laravel-13-34-ry7rk9u4k"},"datePublished":"2026-09-30T13:41:44.850Z","dateModified":"2026-09-30T13:42:09.853Z","description":"Laravel 13.34.0 ships an opt-in #[CountCrashesAsExceptions] attribute so worker crashes (OOM kills, segfaults, container stops) count toward a job's...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/ee40e2048594e45913dd31bd66f36e1c?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/ee40e2048594e45913dd31bd66f36e1c?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Laravel News","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Laravel News","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/ln","url":"https://daily.dev/sources/ln"},"commentCount":1,"discussionUrl":"https://daily.dev/posts/count-worker-crashes-as-job-exceptions-in-laravel-13-34-ry7rk9u4k","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":17},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":1}],"keywords":"php,laravel","timeRequired":"PT7M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Laravel News","item":"https://daily.dev/sources/ln"},{"@type":"ListItem","position":3,"name":"Count Worker Crashes as Job Exceptions in Laravel 13.34"}]}
{"@context":"https://schema.org","@type":"WebPage","@id":"https://daily.dev/posts/count-worker-crashes-as-job-exceptions-in-laravel-13-34-ry7rk9u4k","comment":[{"@type":"Comment","text":"the SIGALRM-before-timeout bit is the sneaky good part here, most people don’t realize their job can just get killed mid-write with zero chance to flush state. curious if this interacts cleanly with DB transactions or if you still need your own checkpointing on top.","datePublished":"2026-10-01T18:05:33.534Z","url":"https://daily.dev/posts/ry7rK9U4K#c-0moZPjHyh","author":{"@type":"Person","name":"PDFops","url":"https://daily.dev/pdfopsdev","image":"https://media.daily.dev/image/upload/s---8isRBKc--/f_auto/v1782922291/avatars/avatar_orjMeK8QKaaVZwGq7ScPz?_a=BAMAMicg0"}}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/count-worker-crashes-as-job-exceptions-in-laravel-13-34-ry7rk9u4k#faq","mainEntity":[{"@type":"Question","name":"How do I make Laravel count a worker crash as an exception toward maxExceptions?","acceptedAnswer":{"@type":"Answer","text":"Add the #[CountCrashesAsExceptions] attribute (or set public $countCrashesAsExceptions = true) to a queued job class in Laravel 13.34.0. Normally only thrown exceptions count toward maxExceptions, so a worker killed by an OOM error, segfault, or container stop does not count, letting a job with retryUntil() and a rate limiter crash workers repeatedly until its deadline. The worker tracks a cache key per attempt to detect crashes, at the cost of two extra cache calls per attempt, which is why it's opt-in and requires maxExceptions to be set. Track opt-in features like this as you plan Laravel queue reliability upgrades on daily.dev."}},{"@type":"Question","name":"How can a Laravel job save its progress before it gets killed by a timeout?","acceptedAnswer":{"@type":"Answer","text":"Implement the Interruptible contract in Laravel 13.34.0 and handle the SIGALRM signal in the interrupted() method. Before this release, the worker sent SIGTERM-style signals to interruptible jobs on shutdown but killed jobs on timeout without notifying them first; now the worker calls interrupted() with SIGALRM before marking the job failed, and also dispatches the JobInterrupted event added in Laravel 13.31. Developers hardening long-running queue jobs can watch releases like this on daily.dev."}},{"@type":"Question","name":"How do I get the execution time of a Laravel queued job without tracking it manually?","acceptedAnswer":{"@type":"Answer","text":"Listen for the JobProcessed event and read its new duration property, added in Laravel 13.34.0. The value is a float in milliseconds rounded to two decimal places, replacing the need to manually track a start time by listening to both JobProcessing and JobProcessed. The property is null when the event fires from somewhere other than the worker. Follow granular framework changes like this queue instrumentation update on daily.dev."}}]}
```

