Senior Laravel Developer Interview Questions: A Complete Guide
Master 20 technical interview questions for senior Laravel roles. Learn what interviewers look for and how to articulate your expertise clearly.
Landing a senior Laravel developer position requires demonstrating deep framework knowledge, architectural thinking, and battle-tested experience with production systems. After 14 years of PHP development and conducting dozens of technical interviews, I have compiled the questions that truly distinguish senior developers from those still growing into the role.
Unlike junior interviews focused on syntax recall, senior interviews are conversations. Interviewers want to understand how you think, how you weigh trade-offs, and whether you can explain complex concepts clearly. This guide focuses on what to say rather than what to code.
Service Container and Dependency Injection
The service container is Laravel's foundation. Senior developers must understand not just how to use it, but why its design enables maintainable, testable applications.
Question 1: Explain the difference between bind, singleton, and scoped bindings
What interviewers look for: Understanding of object lifecycle, memory implications, and the judgment to choose appropriately.
Strong answer:
"The three binding types control when Laravel creates new instances. With bind, you get a fresh instance every time you resolve the class—useful for stateless services where you want to avoid side effects bleeding between uses. Singleton creates one instance that persists for the entire application lifecycle—ideal for expensive-to-create services like API clients or configuration objects that don't change.
Scoped is the interesting middle ground: same instance within a single request, but fresh for each new request. This matters a lot with Laravel Octane, where singletons persist across requests and can cause memory leaks or stale data bugs. Scoped bindings give you request-level sharing without the Octane gotchas."
Follow-up to expect: "When have you been bitten by singleton state issues?" Be ready with a real example.
Red flags: Memorizing the syntax without understanding the lifecycle implications. Not mentioning Octane considerations.
Question 2: How does contextual binding work, and when would you use it?
What interviewers look for: Flexibility in thinking about dependency injection beyond simple one-to-one mappings.
Strong answer:
"Contextual binding lets you inject different implementations of the same interface depending on which class is requesting it. The classic example is filesystem storage—your photo controller might need S3 for high-resolution images, while your avatar controller needs local storage for frequently accessed thumbnails.
Instead of creating separate interfaces for each use case, you tell the container: 'When PhotoController asks for Filesystem, give it S3. When AvatarController asks, give it local.' It keeps your controllers clean while allowing different behaviors.
I've used this for logging channels—critical payment services get the Slack channel, while debug services get file logging. Also useful for cache stores where different services have different TTL requirements."
Follow-up to expect: "How would you test a class that uses contextual binding?" Discuss how you'd either mock the dependency or swap bindings in the test service provider.
Question 3: What are PHP 8 container attributes, and how do they change DI patterns?
What interviewers look for: Awareness of modern Laravel features and ability to evaluate when new patterns improve code.
Strong answer:
"Laravel introduced PHP 8 attributes like #[Auth('api')], #[Cache('redis')], and #[Config('app.timezone')] that move contextual binding configuration from service providers directly into constructors. Instead of hunting through service providers to understand what's being injected, dependencies become self-documenting right where they're used.
The trade-off is that it couples your class to Laravel's container more tightly. For domain classes that should be framework-agnostic, I still prefer constructor injection with interface bindings in the service provider. But for controllers and framework-adjacent code, attributes reduce boilerplate significantly."
Eloquent ORM and Query Optimization
Eloquent's elegance can mask performance problems. Senior developers must recognize patterns that cause database bottlenecks.
Question 4: Explain the N+1 query problem and how you prevent it
What interviewers look for: Immediate recognition of the problem, multiple solution strategies, and proactive detection practices.
Strong answer:
"The N+1 problem happens when you fetch a collection of models, then access a relationship on each one in a loop. Laravel lazy-loads relationships by default, so you get one query for the initial collection, then N additional queries—one per item—when accessing the relationship. For 100 records, that's 101 queries instead of 2.
The primary fix is eager loading with with()—you tell Eloquent upfront which relationships you'll need, and it fetches everything in two optimized queries using WHERE IN. You can also constrain the eager load to only get specific related records, nest it for deep relationships, or use load() after the fact if you already have the models.
In development, I always enable strict mode with Model::preventLazyLoading(). It throws an exception whenever lazy loading happens, so N+1 issues surface immediately rather than sneaking into production. Laravel Debugbar's query tab also makes duplicate queries obvious."
Follow-up to expect: "What if eager loading still causes performance issues with large datasets?" Discuss chunking, cursor-based iteration, and whether you actually need all those related records.
Question 5: How do you approach optimizing slow Eloquent queries?
What interviewers look for: Systematic debugging approach and knowledge of optimization techniques beyond just eager loading.
Strong answer:
"First, I need to understand what's actually slow. I'll check the query log or Debugbar to see the actual SQL being generated and identify if it's query count, individual query time, or data volume. For slow individual queries, I'll run EXPLAIN to see the execution plan and check for full table scans.
Common fixes I reach for: selecting only needed columns instead of select *, especially on relationships. Adding database indexes for frequently filtered or sorted columns—composite indexes if the query filters on multiple columns together. Using exists() instead of count() for existence checks since it can short-circuit.
For large datasets, chunking or cursor iteration keeps memory flat. For expensive queries that don't need real-time data, query result caching. Sometimes the answer is accepting that Eloquent isn't the right tool—complex reporting queries often perform better as raw SQL or database views."
Red flags: Immediately jumping to 'add an index' without investigating. Not mentioning profiling first.
Question 6: Walk me through Eloquent relationship types
What interviewers look for: Comprehensive knowledge including polymorphic relationships and pivot table nuances.
Strong answer:
"The basics are one-to-one, one-to-many, and many-to-many. One-to-one is rare in practice—usually profile data on a user. One-to-many is everywhere: users have posts, orders have line items. Many-to-many uses a pivot table and handles the join automatically.
Has-many-through is useful when you need to skip a level—getting all comments on a user's posts without loading the posts themselves. The container handles the join chain.
Polymorphic relationships are where it gets interesting. Morph-many handles things like comments that can belong to posts, videos, or any other model—the table stores both the ID and the model type. Morph-to-many is the many-to-many version, like tags that can be applied to multiple different model types.
The gotcha with polymorphic relationships is the stored class name. If you refactor or rename models, you need migrations to update those type columns. I've seen codebases where they used morph maps to decouple stored values from actual class names."
Queue System and Background Jobs
Production Laravel applications depend on robust queue handling. Senior developers must understand job lifecycle, failure handling, and performance tuning.
Question 7: How do you implement rate limiting for queued jobs?
What interviewers look for: Understanding of job middleware pattern and practical rate limiting for external API calls.
Strong answer:
"Job middleware intercepts jobs before they execute, similar to HTTP middleware. For rate limiting, you typically use Redis throttling—check if you're within limits, and if not, release the job back to the queue with a delay.
The built-in RateLimited middleware works well for simple cases. For per-customer or per-vendor throttling, I'll create custom middleware that builds the throttle key dynamically from job properties. The pattern is: attempt to acquire a lock, if successful process and continue, if not release back to the queue.
Important nuance: released jobs still increment attempt count, so you usually want time-based retry limits with retryUntil() rather than attempt counts. Otherwise a rate-limited job might 'fail' without ever actually being tried."
Follow-up to expect: "How do you handle jobs that should never run concurrently?" Discuss WithoutOverlapping middleware.
Question 8: Explain job batching and how you handle partial failures
What interviewers look for: Knowledge of batch operations and thoughtful error handling strategies.
Strong answer:
"Batching groups related jobs and gives you callbacks for completion, failure, and finally. You can track progress with pending job counts and percentage complete, which is great for user-facing progress indicators on exports or bulk operations.
The key decision is whether to use allowFailures(). Without it, any job failure cancels remaining jobs—appropriate when partial completion is useless. With it, the batch continues despite failures, and you handle the partial success in your finally callback.
Inside batched jobs, you should check batch()->cancelled() early and bail out if true—saves processing time when an error already occurred. Jobs can also add more jobs to their batch dynamically, which is useful for discovery scenarios where you don't know the full scope upfront."
Question 9: How do you configure Horizon for production?
What interviewers look for: Practical experience running queues at scale, not just following tutorials.
Strong answer:
"Horizon gives you multiple supervisors with different configurations. I typically set up at least three: one for critical/fast jobs with high process count and low memory, one for default work with auto-balancing, and one for long-running jobs like exports with fewer processes but more memory and longer timeouts.
The balancing strategy matters—'auto' with 'time' strategy scales based on wait time, which prevents queue backup. For long jobs, 'simple' balancing is usually better since those queues shouldn't auto-scale aggressively.
The nice value prioritizes CPU time between supervisors. Critical supervisors get nice 0, less important work gets higher values. I also tune maxTime and maxJobs to recycle workers periodically, preventing memory bloat from long-running processes.
Monitoring-wise, I set up alerts for queue wait time thresholds and failed job counts. Horizon's dashboard is useful but shouldn't be your only monitoring."
Testing Strategies
Senior developers write tests that catch bugs without slowing development. Testing philosophy matters as much as testing knowledge.
Question 10: When do you use feature tests versus unit tests?
What interviewers look for: Pragmatic testing philosophy rather than dogmatic adherence to any testing pyramid.
Strong answer:
"Unit tests isolate a single class with all dependencies mocked. They're fast, precise, and great for complex business logic like pricing calculations or state machines. Feature tests boot Laravel and test full request cycles—HTTP in, database state changed, response out.
For typical Laravel applications where business logic lives in controllers and Eloquent models, I lean heavily on feature tests. They catch integration issues that unit tests miss—middleware, validation, authorization, database constraints. The overhead of booting Laravel is minimal with modern test tooling.
I'll pull out unit tests when I have pure business logic extracted into service or action classes. A pricing calculator with complex rules deserves unit tests for edge cases. But testing that a controller calls the pricing service correctly? That's a feature test.
The ratio depends on your architecture. Fat controllers means more feature tests. Extracted domain logic means more unit tests. I've seen teams waste time unit testing trivial code that feature tests already cover."
Red flags: Rigid adherence to a specific test ratio without justifying why. Not mentioning what different test types actually catch.
Question 11: How do you test jobs, events, and notifications?
What interviewers look for: Familiarity with Laravel's fake systems and testing side effects.
Strong answer:
"Laravel's fake system is elegant—you call Queue::fake() at the start of a test, and all jobs get captured instead of dispatched. Then you assert on what was pushed: which jobs, with what data, to which queue.
Same pattern for events, notifications, and mail. Fake, trigger the action, assert on what would have been sent. For notifications, you can even assert on the channels and verify the notifiable received specific data.
The distinction I make: fake when testing that side effects were triggered correctly, real execution when testing the side effect itself works. If my test is about order processing dispatching a payment job, I fake the queue. If my test is about the payment job correctly charging Stripe, I run the job directly and mock the Stripe client.
For complex workflows, I sometimes combine approaches—fake most things but let specific events fire to test listener chains."
Question 12: What's your approach to database testing efficiency?
What interviewers look for: Understanding of test isolation strategies and performance optimization.
Strong answer:
"RefreshDatabase trait wraps each test in a database transaction that rolls back, so you get a clean slate without running migrations repeatedly. It's fast for most test suites.
Factories are essential—I invest time in well-designed factories with meaningful states. Admin user, suspended user, verified user as states rather than one-off overrides everywhere. Sequences handle scenarios where you need variety in test data.
For large test suites, parallel testing helps significantly. Laravel handles the database setup—each parallel process gets its own test database. The catch is any test that relies on shared resources like Redis or filesystem needs extra isolation.
I avoid over-seeding. Each test should create only the data it needs. Shared fixtures seem convenient but create hidden dependencies between tests and make failures harder to debug."
Architecture Patterns
Senior developers structure applications for maintainability. These questions probe architectural decision-making.
Question 13: When is the Repository pattern valuable versus overhead?
What interviewers look for: Nuanced view that acknowledges trade-offs, not dogmatic pattern application.
Strong answer:
"The Repository pattern abstracts data access behind an interface, letting you swap implementations or test without a database. In Laravel, the question is whether that abstraction earns its keep.
Repositories add value when you genuinely might swap data sources—maybe you're building a package that should work with different ORMs. Or when complex query logic is repeated across the codebase and deserves encapsulation. Or when your team requires strict separation between business logic and data access for architectural consistency.
They add overhead when your repository methods just mirror Eloquent—find(), create(), update(). That's indirection without benefit. If you'll never swap from Eloquent, and Eloquent's expressiveness is a feature not a liability, you're writing wrappers for the sake of wrappers.
My default: start with Eloquent directly. Extract to repositories when I have complex, repeated queries that would benefit from a name. A method called getActiveUsersWithRecentOrders() tells you more than reading a query builder chain."
Follow-up to expect: "How do you handle this on teams with mixed opinions?" Discuss setting conventions and documenting architectural decisions.
Question 14: How do Action classes fit into Laravel architecture?
What interviewers look for: Understanding of single-responsibility extraction and when it improves versus complicates code.
Strong answer:
"Action classes extract a single operation into its own class. Instead of a 50-line controller method that creates a user, assigns roles, sends welcome email, and logs analytics, you have a CreateUser action that encapsulates all of that.
The benefits compound: that action can be called from a controller, an Artisan command, a queued job, or a test. The controller becomes thin, just handling HTTP concerns. Testing the business logic doesn't require spinning up HTTP requests.
I organize them by domain—Actions/Users/CreateUser, Actions/Orders/ProcessPayment. Each action has one public method, usually execute() or __invoke(). Dependencies come through constructor injection.
The trap is creating actions for everything. A simple CRUD update that's three lines of code doesn't need extraction. Actions shine for operations with multiple steps, external service calls, or complex validation logic."
Question 15: How do you organize a large Laravel application?
What interviewers look for: Understanding of modular architecture and practical organization strategies.
Strong answer:
"Laravel's default structure works for small applications, but large apps need more organization. I typically move toward domain-based structure where business logic groups by concept rather than by technical type.
So instead of one giant Models folder, you have Domain/Users/Models, Domain/Orders/Models. Actions, events, and exceptions live with their domain. The default app folder becomes HTTP concerns—controllers, requests, resources, middleware.
The key principle is that domain code shouldn't depend on framework code. Your order processing logic shouldn't import HTTP Request classes. Keep framework coupling at the edges, pure business logic in the center.
For truly large applications with multiple teams, Laravel's package system lets you extract domains into separate Composer packages with explicit dependencies. That's usually overkill, but it's there when you need hard boundaries."
Security Best Practices
Security knowledge separates senior developers from those who create vulnerabilities.
Question 16: How does Laravel prevent SQL injection?
What interviewers look for: Understanding of parameterized queries and awareness of how to accidentally bypass protection.
Strong answer:
"Eloquent and Query Builder use prepared statements with parameter binding automatically. When you write where('email', $email), Laravel sends the SQL structure and values separately—the database treats user input as data, never as executable SQL.
The danger is raw queries with string interpolation. Using DB::raw() or selectRaw() with concatenated user input bypasses protection entirely. Same with orderByRaw($userInput)—that's injectable.
The fix for dynamic queries is whitelisting. If users can choose sort columns, validate against an allowed list before using it. Never pass user input directly to raw expressions. For complex raw queries, use named bindings.
I've also seen injection through JSON column queries where the path comes from user input. Same principle applies—whitelist allowed paths."
Question 17: Explain CSRF protection and when to exclude routes
What interviewers look for: Understanding of the attack vector and legitimate exclusion scenarios.
Strong answer:
"CSRF exploits the browser's automatic cookie inclusion. If I'm logged into your site and visit a malicious page, that page can submit a form to your site with my session cookies attached. Without CSRF protection, your server can't tell if the request came from your legitimate form or an attacker's page.
Laravel generates a unique token per session, includes it in forms with @csrf, and verifies it matches on submission. The token proves the request originated from your own forms.
Legitimate exclusions are third-party webhooks—Stripe or GitHub callbacks can't include your CSRF token, so they use signature verification instead. API routes using token authentication rather than session cookies don't need CSRF protection since there's no cookie to hijack.
The danger is excluding routes that actually use session auth. If your AJAX endpoints use session cookies, they need CSRF tokens in headers."
Question 18: How do you implement API authentication and authorization?
What interviewers look for: Sanctum knowledge and policy-based authorization patterns.
Strong answer:
"For most Laravel APIs, Sanctum handles authentication. It issues tokens with optional abilities—scopes that limit what the token can do. A mobile app might get full access, while a third-party integration gets read-only tokens.
Token abilities are checked with tokenCan()—useful for restricting what different clients can do with the same authenticated user. A webhook token might only have the ability to create orders, not view customer data.
Authorization beyond authentication uses policies. Each model gets a policy with methods for each action: view, create, update, delete. Policies receive the user and the model, returning true or false. Controllers use authorize() to check policies before acting.
The pattern I like: authentication proves identity, token abilities limit API access, policies enforce business rules. A user might be authenticated with a valid token that allows order management, but the policy still checks that they own the specific order they're trying to modify."
Real-World Scenario Questions
These questions assess practical problem-solving and system design thinking.
Question 19: Your application is experiencing slow response times. Walk through your debugging process.
What interviewers look for: Systematic approach and experience with common bottlenecks.
Strong answer:
"First, I need to scope the problem. Is it all requests or specific endpoints? All users or a subset? When did it start—after a deploy, traffic increase, or data growth? Monitoring dashboards narrow this quickly.
For specific endpoint slowness, I'll check the query count and timing. Laravel Debugbar in development shows this immediately. N+1 queries are the most common culprit—usually visible as dozens of similar queries. Fix is eager loading.
If query count is fine but individual queries are slow, I'll check for missing indexes. Pull the slow query, run EXPLAIN, look for full table scans on large tables. Adding appropriate indexes often provides dramatic improvement.
Beyond database: external API calls that should be queued, heavy computation that could be cached, or just too much data being loaded when pagination or lazy loading would work. For memory issues, I'll check for accidentally loading huge collections into memory.
Systematic approach matters more than jumping to solutions. I've seen developers add indexes randomly hoping something sticks instead of profiling first."
Question 20: Design a notification system that respects user preferences and rate limits
What interviewers look for: System design thinking, consideration of user experience, and practical implementation.
Strong answer:
"User preferences need persistence—what channels they want (email, SMS, push), notification frequency (immediate, daily digest, weekly), and quiet hours. This becomes a related model or JSON column on the user.
Notifications check preferences in their via() method to determine delivery channels. If a user only wants email, that's all they get. Quiet hours are trickier—you either queue notifications for later delivery or batch them into a digest.
For digests, store notifications in the database instead of sending immediately. A scheduled job runs at the user's preferred time, collects pending notifications, renders a digest email, and sends it. This requires notifications to be digest-compatible with summary representations.
Rate limiting prevents notification fatigue—nobody wants 50 emails when their popular post gets engagement. Job middleware with per-user throttling limits notifications per time window. Excess notifications go to the database for digest inclusion.
The notification itself should also support unsubscription. shouldSend() method checks if the user has opted out of this notification type before sending.
Key trade-off: immediate notifications have better engagement but higher annoyance. Digests are less intrusive but reduce urgency. Giving users control respects their preferences while keeping them informed."
Wrapping Up
Senior Laravel interviews are conversations about trade-offs, experience, and judgment. The best candidates don't just know Laravel—they can articulate why they'd choose one approach over another and what they've learned from production systems.
These questions probe depth across the framework, but the common thread is explaining complex concepts clearly while demonstrating practical experience. Technical knowledge matters, but so does the ability to reason through problems and communicate your thinking.
Preparing for Laravel interviews or hiring senior developers? With 14 years of PHP experience and extensive Laravel expertise, I offer consulting services for teams building production applications. Get in touch to discuss your Laravel architecture, performance optimization, or team mentoring needs.
Related Reading:
- Laravel API Development Best Practices: A Complete Guide
- Laravel Octane: Achieving Sub-50ms Response Times
- AI-Assisted Code Review for Laravel
- Migrating Legacy Laravel Apps: Lessons from 14 Years
- TypeScript, Vue 3, and Laravel: End-to-End Type Safety
External Resources:
- Laravel Service Container Documentation - Official Laravel Docs
- Laravel Eloquent Relationships - Official Laravel Docs
- Laravel Queues Documentation - Official Laravel Docs

Richard Joseph Porter
Senior Laravel Developer with 14+ years of experience building scalable web applications. Specializing in PHP, Laravel, Vue.js, and AWS cloud infrastructure. Based in Cebu, Philippines, I help businesses modernize legacy systems and build high-performance APIs.
Need Help Upgrading Your Laravel App?
I specialize in modernizing legacy Laravel applications with zero downtime. Get a free codebase audit and upgrade roadmap.
Related Articles
Laravel API Development Best Practices Guide
Master REST API development with Laravel. Learn authentication, versioning, error handling, rate limiting, and performance optimization from 14 years of PHP experience.
Migrate WordPress to Laravel: The Complete Developer Guide
Step-by-step guide to migrating WordPress sites to Laravel. Cover content migration, database design, SEO preservation, and custom feature implementation.
Migrate Legacy Laravel Apps: 14 Years of Lessons
Upgrade Laravel 4.x-8.x to modern versions safely. Real-world migration strategies, testing patterns, and lessons from 14 years of PHP development.