Why we ditched Lumen PHP

Lumen PHP it a perfect candidate for building scalable and high-performance APIs. Until it isn’t.

Why we ditched Lumen PHP

Lumen is a stripped down version of the powerful and now very popular Laravel PHP framework, focused on performance and serving stateless requests. I doesn’t have all the bells and whistles of Laravel, but it also doesn’t need them when serving API requests.

For example, sessions, cookies and views are not a part of Lumen. It’s not intended for serving websites so everything around that got ditched.

This also is why we ditched Laravel Spark in 2018 and migrated to Lumen PHP, as I already mentioned in a previous article. Because Lumen PHP it a perfect candidate for building scalable and high-performance APIs.

Until it doesn’t.

After we migrated to Lumen PHP, we did get all the benefits from it. The API was completely separated from the client web app, the performance was amazing, and everything seemed fine.

The main wall that we hit were the libraries. Such as Laravel Horizon for Redis queue management, Laravel Passport for oAuth. We were able to use this with some hacks and third party packages that found ways to make the work with Lumen.

Then we needed Laravel Cashier, to integrate the payments processor.

And that was the last straw.

I realized that we were way behind on many packages, because there was no up-to-date hacks available. Especially when we tried to migrate to the latest Lumen 7.x, as we were on Lumen 5.6.

After a ton of research and listening to a podcast by Taylor Otwell who said the bootstrap is about 5 ms, which is insignificant, we embarked on an adventure to migrate the API into a brand new Laravel application. Some people said that for a blank application, Lumen has a 20% boost over Laravel, due to the routing library. They also said that this only applies to “Hello World” benchmarks, where most of the work is the actual routing, and that for real live applications, that percent is much lower. Anyway, my personal take on this is that for the 20% performance difference, it’s not worth wasting time with Lumen.

So, it was time to skip hacking ancient versions of Lumen and switch to Laravel for the core application. It has a lot of features that we need for development speed, and the (allegedly) 20% boost in performance is not worth wasting time with hacks, vulnerable and obsolete libraries, and our sanity.

The process of migrating went pretty smooth and it took about one full week.

Step 1 — was to create a new Laravel application.

Step 2 — was to copy all the tests from Lumen and update phpunit.xml to use the new folders in tests.

Then, run phpunit and see which is the first running and failing test, and run just that test.

Finally, make each test pass:

  • change extends \TestCase to extends TestCase and add use Tests\TestCase; as Laravel’s test are better namespaced.
  • change use DatabaseTransactions to use RefreshDatabase to refresh the migrations on each run.
  • add the migrations and model factories required for the data structures.
  • integrate the helpers.
  • run tests and fix whatever fails.

After days of red test results, we were finally able to migrate all the code to the latest Laravel version.

From then on, we’re updating the packages every week, because the complete test suite allows us to confidently apply updates and ship the API to production.

I’m curious if you have undergone such a migration, as well as the challenges and benefits that came with it.