---
title: "Installation — Lifecycle for Laravel | Roundly"
description: "Install via Composer, choose key types, publish the migrations, and schedule the sweep when states expire or transitions are scheduled."
url: https://roundly-consulting.com/open-source/docs/lifecycle-for-laravel/installation
language: en
---

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

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

# Installation

Require the package. The service provider and the Lifecycles facade alias are auto-discovered:

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

The migrations create polymorphic subject and actor columns. If your models (or users) use UUID or ULID keys, set the key types before migrating — all subjects share one key type, and so do all actors:

```bash
LIFECYCLE_KEY_TYPE=uuid          # your models with a lifecycle: bigint (default), uuid or ulid
LIFECYCLE_ACTOR_KEY_TYPE=bigint  # your users
```

The values are case-insensitive, and a blank value is not set, so it reads as bigint. Anything else throws the toolkit’s InvalidConfigurationException when the migrations run, before any table is created.

Publish and run the migrations. They are publish-only — the package never loads them itself — and forward-only:

```bash
php artisan vendor:publish --tag="lifecycle-migrations"
php artisan migrate
```

Optionally publish the config file and the translations (English and Slovak ship with the package):

```bash
php artisan vendor:publish --tag="lifecycle-config"
php artisan vendor:publish --tag="lifecycle-translations"
```

## Your lifecycle columns

A lifecycle attribute is a plain string (or integer) column on your own table; the package adds its own tables for state records, history, schedules and quota locks. Add the column in a migration:

```php
Schema::table('listings', function (Blueprint $table): void {
    $table->string('status', 64)->nullable()->index();   // int-backed enum: unsignedSmallInteger
});
```

No database default is needed: a new model starts in the initial state. Index the column together with any quota scope columns, for example $table->index(\['status', 'user\_id'\]), and list the model in lifecycle.subjects so lifecycle:validate checks it.

## Schedule the sweep

If any state has a TTL, or you schedule transitions, run the sweep every minute. Pruning is optional:

```php
// routes/console.php
use Illuminate\Support\Facades\Schedule;

Schedule::command('lifecycle:sweep')->everyMinute();
Schedule::command('lifecycle:prune')->daily();
```

lifecycle:sweep is isolatable (--isolated prevents parallel runs across servers), and two concurrent sweeps are still safe: each schedule runs at most once.

The package writes its rows on each subject’s own connection, and one sweep covers one connection’s package tables. Models on a connection other than the default need a sweep of that connection too:

```php
// models on another database connection: one sweep per connection
Schedule::command('lifecycle:sweep --database=tenant')->everyMinute();
```

## Check the installation

```bash
php artisan about                 # the "Lifecycle" section
php artisan lifecycle:validate    # every lifecycle of every model in lifecycle.subjects
```

php artisan about shows a Lifecycle section — key types, strict writes, the models in use, queued sweeps, whether lifecycle:sweep is scheduled (for the default connection), and history pruning. lifecycle:validate warns when a definition needs the sweep but it is not scheduled, and checks the sweep of each listed model’s own connection. A sweep scheduled as a closure or job is recognised when it is named lifecycle:sweep (->name('lifecycle:sweep')); an unnamed closure makes the answer unknown.

The publish tags are lifecycle-migrations, lifecycle-config, lifecycle-translations and lifecycle-stubs (the make:lifecycle stubs).

## 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/lifecycle-for-laravel.md)
