---
title: "Due dates and the sweep — Tickets for Laravel | Roundly"
description: "Set, move or clear due dates, fill them from categories, and flag overdue and due-soon tickets exactly once with Tickets::sweep() or tickets:sweep."
url: https://roundly-consulting.com/open-source/docs/tickets-for-laravel/due-dates
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Tickets for Laravel](https://roundly-consulting.com/open-source/docs/tickets-for-laravel.md)

# Due dates and the sweep

The due date is manual: given at creation, set later, or filled at creation by the Contracts\\DueDateResolver (default: now plus the nearest category’s default\_due\_in) — the seam an SLA layer plugs into:

```php
Tickets::for($ticket)->due(now()->addHours(4));   // TicketDueDateChanged; clears both flags
Tickets::for($ticket)->due(null);                 // no due date
Ticket::query()->overdue()->get();                // past due and unresolved (Waiting counts)

$result = Tickets::sweep();   // SweepResult { overdue: 3, dueSoon: 1 }
```

## The sweep

Tickets::sweep() — and php artisan tickets:sweep, every five minutes — walks the unresolved tickets in id-ordered chunks:

- Past the due date → TicketOverdue, an overdue activity entry and the overdue notification.
- Within tickets.due.soon\_window (PT4H; off = never) → TicketDueSoon and the due\_soon notification (no activity entry).
- Each fires exactly once per due date: a compare-and-set on overdue\_notified\_at / due\_soon\_notified\_at that also matches the due\_at the sweep read, so two concurrent sweeps flag a ticket once and a sweep that read the old date never flags a moved one.
- Moving the due date re-arms both flags. A ticket swept late (already past due) is flagged overdue only.
- The sweep never closes tickets — auto-close is lifecycle:sweep.

```php
$result = Tickets::sweep();   // SweepResult
$result->overdue;             // int — tickets this sweep flagged overdue
$result->dueSoon;             // int — tickets this sweep flagged due soon
$result->total();             // int — both added up
```

SweepResult counts the tickets this sweep flagged. Waiting tickets still count as overdue. The PHP API accepts a past due date (for imports); the HTTP API requires after:now.

## Your own due-date rule

Bind a Contracts\\DueDateResolver (dueAt(Ticket): ?CarbonImmutable) through tickets.due.resolver or the container. It is asked when a ticket is created without a due date, on the stored ticket — with its category loaded — before its custom fields, tags and watchers are written.

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/tickets-for-laravel.md)
