You're spinning up a new API service. Someone on the team says: "Should we use Lumen? It's faster than Laravel, right?" And you pause. Because you remember Lumen being a thing. You also half-remember it kind of stopped being a thing. But you're not sure when, or why, or whether the people still pitching it are looking at the same calendar you are.
This question keeps coming back. It came back in 2018. It came back in 2020. And in 2023, it's still coming back, usually from someone who Googled "fastest PHP framework" once in 2016 and locked the answer in.
Let's break it down. Because the honest answer in 2023 isn't "don't use Lumen" and it isn't "Lumen is great, ship it." The honest answer is more annoying than that, and more useful.
A Quick Refresher On Why Lumen Existed
Lumen showed up around 2015. Taylor Otwell built it as a stripped-down Laravel. Same Illuminate components under the hood, same routing flavor, same service container, just with a leaner bootstrap and a smaller default footprint. The pitch was specific: if you're building APIs and microservices and you don't need Blade, sessions, cookies, or the full Laravel auth stack, here's a faster front door.
And it was faster. Noticeably. Lumen could serve a basic JSON response in less time than Laravel because it just had less stuff to do per request. No view layer to wire up. No session middleware to evaluate. The container was lighter. Some of the more expensive paths weren't loaded by default.
For 2015-era PHP, that mattered. PHP-FPM was the standard runtime. Every request booted the framework from scratch. Imagine your framework taking, say, several tens of milliseconds to bootstrap and Lumen taking noticeably less. You'd just bought yourself a meaningful chunk of latency back on every request.
That's the thing to remember: Lumen wasn't a different framework. It was a slimmer Laravel, optimized for a specific runtime model: boot, serve one request, die.
What Lumen Got Right
For its moment, Lumen got the trade-off correct.
It picked a real audience: API services, microservices, internal endpoints, things that didn't need server-rendered HTML. It removed real cost: the parts of Laravel that aren't free to load. And it kept the parts that mattered: validation, the service container, jobs, the database layer, the same mental model as Laravel itself.
If you knew Laravel, you knew Lumen. The transferable knowledge was 90% of the framework. The remaining 10% was a list of "things Lumen doesn't ship by default": sessions, cookies, view rendering, certain helpers. You could opt back into most of them when you needed to.
That's a respectable design. A lot of "lightweight framework" pitches in PHP land have been accidental complexity wearing a small hat. Lumen wasn't that. It was Laravel with a diet.
What Stopped Being True
Then a few things happened.
1. Laravel itself got faster. Across the 6.x to 9.x line, the framework's own bootstrap got leaner. Route caching, config caching, optimized class loading, compiled service providers. None of these are exotic, but in aggregate they closed a lot of the gap Lumen used to advertise.
2. Then Laravel Octane showed up. Octane runs your Laravel app on a long-lived worker process (Swoole or RoadRunner) instead of booting per request. Once you do that, the entire "boot cost" argument collapses. There is no per-request boot. The app is already in memory. You handle the request and move on. A Lumen advantage built on bootstrap time becomes irrelevant against a Laravel app that doesn't bootstrap.
3. Lumen's release cadence slowed. New Lumen versions started tracking Laravel's number but with smaller deltas. Eventually, the framework's own guidance shifted to recommend Laravel for new projects, even API-only ones. The signal was clear: Lumen wasn't going to keep pace with Laravel as an actively-evolving codebase.
4. The microservices story shifted. A lot of teams that adopted Lumen for "we'll have many small API services" ended up with two or three Lumen services, never built the rest, and quietly merged things back into a Laravel monolith with route-level scoping. The fleet-of-tiny-PHP-services pattern never really took over the way the pitch suggested it would.
So the original advantage, "faster bootstrap for API workloads," got eroded from three sides at once: Laravel itself, Octane, and the runtime model the world was actually building.
Where Lumen Still Makes Sense In 2023
Now the useful question. Does it still make sense for anyone?
Yes. But the list is short and specific.
You already have Lumen services in production and they work. This is the biggest one. If you've got a Lumen 8 or Lumen 9 service that does its job, has tests, and isn't bleeding maintenance time, the right call is almost always "leave it alone." Migrating a working service is rarely net positive. The "we should be on Laravel" energy is better spent on the next service, not the one that's stable.
You're stuck on classic PHP-FPM and can't run Octane. If your hosting environment doesn't allow long-lived workers (shared hosting, certain managed PaaS setups, restrictive corporate infra), then you're back in the per-request-boot world, and Lumen's smaller bootstrap is still a real number. Smaller than it used to be relative to Laravel, but still measurable on a tight latency budget.
Tiny internal endpoints with a hard memory ceiling. If you're packing a service into a constrained container and the difference between "Laravel boots and uses X memory" vs "Lumen boots and uses noticeably less" matters for your scaling math, that's a real argument. Rare, but it shows up in cost-sensitive setups.
That's about it. Three narrow cases. Notice none of them are "because microservices are cool."
$router->get('/orders/{id}', function ($id) {
return Order::with('items')->findOrFail($id);
});
$router->post('/orders', 'OrderController@store');
// Validation, container, jobs — all there.
$router->group(['middleware' => 'auth'], function () use ($router) {
$router->post('/orders/{id}/refund', 'OrderController@refund');
});
If you're already operating in this world, none of this is alarming. It works.
Where It Doesn't (And You Should Pick Something Else)
The cases where Lumen is the wrong choice in 2023 are bigger.
Greenfield API services. If you're starting today and you control the runtime, just use Laravel. Add Octane if you need the throughput. You'll get the full ecosystem (every package, every doc, every Stack Overflow answer) instead of the increasingly dusty subset that explicitly names Lumen.
You expect the service to grow. A common pattern: services start small on Lumen and end up in pain not because Lumen is bad, but because they outgrew the original "tiny API" framing. You start needing sessions, then a view, then a queue dashboard, then a small admin panel. Each of those works on Lumen, but each of those is also a place where you're swimming against the framework's defaults instead of with them. If you suspect the service will grow, picking Lumen is borrowing future friction in exchange for a present optimization that may not even matter.
You're betting on long-term ecosystem support. Newer Laravel features (first-party packages, certain Sanctum/Telescope/Horizon integrations, some testing utilities) land in Laravel first and may never get a polished Lumen-shaped path. Telescope and Horizon, in particular, target full Laravel. That gap widens, not narrows, every year.
You want the latest PHP idioms with first-party support. As Laravel adopts newer PHP features and language patterns, Lumen tends to lag. Not by years, but by enough that "I'm on the modern path" feels less true on Lumen than on Laravel.
The pattern under all four bullets is the same: Lumen optimizes for a runtime cost that Octane removed, while paying ecosystem cost that keeps growing. That's the wrong direction for a new project.

