Laravel Application Lifecycle
Complete understanding of request lifecycle from entry to exit in Laravel
Laravel Application Lifecycle is the process that every HTTP request goes through from entry to exit. Understanding this process is essential for Laravel developers to perform appropriate optimizations and debug issues.
Lifecycle Stages:
1. Request Entry: HTTP request arrives through web server (Apache/Nginx) to public/index.php file. This file is Laravel's main entry point.
2. Bootstrap: Laravel loads bootstrap/app.php file and creates Application instance. Service Container is also initialized at this stage.
3. Service Providers Registration: All registered Service Providers in config/app.php are loaded. At this stage, register() method of each provider is executed.
4. Service Providers Boot: After registration, boot() method of all providers is executed. At this stage providers can access other services.
5. HTTP Kernel: Request is sent to HTTP Kernel which is defined in app/Http/Kernel.php. Kernel applies middleware stack.
6. Middleware Execution: Middlewares are executed in defined order. Each middleware can modify request or return response.
7. Routing: Routing system maps URL to appropriate Controller and Action. Route model binding is also performed at this stage.
8. Controller Execution: Related Controller is instantiated and action method is executed. Dependency injection is also performed at this stage.
9. Response Generation: Response is returned as View, JSON, Redirect or Response object.
10. Termination Middleware: Terminate middlewares are executed which are used for cleanup operations.
11. Response Send: Final response is sent to client.
Optimizations:
- Route caching to reduce routing overhead
- Config caching to reduce config loading time
- Service Provider optimization
- Middleware optimization
Examples
Request path in index.php
<?php
use Illuminate\Http\Request;
require __DIR__.'/vendor/autoload.php';
$app = require_once __DIR__.'/bootstrap/app.php';
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$response = $kernel->handle(
$request = Request::capture()
);
$response->send();
$kernel->terminate($request, $response);
This code is Laravel's main entry point. Request is captured, sent to Kernel, processed and response is sent.
Service Provider Registration
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function register()
{
// This runs during registration phase
$this->app->singleton('Service', function ($app) {
return new Service();
});
}
public function boot()
{
// This runs after all providers are registered
// Can access other services here
$service = $this->app->make('Service');
}
}
register() runs during registration phase and boot() runs after all providers are registered.
HTTP Kernel and Middleware Stack
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
protected $middleware = [
// Global middleware - runs on every request
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
];
protected $middlewareGroups = [
'web' => [
// Web middleware group
\App\Http\Middleware\EncryptCookies::class,
],
'api' => [
// API middleware group
'throttle:api',
],
];
protected $middlewareAliases = [
'auth' => \App\Http\Middleware\Authenticate::class,
];
}
HTTP Kernel manages middleware stack. Global middleware runs on all requests.
Route Resolution and Controller Execution
<?php
// Route definition
Route::get('/users/{user}', [UserController::class, 'show']);
// Controller
class UserController extends Controller
{
public function show(User $user) // Route model binding
{
// Dependency injection happens here
return view('users.show', compact('user'));
}
}
// Lifecycle:
// 1. Route matches URL
// 2. Route model binding resolves User model
// 3. Controller is instantiated with DI
// 4. Method is executed
// 5. Response is generated
Route resolution includes route matching, model binding, controller instantiation and method execution.
Termination Middleware
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class LogRequestMiddleware
{
public function handle(Request $request, Closure $next)
{
$response = $next($request);
// This runs after response is generated
// But before response is sent
return $response;
}
public function terminate($request, $response)
{
// This runs AFTER response is sent to client
// Use for cleanup, logging, etc.
Log::info('Request completed', [
'url' => $request->url(),
'status' => $response->status()
]);
}
}
terminate() runs after response is sent to client and is used for cleanup operations.
Exception Handling in Lifecycle
<?php
namespace App\Exceptions;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
class Handler extends ExceptionHandler
{
public function render($request, Throwable $exception)
{
// This runs when exception occurs during lifecycle
if ($exception instanceof ModelNotFoundException) {
return response()->json(['error' => 'Not found'], 404);
}
return parent::render($request, $exception);
}
}
// Exception can occur at any stage:
// - During service provider boot
// - During middleware execution
// - During route resolution
// - During controller execution
Exception handler can handle exceptions at any stage of lifecycle.
Console Command Lifecycle
<?php
// Console commands have different lifecycle
// public/index.php is NOT executed
// Entry point: artisan
// 1. Bootstrap app (similar to HTTP)
// 2. Load service providers
// 3. Resolve command from container
// 4. Execute command
// 5. Return exit code
php artisan migrate
// Lifecycle:
// artisan -> Kernel -> CommandResolver -> Command::handle()
Console commands have different lifecycle and use artisan as entry point.
Queue Job Lifecycle
<?php
// Queue jobs have separate lifecycle
// Each job runs in isolated process
// Lifecycle:
// 1. Worker picks job from queue
// 2. Bootstrap app (fresh instance)
// 3. Load service providers
// 4. Instantiate job class
// 5. Execute handle() method
// 6. Cleanup
class ProcessOrder implements ShouldQueue
{
public function handle()
{
// This runs in separate process
// Has its own container instance
}
}
Queue jobs have separate lifecycle and each job runs in separate process.
Use Cases
- Deeper understanding of Laravel's working for debugging
- Performance optimization with lifecycle understanding
- Creating custom middleware to intercept requests
- Creating custom service providers to bootstrap services
- Understanding exception handling in lifecycle
- Optimizing startup time with deferred providers
Common Mistakes
- Assuming service providers boot on every request (deferred providers)
- Using services in register() that haven't been registered yet
- Forgetting that terminate middleware runs after response send
- Using singleton for stateful services causing issues
- Not understanding difference between HTTP and Console lifecycle
- Forgetting exception handling in lifecycle
Best Practices
- Use deferred providers for rarely used services
- In register() only do binding, don't use other services
- Use boot() to access other services
- Use terminate middleware for cleanup operations
- Implement exception handling properly in Handler
- Use route caching and config caching in production
- Optimize middleware to only run on required routes
Edge Cases
- Exception in service provider boot causing crash
- Circular dependency in service providers
- Middleware modifying response after generation
- Route model binding with custom resolution logic
- Console commands requiring HTTP context
- Queue jobs requiring HTTP request
Performance Notes
- Route caching can reduce routing overhead by up to 50%
- Config caching can reduce config loading time
- Deferred providers can reduce bootstrap time
- Middleware optimization can reduce request processing time
- Service provider optimization is important for startup time
- Laravel 11.x has performance improvements in lifecycle
Security Notes
- Ensure security middlewares are in appropriate places
- Exception handling should not expose sensitive information
- Service providers should follow security best practices
- Route model binding should have validation
Interview Points
- What is the lifecycle of an HTTP request in Laravel?
- What is the difference between register() and boot() in service providers?
- How does middleware stack work?
- What is the difference between HTTP and Console lifecycle?
- At which stage is route model binding performed?
- When does termination middleware execute?
- How can you optimize lifecycle?
Version Notes
- Laravel 11.x: Improved performance in bootstrap process
- Laravel 11.x: Changes in application structure
- Laravel 10.x: Improved middleware pipeline
- Laravel 9.x: Improved service provider loading