---
title: "Lifecycle for Laravel — docs | Roundly"
description: "Developer docs for Lifecycle for Laravel, a state machine for Eloquent: guarded transitions, race-free quotas, expiry, scheduling, rollbacks and history."
url: https://roundly-consulting.com/open-source/docs/lifecycle-for-laravel
language: en
---

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

Open source

# Lifecycle for Laravel

Install

`composer require roundly-consulting/lifecycle-for-laravel`

Requires: PHP ^8.4 · Laravel ^12.0|^13.0

[GitHub](https://github.com/roundly-consulting/lifecycle-for-laravel) [Packagist](https://packagist.org/packages/roundly-consulting/lifecycle-for-laravel) [Donate (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Patreon](https://www.patreon.com/cw/roundly)

## Overview

Status lifecycles — a state machine — for any Eloquent model with a status: orders, tickets, listings, subscriptions, applications. Declare a model’s states and the named transitions between them once, in a small definition class — then every move goes through one guard pipeline that checks who may act, limits and race-free quotas, and writes an append-only history row. Expiry, “expiring soon” warnings, scheduled transitions and rollbacks are built in, and every refusal is a structured, translated reason your UI can show. Native and MIT-licensed, built only on Laravel and Roundly’s own foundation packages — no third-party dependencies.

### What you get

#### Declarative definitions

Backed-enum or string states, an initial state, terminal states and named transitions with wildcards — several lifecycles per model.

#### One guard pipeline

Gate abilities, actor rules, reasons, payload validation, custom guards and deadlines — every refusal is a structured, translated Denial.

#### Limits and race-free quotas

Max occurrences, cooldowns, minimum dwell, rate limits and per-scope quotas that hold even under concurrent requests.

#### Expiry and scheduling

Per-state TTLs, grace periods, once-only warnings, extend and renew, and any transition scheduled for later — one sweep runs them all.

#### Rollbacks and history

Undo the last transition or roll back to a point, with windows, compensation and snapshots — on top of an append-only history.

#### Safe under concurrency

A row lock plus a compare-and-swap write per transition, after-commit events, optimistic versions and idempotency keys.

#### Facade, DI or actions

One Lifecycles facade, an injectable manager or single-purpose actions — plus a fake that refuses what the real engine refuses without a database.

### Documentation

#### [Installation](https://roundly-consulting.com/open-source/docs/lifecycle-for-laravel/installation.md)

Install via Composer, choose key types, publish the migrations, and schedule the sweep when states expire or transitions are scheduled.

#### [Configuration](https://roundly-consulting.com/open-source/docs/lifecycle-for-laravel/configuration.md)

Every config key, default and env variable — key types, subjects, strict writes, actors, transactions, history, rollbacks and schedules.

#### [Defining a lifecycle](https://roundly-consulting.com/open-source/docs/lifecycle-for-laravel/defining-lifecycles.md)

Declare states, the initial and terminal states and named transitions in a definition class — every builder method and how to validate it.

#### [Models with a lifecycle](https://roundly-consulting.com/open-source/docs/lifecycle-for-laravel/subjects.md)

Implement LifecycleSubject, add the HasLifecycle trait and map attributes to definitions — several lifecycles per model, relations and reserved names.

#### [The Lifecycles facade](https://roundly-consulting.com/open-source/docs/lifecycle-for-laravel/facade.md)

Tour the Lifecycles facade — for($model) handles, model() helpers, the definitions() and schedules() accessors, the sweep and direct writes.

#### [DI and actions](https://roundly-consulting.com/open-source/docs/lifecycle-for-laravel/without-facade.md)

Skip the facade: inject LifecycleManager or call a single-purpose action with a request DTO — the handle → manager → action map.

#### [Applying transitions](https://roundly-consulting.com/open-source/docs/lifecycle-for-laravel/applying-transitions.md)

Apply named transitions with an actor, reason and payload — transitionTo(), attempt(), results, optimistic versions and idempotency keys.

#### [Asking before acting](https://roundly-consulting.com/open-source/docs/lifecycle-for-laravel/asking-before-acting.md)

Check a transition before applying it — can(), check(), allowedTransitions() and the structured, translated Decision and Denial objects.

#### [Restrictions and guards](https://roundly-consulting.com/open-source/docs/lifecycle-for-laravel/restrictions.md)

The guard pipeline in order — system context, actor rules, Gate abilities, reasons, payloads, custom guards — and every denial code.

#### [Limits, quotas and freezes](https://roundly-consulting.com/open-source/docs/lifecycle-for-laravel/limits-and-quotas.md)

Max occurrences, cooldowns, minimum dwell, seals, rate limits, race-free quotas per scope, and freezing one lifecycle of a subject.

#### [Handlers, hooks, stamps and snapshots](https://roundly-consulting.com/open-source/docs/lifecycle-for-laravel/handlers-and-hooks.md)

Run side effects inside the transaction with handlers and onEnter/onExit hooks, stamp timestamps, snapshot attributes and compensate on rollback.

#### [Expiry](https://roundly-consulting.com/open-source/docs/lifecycle-for-laravel/expiry.md)

Per-state TTLs from an interval, a closure or a column — grace periods, once-only warnings, effectiveState() and extend, renew or neverExpire().

#### [Scheduled transitions and the sweep](https://roundly-consulting.com/open-source/docs/lifecycle-for-laravel/scheduled-transitions.md)

Schedule any transition for later and run due expiries, warnings and schedules with lifecycle:sweep — inline or queued, with retries.

#### [Rollbacks and history](https://roundly-consulting.com/open-source/docs/lifecycle-for-laravel/rollbacks-and-history.md)

Undo the last transition or roll back to a history point — all or nothing, with windows, compensation and snapshots — plus the append-only history.

#### [Querying](https://roundly-consulting.com/open-source/docs/lifecycle-for-laravel/querying.md)

Query scopes for state, expiry, grace, freezes and time in state — plus withLifecycle() eager loading to avoid N+1 queries.

#### [Strict writes and drift](https://roundly-consulting.com/open-source/docs/lifecycle-for-laravel/strict-writes.md)

Why direct status writes throw, which write paths bypass the engine, and how allowDirectWrites() and adoption reconcile drift.

#### [Definitions and graphs](https://roundly-consulting.com/open-source/docs/lifecycle-for-laravel/definitions-and-graphs.md)

Inspect states and transitions with Lifecycles::model() and definitions(), and export Mermaid or DOT diagrams with lifecycle:graph.

#### [API resources and validation](https://roundly-consulting.com/open-source/docs/lifecycle-for-laravel/api-resources.md)

LifecycleResource and TransitionRecordResource for APIs, the ValidTransition and ValidState rules, and 422 or Retry-After from refusals.

#### [Events](https://roundly-consulting.com/open-source/docs/lifecycle-for-laravel/events.md)

Every event, when it fires and its payload — listen for LifecycleTransitioned, not Eloquent’s updated, and keep side effects after commit.

#### [Artisan commands](https://roundly-consulting.com/open-source/docs/lifecycle-for-laravel/commands.md)

make:lifecycle, sweep, graph, validate, show, adopt and prune — signatures, options and when to run each.

#### [Concurrency and databases](https://roundly-consulting.com/open-source/docs/lifecycle-for-laravel/concurrency.md)

One transaction and lock order per change, compare-and-swap state writes, MySQL READ COMMITTED for quotas, deadlock retries and Octane.

#### [Migrating from status enums](https://roundly-consulting.com/open-source/docs/lifecycle-for-laravel/migrating.md)

Map hand-rolled status enums, checks and commands onto the package, and move an existing table over with lifecycle:adopt.

#### [Testing](https://roundly-consulting.com/open-source/docs/lifecycle-for-laravel/testing.md)

Swap in Lifecycles::fake() to record transitions and refuse on demand, with every assertion — or test the real engine with factories and time travel.

#### [Requirements](https://roundly-consulting.com/open-source/docs/lifecycle-for-laravel/requirements.md)

PHP 8.4+, Laravel 12 or 13, and SQLite, PostgreSQL or MySQL/MariaDB — with the package’s tables in the same database as your models.

## 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.md)
