Skip to main content
Service providers registered at Laravel’s boot time are loaded on every request — even if that service is never used during a given request. Deferred Service Providers solve this problem by deferring the loading of a provider until its service is actually needed.
This page assumes familiarity with Laravel Package Development. Make sure you understand the fundamentals of service providers before reading on.

Why deferred providers matter

A typical service provider runs register() and boot() on every request. Initializing mail, queues, cache, and other features that are not needed on every page is wasteful.
By deferring this provider, initialization only happens on requests that actually generate a report.

The DeferrableProvider interface

Illuminate\Contracts\Support\DeferrableProvider is a simple interface with a single method: provides().
Implementing this interface is all it takes to put a provider into deferred mode.

Basic implementation

Implementing a deferred provider takes three steps.
1

Implement DeferrableProvider

2

Register bindings in register()

Write your bindings in register() just like a regular provider.
3

Return registered services from provides()

provides() must return every service bound in register(). Laravel uses this list to determine which provider to load when a given service is requested.

How the service manifest works

At boot time, Laravel generates a manifest file at bootstrap/cache/services.php. This file stores a mapping of all services provided by deferred providers.
Thanks to this manifest, Laravel knows which provider supplies which service without loading any provider files. The actual provider is only loaded the first time its service is resolved.
After adding or modifying providers, regenerate the manifest:

Internal flow


The importance of provides()

If a binding is missing from provides(), that service will never be resolved.
The same applies when using the $bindings / $singletons properties — every key must be included in provides().

Constraints of deferred providers

Deferred providers are designed solely for registering container bindings. Providers that do the following in boot() cannot be deferred.
You can write a boot() method in a deferred provider, but its contents will not run until the service is resolved. Placing “always needed” logic like route or middleware registration in boot() will lead to unexpected behavior.

The when() method — event-triggered loading

The when() method lets you load a provider when a specific event fires, rather than only when a service is resolved. This is useful for providers that are only needed in certain contexts, such as job processing.
When any event listed in when() fires, the provider is loaded even if none of its services have been directly resolved.

Using deferred providers in packages

When distributing a third-party package, a deferred service provider directly benefits the performance of the user’s application.
mergeConfigFrom() internally checks for a cached config, so it is safe to call inside a deferred provider’s register(). However, if config is already cached, it has no effect.

Separating Artisan command registration with runningInConsole()

Command registration is only needed when Artisan is running, so guard it with runningInConsole(). If you want to defer a provider that also registers commands, either include the command classes in provides() or create a separate provider for commands.

Deferred providers in Laravel core

Many of Laravel’s built-in providers are deferred, avoiding eager initialization of services that are not used on every request. In an API-only application, providers like MailServiceProvider and BroadcastServiceProvider may never be loaded at all during a request.

When to defer (and when not to)

  • Services not used on every request (mailers, report generators, external API clients, etc.)
  • Services requiring external connections or file I/O to initialize
  • Services with a heavy object graph
  • Providers that only register CLI commands
  • Providers that register routes (e.g., loadRoutesFrom)
  • Providers that register always-on middleware or exception handlers
  • Providers that register Eloquent global scopes or observers
  • Lightweight services used on the majority of requests (deferred overhead may exceed the benefit)

Laravel Package Development

A comprehensive guide to developing Laravel packages centered on service providers.

Package Versioning and Compatibility

Strategies for maintaining packages across major Laravel and PHP version upgrades.
Last modified on June 6, 2026