Migrating From Lumen Without Losing Your Weekend
Eventually a lot of teams want out. Maybe the service grew. Maybe you finally got Octane on the platform. Maybe you just want fewer code paths to worry about.
The good news: Lumen-to-Laravel migration is one of the friendlier migrations in PHP land, because the underlying components are the same.
The honest news: it's still real work, and the parts that bite you are predictable.
1. Routing. Lumen's router is similar to Laravel's, but not identical. Group syntax, middleware references, and route-caching behavior have small differences. Plan to walk every route definition and rewrite it in Laravel's routes/api.php style. Most of it is mechanical. A small fraction will surprise you.
2. Service providers. Lumen registers a smaller set of providers by default. When you migrate, you're moving onto Laravel's full provider stack, which means features you'd manually wired up may now exist out of the box. Providers you wrote because Lumen was missing something may now be redundant. Audit them; don't blind-port.
3. Middleware. Lumen middleware classes generally work as-is, but the kernel registration shape is different (bootstrap/app.php vs app/Http/Kernel.php). Move them deliberately. Watch for middleware that depends on session or cookie state. Those will behave differently under Laravel's full request lifecycle.
4. Configuration. Lumen leans on .env heavily and ships fewer config files. Laravel ships more. As you migrate, generate the missing config files (or copy them from a fresh Laravel install) so package defaults work properly. This is where "it ran on Lumen but throws on Laravel" usually comes from: a missing config key the package now expects.
5. Authentication. This is the one most likely to eat a Saturday. If you used Lumen's auth, you probably built around its narrower interface. Laravel has a richer auth stack (Sanctum, Passport, the full guard system). Decide whether you're porting your existing auth as-is or modernizing it during the migration. Don't try to do both at once.
6. Tests. Run them early. Run them often. Most Lumen tests written with TestCase translate directly. Some HTTP-test helpers have slightly different signatures between the two frameworks. Fix these before you do anything else, so you have green tests as a baseline while you migrate.
A reasonable migration order:
1. Spin up a fresh Laravel app on the version aligned with your PHP runtime.
2. Copy over composer dependencies, resolving conflicts.
3. Move routes, controllers, models, requests.
4. Re-register middleware in Laravel's kernel.
5. Audit service providers — port what's still needed, drop redundants.
6. Replay tests; fix the HTTP/test helper deltas.
7. Wire auth deliberately, not by reflex.
8. Add Octane (if your platform allows it). Now you've actually upgraded.
The "add Octane" step is the one people skip. It's the step that turns the migration from a sideways move into an actual win. If you're going to spend the weekend, get the throughput payoff.
So What's The Answer
Lumen is a framework that solved a real problem in 2015 and got slowly outflanked.
It still works. Some teams should keep using it. Most teams starting today shouldn't. And the migration path back to Laravel is well-understood enough that the "we'll be stuck on Lumen forever" fear isn't real.
If you remember nothing else: the bootstrap-cost argument that made Lumen interesting is the argument Octane neutralized. Pick the framework that fits the runtime you're actually going to deploy on, not the runtime you used in 2015.






