Laravel 13.31: Queue totalSize() &amp; JobInterrupted Event | Mohamed Said       [Skip to content](#main)  [ ![](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png) Mohamed SaidLaravel Backend Engineer ](https://www.msaied.com/public) - [Home](https://www.msaied.com/public)
- [Projects](https://www.msaied.com/public/projects)
- [Articles](https://www.msaied.com/public/articles)
- [Certificates](https://www.msaied.com/public/certificates)
- [About](https://www.msaied.com/public#about)

           [  Contact](https://www.msaied.com/public#contact) Menu 

Menu
----

Close 

 - [HomeStart here](https://www.msaied.com/public)
- [ProjectsCase studies](https://www.msaied.com/public/projects)
- [ArticlesEngineering notes](https://www.msaied.com/public/articles)
- [CertificatesCredentials](https://www.msaied.com/public/certificates)
- [AboutHow I work](https://www.msaied.com/public#about)
- [ContactGet in touch](https://www.msaied.com/public#contact)

  [Start a conversation](https://www.msaied.com/public#contact) [WhatsApp](https://wa.me/201094619204) [Email](mailto:hello@msaied.com) 

 1. [Home](https://www.msaied.com/public)
2. /
3. [Articles](https://www.msaied.com/public/articles)
4. /
5. [Laravel](https://www.msaied.com/public/articles?category=laravel)
6. /
7. Queue totalSize() and JobInterrupted Event in Laravel 13.31

   [Laravel](https://www.msaied.com/public/articles?category=laravel) 

 Queue totalSize() and JobInterrupted Event in Laravel 13.31
============================================================

 Laravel 13.31 ships Queue::totalSize(), a new JobInterrupted event, chaperone support for BelongsToMany pivot models, cleaner test assertions, and a Vite devServerUrl() helper.

 ![](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp) [Mohamed Said](https://www.msaied.com/public#person) Published 9 Sep 2026 · Updated 9 Sep 2026 · 3 min read

ShareCopy linkCopied

 ![Queue totalSize() and JobInterrupted Event in Laravel 13.31](https://cdn.msaied.com/648/d0e925e5b65d5b1d925fdaf612af5db2.png) 

  On this page +1. [What's New in Laravel 13.31](#whats-new-in-laravel-1331)
2. [Queue totalSize() Method](#queue-codetotalsizecode-method)
3. [JobInterrupted Event](#codejobinterruptedcode-event)
4. [Chaperone Support for BelongsToMany Pivot Models](#chaperone-support-for-codebelongstomanycode-pivot-models)
5. [once Assertions for Mail and Notification Fakes](#codeoncecode-assertions-for-mail-and-notification-fakes)
6. [Vite devServerUrl() Helper](#vite-codedevserverurlcode-helper)
7. [Additional Fixes and Improvements](#additional-fixes-and-improvements)
8. [Key Takeaways](#key-takeaways)

 What's New in Laravel 13.31
---------------------------

The Laravel team released **v13.31.0** on September 8, 2026, packed with quality-of-life improvements for queue management, Eloquent relationships, testing, and front-end tooling. Here is a breakdown of the highlights.

---

Queue `totalSize()` Method
--------------------------

Contributed by [Jack Bayliss](https://github.com/jackbayliss), the new `Queue::totalSize()` method gives you a single call to count every job on a queue connection — pending, delayed, and reserved — without manually summing three separate methods.

```php
// Before
$total = Queue::totalPendingSize()
       + Queue::totalDelayedSize()
       + Queue::totalReservedSize();

// After
$total = Queue::totalSize();

```

This is especially useful for dashboards and monitoring scripts that need a quick health check on queue depth.

---

`JobInterrupted` Event
----------------------

Also contributed by Jack Bayliss, the new `JobInterrupted` event fires whenever a job that implements the `Interruptible` contract is interrupted by the queue worker. You can listen for it to run cleanup logic, flush state, or write an audit log entry.

```php
use Illuminate\Queue\Events\JobInterrupted;

Event::listen(JobInterrupted::class, function (JobInterrupted $event) {
    // Perform cleanup or logging here
});

```

This closes a long-standing gap: previously there was no first-class hook for reacting to a worker-initiated interruption.

---

Chaperone Support for `BelongsToMany` Pivot Models
--------------------------------------------------

[Caleb White](https://github.com/calebdw) added chaperone support to `BelongsToMany` relationships. When you use a custom pivot model that defines `BelongsTo` relations back to the parent and related models, calling `->chaperone()` on the relationship now hydrates those relations from already-loaded model instances instead of issuing extra database queries.

```php
class Tag extends Model
{
    public function posts(): BelongsToMany
    {
        return $this->belongsToMany(Post::class)
            ->using(PostTagPivot::class)
            ->chaperone(); // auto-guesses relationship names
    }
}

```

If the relationship names are non-standard, you can override them explicitly:

```php
->chaperone(declaring: 'tag', related: 'post');

```

If no custom pivot model is provided, `->chaperone()` is a no-op, so it is safe to add without side effects.

---

`once` Assertions for Mail and Notification Fakes
-------------------------------------------------

[@talaridisTh](https://github.com/talaridisTh) added expressive `assertSentOnce` / `assertQueuedOnce` helpers that replace the verbose `*Times(..., 1)` pattern:

```php
// Before
Mail::assertSentTimes(OrderShipped::class, 1);
Notification::assertSentToTimes($user, InvoicePaid::class, 1);

// After
Mail::assertSentOnce(OrderShipped::class);
Notification::assertSentToOnce($user, InvoicePaid::class);

```

The same pattern applies to `assertQueuedOnce` and `assertSentOnDemandOnce`.

---

Vite `devServerUrl()` Helper
----------------------------

[@ramonmalcolm10](https://github.com/ramonmalcolm10) added a `devServerUrl()` method to the Vite class, making it straightforward to retrieve the running Vite development server URL programmatically — useful when generating asset URLs outside of standard Blade directives.

---

Additional Fixes and Improvements
---------------------------------

- Redis queue driver is now cluster-safe (`bulk()` uses node-less `MULTI`; `allQueueNames()` uses `KEYS`).
- `lazy()` and `lazyById()` no longer ignore `limit()` and `offset()`.
- `assertJsonMissingPath()` now correctly handles wildcards.
- Memory leak fix in the HTTP client.
- `UsePolicy` and `UseEloquentBuilder` attributes now resolve from parent classes.
- `RateLimited` job middleware no longer hits limits that should not block the job.
- Context is now correctly propagated to concurrent processes.

---

Key Takeaways
-------------

- **`Queue::totalSize()`** replaces three separate calls with one.
- **`JobInterrupted`** event enables first-class cleanup hooks for interruptible jobs.
- **`BelongsToMany` chaperone** eliminates redundant queries when using custom pivot models with `BelongsTo` relations.
- **`assertSentOnce` / `assertQueuedOnce`** make test assertions more readable.
- **`Vite::devServerUrl()`** exposes the dev server URL as a first-class API.

---

[View the full Laravel 13.31.0 release notes and diff on Laravel News →](https://laravel-news.com/laravel-13-31-0)

- [Laravel 13](https://www.msaied.com/public/articles?search=Laravel%2013)
- [Queue](https://www.msaied.com/public/articles?search=Queue)
- [Eloquent](https://www.msaied.com/public/articles?search=Eloquent)
- [Testing](https://www.msaied.com/public/articles?search=Testing)
- [Release](https://www.msaied.com/public/articles?search=Release)

 Frequently asked questions 
---------------------------

  What does Queue::totalSize() return in Laravel 13.31?It returns the combined count of all jobs on a queue connection — pending, delayed, and reserved — in a single method call, replacing the need to manually sum Queue::totalPendingSize(), Queue::totalDelayedSize(), and Queue::totalReservedSize().

   When does the JobInterrupted event fire in Laravel?The JobInterrupted event fires when a job that implements the Interruptible contract is interrupted by the queue worker. You can listen for it to run cleanup logic, flush state, or log the interruption.

   What does calling -&gt;chaperone() on a BelongsToMany relationship do?When a custom pivot model defines BelongsTo relations back to the parent and related models, chaperone() hydrates those relations from already-loaded instances during BelongsToMany hydration, avoiding extra database queries. If no custom pivot model is used, it is a no-op.

   ![Mohamed Said](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp)About the author
----------------

[Mohamed Said](https://www.msaied.com/public#person)Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

[About](https://www.msaied.com/public#about) [GitHub ↗](https://github.com/EG-Mohamed) [LinkedIn ↗](https://www.linkedin.com/in/msaiedm/) [WhatsApp ↗](https://wa.me/201094619204) [Email Address ↗](mailto:hello@msaied.com) [My CV ↗](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)  

   [Previous articleRead/Write Splitting and Sticky Reads in Laravel: A Production Guide](https://www.msaied.com/public/articles/readwrite-splitting-and-sticky-reads-in-laravel-a-production-guide) [Next articleEvent Sourcing in Laravel: Aggregates, Projectors, and Rebuilding Read Models](https://www.msaied.com/public/articles/event-sourcing-in-laravel-aggregates-projectors-and-rebuilding-read-models)  

   On this page
-------------

1. [What's New in Laravel 13.31](#whats-new-in-laravel-1331)
2. [Queue totalSize() Method](#queue-codetotalsizecode-method)
3. [JobInterrupted Event](#codejobinterruptedcode-event)
4. [Chaperone Support for BelongsToMany Pivot Models](#chaperone-support-for-codebelongstomanycode-pivot-models)
5. [once Assertions for Mail and Notification Fakes](#codeoncecode-assertions-for-mail-and-notification-fakes)
6. [Vite devServerUrl() Helper](#vite-codedevserverurlcode-helper)
7. [Additional Fixes and Improvements](#additional-fixes-and-improvements)
8. [Key Takeaways](#key-takeaways)

 ###  Have a technical challenge?

 Tell me what you’re building. I reply within two working days.

[Start a conversation](https://www.msaied.com/public#contact) 

   Related articles
-----------------

 [ ![](https://cdn.msaied.com/740/cce86edc21eddcbdd2f2454fadaf9c70.png)  · 3 min read### The Pipeline Pattern in Laravel: Custom Pipelines Beyond Middleware

5 Oct 2026 ](https://www.msaied.com/public/articles/the-pipeline-pattern-in-laravel-custom-pipelines-beyond-middleware-1) [ ![](https://cdn.msaied.com/739/2d6897fdcdcf090613f96f72a64b8a78.png)  · 4 min read### MySQL Full-Text Search in Laravel: Indexes, Relevance Scoring, and Boolean Mode

4 Oct 2026 ](https://www.msaied.com/public/articles/mysql-full-text-search-in-laravel-indexes-relevance-scoring-and-boolean-mode) [ ![](https://cdn.msaied.com/738/073696a3fefe18bec825beec5ac658f5.png)  · 4 min read### Laravel Queue Rate-Limited Middleware: Throttling Jobs Without Losing Work

4 Oct 2026 ](https://www.msaied.com/public/articles/laravel-queue-rate-limited-middleware-throttling-jobs-without-losing-work) 

  Have a technical challenge?
----------------------------

Tell me what you’re building. I reply within two working days.

 [Discuss your project ↗](https://www.msaied.com/public#contact) 

  © 2026 Mohamed Said · Built with Laravel, meant to last.Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

 - [Home](https://www.msaied.com/public)
- [Articles](https://www.msaied.com/public/articles)
- [Certificates](https://www.msaied.com/public/certificates)
- [GitHub](https://github.com/EG-Mohamed)
- [LinkedIn](https://www.linkedin.com/in/msaiedm/)
- [WhatsApp](https://wa.me/201094619204)
- [Email Address](mailto:hello@msaied.com)
- [My CV](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
- [Sitemap](https://www.msaied.com/public/sitemap.xml)
