Skip to main content
Los service providers registrados durante el arranque de Laravel se cargan siempre, incluso si sus funcionalidades no se usan ni una vez durante la petición. Los service providers diferidos (Deferred Service Provider) resuelven este problema: retrasan la carga del provider hasta que sus servicios se usan realmente.
Esta página da por sabido el contenido de Fundamentos del desarrollo de paquetes. Es recomendable entender primero cómo funciona un service provider normal.

Por qué necesitas providers diferidos

Un service provider normal ejecuta register() y boot() en cada petición. Es un desperdicio inicializar en todas las páginas funcionalidades como el envío de correos, colas o caché si no se usan en muchas de ellas.
Si haces este provider diferido, solo se inicializará en las peticiones que generen realmente un report.

Interfaz DeferrableProvider

Illuminate\Contracts\Support\DeferrableProvider es una interfaz muy simple con un único método provides().
Basta con implementar esta interfaz para que el provider pase a modo diferido.

Implementación básica

La implementación de un provider diferido consta de tres pasos.
1

Implementar DeferrableProvider

2

Enlazar los servicios en register()

Igual que en un provider normal, define los bindings en register().
3

Devolver los servicios registrados en provides()

provides() debe devolver todos los servicios que has enlazado en register(). Laravel usa esta lista para saber al pedir qué servicio debe cargar este provider.

Cómo funciona el manifest de servicios

En el arranque, Laravel genera un archivo llamado bootstrap/cache/services.php. Este manifest contiene la lista de servicios que ofrecen los providers diferidos.
Gracias a este manifest, Laravel sabe qué provider ofrece cada servicio sin necesidad de cargar el archivo del provider. El provider real solo se carga cuando el servicio se resuelve por primera vez.
Cuando añadas o modifiques providers, regenera el manifest.

Flujo interno de funcionamiento


Importancia del método provides()

Si en provides() te olvidas de algún servicio, ese servicio no se resolverá nunca.
Lo mismo aplica si usas las propiedades $bindings / $singletons.

Limitaciones de los providers diferidos

Los providers diferidos son adecuados solo para providers cuyo único cometido es registrar bindings en el contenedor. Los providers que hacen lo siguiente en boot() no pueden ser diferidos.
Puedes escribir un método boot() en un provider diferido, pero su contenido no se ejecutará hasta que se resuelva el servicio. Si en boot() haces cosas «que siempre se necesitan», como rutas o middlewares, obtendrás un comportamiento inesperado.

Método when() — registro por evento

Con el método when() puedes hacer que un provider se registre cuando se dispare un evento concreto. Es útil para providers que solo se necesitan en contextos específicos, como procesos de jobs.
Cuando se dispare uno de los eventos devueltos por when(), el provider se cargará aunque no se haya resuelto directamente ningún servicio.

Uso en el desarrollo de paquetes

Al distribuir un paquete de terceros, los providers diferidos también contribuyen al rendimiento de las aplicaciones de tus usuarios.

Patrón recomendado

mergeConfigFrom() comprueba internamente si la configuración ya está cacheada, así que es seguro llamarlo dentro del register() de un provider diferido. Eso sí, si la configuración está cacheada, no hará nada.

Separar el registro de comandos Artisan con runningInConsole()

Como el registro de comandos solo es necesario al arrancar Artisan, protégelo con runningInConsole(). Si además quieres diferir el provider que registra los comandos, incluye las clases de comando en provides() o proporciona un provider separado dedicado a los comandos.

Ejemplos en el core de Laravel

Muchos de los providers del core de Laravel son diferidos. Es un diseño pensado para no cargar de forma inmediata todos los servicios que no se usan en cada petición. En una aplicación con solo endpoints de API puede darse el caso de que MailServiceProvider o BroadcastServiceProvider no se carguen nunca durante una petición.

Criterios para decidir si diferir

  • Servicios que no se usan en todas las peticiones (correo, reports, clientes de APIs externas, etc.)
  • Servicios cuya inicialización requiere conexiones externas o lectura de archivos.
  • Servicios con grafos de objetos pesados.
  • Providers que solo aportan comandos usados por CLI.
  • Providers que registran rutas (loadRoutesFrom, etc.).
  • Providers que registran middlewares o handlers de excepciones activos permanentemente.
  • Providers que registran global scopes u observers de Eloquent.
  • Servicios ligeros usados en la mayoría de peticiones (donde la sobrecarga del diferido puede ser mayor).

Páginas relacionadas

Fundamentos del desarrollo de paquetes

Aprende cómo desarrollar paquetes Laravel centrados en los service providers.

Gestión de la compatibilidad de versiones de paquetes

Estrategias de mantenimiento de paquetes ante grandes actualizaciones de versión de Laravel y PHP.
Última modificación el 13 de julio de 2026