Skip to content

Pending Tenants (draft)

Too many tenant migrations can make creating new tenants slow. To solve that, you can create ready-to-use pending tenants.

Pending tenants are “pre-created” tenants whose pending status is determined by the pending_since attribute — if it’s not null, the tenant is pending. Instead of creating new tenants, a pending tenant will be pulled from the pending tenant pool (pending_since will be set to null, so the tenant’s pending status will be removed).

Usage

To enable pending tenants, make your tenant model (the one used in the tenancy.models.tenant config) use the HasPending trait.

HasPending trait

The HasPending trait includes or excludes pending tenants from the tenant model queries (e.g. Tenant::all()) depending on the value of the tenancy.pending.include_in_queries config key. If the config key is false, pending tenants will be excluded from the tenant queries.

The trait allows you to include and exclude pending tenants manually using the withPending() and withoutPending() query scopes (e.g. Tenant::withPending()->all() or Tenant::withoutPending()->all()) — this way, you can bypass the tenancy.pending.include_in_queries config.

The trait provides methods required for creating and pulling pending tenants (createPending(), pullPending(), pullPendingFromPool()). It also provides the pending() method that determines if the tenant is pending or not (used like $tenant->pending()), depending on the value of the pending_since attribute, which the trait casts to a timestamp (initializeHasPending()).

Pending tenants exclusion from queries

Pending tenants can get included or excluded from Tenant queries (e.g. Tenant::all()) depending on the value of the tenancy.pending.include_in_queries config key. To exclude the tenants from a query manually, add ->withoutPending() to the query, e.g. Tenant::where(...)->withoutPending() and to include them, add ->withPending() instead.

Creating pending tenants

To create pending tenants, you can use the tenants:pending-create command, or the CreatePendingTenants job (the job just calls the command). By default, the pending tenants will be created until the maximum count (the pool size) is reached. The pool size depends on the 'tenancy.pending.count' config key — the TENANCY_PENDING_COUNT environment variable is used as the default pool size, and if the environment variable isn’t set, the pool size defaults to 5.

You can specify how many tenants to create (even beyond the configured pool size) by passing the --count option to the tenants:pending-create command (e.g. php artisan tenants:pending-create --count=10 will create 10 pending tenants, even if the configured pool size is 5).

To manually create a pending tenant, you can use the createPending() method provided by the HasPending trait.

Deleting pending tenants

To clear the pending tenant pool, you can use the tenants:pending-clear command, or the ClearPendingTenants job (the job just calls the command).

Passing the --older-than-days or the --older-than-hours option makes the command delete only the pending tenants that exist for more days/hours than the day/hour amount passed in the option (e.g. php artisan tenants:pending-clear --older-than-days=2 will delete all pending tenants that exist for more than two days). These two options can’t be used simultaneously.

Tenant-aware commands and pending tenants

All tenant-aware commands respect your tenancy.pending.include_in_queries configuration. The commands also have the --with-pending option which makes the command run for pending tenants too. For example, tenants:migrate --with-pending runs tenants:migrate for the pending tenants too, even if the tenancy.pending.include_in_queries config is false.