Laravel Interview Questions
Real Laravel interview questions on Eloquent, middleware, the service container, Sanctum, and queues.
A curated set of Laravel interview questions, ordered roughly from fundamentals to more advanced — the kind you'll actually be asked in real screens and on-sites.
Eloquent & the database
Q: When would you use the query builder instead of Eloquent?
Eloquent is well suited to expressing business logic through models — objects with relationships, accessors, casts, and events attached. The plain query builder (DB::table(...)) skips that overhead entirely, returning simple stdClass results, which tends to fit large reporting queries, bulk updates, or any query where you don't need (or want) full model instances. Eloquent is actually built on top of the query builder, so reaching for the builder directly is dropping down one level, not switching to an unrelated tool.
Q: What's the N+1 query problem, and how do you fix it in Laravel?
It happens when fetching a list of records triggers one query, and then accessing a relationship on each record inside a loop triggers one additional query per record — for 100 posts, 101 total queries just to display each post's author. Eager loading with Post::with('author')->get() fixes it by fetching every related author in one extra query up front, regardless of how many posts there are, so accessing $post->author inside the loop reads already-loaded data instead of hitting the database again.
Middleware & the request lifecycle
Q: What is middleware, and what's a concrete example you'd actually write?
Middleware filters and acts on HTTP requests as they flow through the application, before they reach a route's controller, after the response is built, or both — the standard place for concerns that cut across many routes, like authentication, logging, or rate limiting. A concrete example is an admin-guard middleware: it checks $request->user()->is_admin and either calls abort(403) or forwards the request with $next($request), centralizing that check instead of duplicating it in every admin controller.
Q: How is middleware registered and applied in a modern Laravel app?
In Laravel 11 and later, middleware aliases are registered in bootstrap/app.php (via ->withMiddleware(...)) rather than the app/Http/Kernel.php class used in older versions. Once aliased, middleware is applied to routes with ->middleware('name') on a single route or Route::middleware([...])->group(...) across a whole group of routes, and multiple middleware run in the order listed, each able to short-circuit the request before it ever reaches the controller.
The service container & dependency injection
Q: What is the service container, briefly, and why does it matter day to day?
It's Laravel's dependency injection container — a registry that knows how to build objects and their dependencies automatically. In practice, this means a controller method (or any class Laravel resolves) can simply type-hint a class in its constructor or method signature, and Laravel supplies a fully constructed instance, resolving that class's own dependencies recursively. This is what makes Laravel's automatic injection of things like Request objects and Eloquent models (via route model binding) into controller methods possible without any manual wiring.
Templating
Q: What does Blade give you that writing plain PHP in a view file doesn't?
Blade's {{ }} output syntax auto-escapes values by default (guarding against XSS), and directives like @if, @foreach, @extends/@section read more cleanly than equivalent <?php ?> blocks while compiling down to the same cached, plain PHP under the hood — no runtime cost either way. It also adds structure plain PHP doesn't provide out of the box, like inheritance-based layouts (@extends) and reusable components (<x-alert>), which would otherwise mean hand-rolled includes and manually repeated escaping.
Q: Eloquent vs a plain array/data class for representing data — why bother with an ORM at all?
An Eloquent model attaches real behavior to a row of data: relationships (hasMany, belongsTo) that lazy-load or eager-load related records, mass-assignment protection, automatic timestamp management, attribute casting (e.g., a JSON column automatically decoded into an array), and query scopes for reusable filtering logic. A plain array or DTO can hold the same values, but none of that behavior — every relationship, cast, and safeguard would need to be re-implemented by hand at every call site instead of living once on the model.
Authentication & background work
Q: When would you reach for Sanctum instead of Laravel's default session-based authentication?
Session-based auth (the default for web routes and Breeze/Jetstream scaffolding) works when the client is a browser sharing cookies with the app on the same domain. Sanctum is for everything else that still doesn't need a full OAuth2 server: a mobile app or third-party client authenticating with a bearer token from createToken(), or — via its separate stateful mode — a first-party SPA on a related domain authenticating with cookies and CSRF protection instead of a token exposed to its JavaScript at all.
Q: Why dispatch slow work to a queued job instead of running it inline in the controller, and what makes a Job class safe to run later?
Slow operations (sending email, calling a third-party API, generating a report) block the request/response cycle and tie up a web server worker for as long as they take if run synchronously; dispatching a ShouldQueue job lets the controller respond immediately while a separate worker process does the work in the background, with automatic retries ($tries, $backoff) for transient failures. SerializesModels is what makes this safe across a delay — it stores only a model's primary key in the serialized job payload and re-fetches a fresh instance when the job actually runs, instead of operating on a stale snapshot captured at dispatch time.
Testing & tooling
Q: What does a Laravel feature test verify that a narrower unit test doesn't?
A feature test drives a request through the actual route — routing, middleware, controller, validation, and the database — using $this->post(...)/$this->get(...) and asserting on both the HTTP response and real database state (assertDatabaseHas). A unit test isolates one class or method, typically with its dependencies mocked out, and never boots the full request cycle — it can miss a bug in routing or middleware entirely, which is why most Laravel test suites lean heavily on feature tests for anything user-facing.
Q: What does Laravel's task scheduler solve that a handful of manual crontab entries doesn't?
It moves the definition of when each task runs out of server configuration and into version-controlled code (routes/console.php), so adding or changing a schedule is a normal code change reviewed like any other, rather than a manual crontab edit on every server. Only one real crontab entry is ever needed — running php artisan schedule:run every minute — and ->onOneServer() prevents the same task from firing redundantly on every server in a multi-server deployment.