grahl/ch

Tweaking a slow Lando site

Docker for Mac is notoriously slow, especially in terms of file syncing. It has gotten better in the past but it’s still the platform underperforming the most.

Recent versions of Lando have introduced some optimizations we can make use of to improve performance. To know if that actually benefits us, let’s measure.

Establishing a baseline

First, we need a fairly stable scenario, I choose a module in a project with a decent amount of Drupal kernel tests (70 tests, 1685 assertions). The number of tests should iron out any variations of other things on the host influencing the test.

Executing that on a mediocre i7 running Linux gives us a baseline number without any filesystem overhead:

Time: 5.11 minutes, Memory: 8.00 MB

Beefy i9 with lots of RAM but macOS:

Time: 18.71 minutes, Memory: 8.00 MB

Ouch. So let’s try to use excludes.

Excludes

We can tell Lando to sync certain directories only once, they will then no longer be copied to and from the container. If you are working in a team, where others don’t have this bottleneck you can put that into .lando.local.yml.

excludes:
  - docroot/core
  - docroot/libraries
  - docroot/modules/contrib
  - docroot/themes/contrib
  - docroot/themes/custom/your_theme/node_modules
  - vendor

Note that changes in these folders require a rebuild every time you change something in there, or you execute the command locally as well as in the container for consistency.

Time: 8.34 minutes, Memory: 8.00 MB

It turns out that this particular project consisted of 238k files due to multiple node_modules folders and that 221k of those files could be excluded with little effort.

Just to see what would happen I added the entire repository to the container in an exclude and reran the test, it came in at 3.76 minutes. Not practical for everyday use but showing that with that bottleneck removed, the i9 is now outperforming the other system.

Disabling the home mount

I’m not a fan of the fact that Lando mounts my home directory into the container, apart from performance, that just doesn’t belong there and I’m much happier not having my SSH keys in there.

I have made a fairly trivial change to the CLI you can use to disable this: Remove home mount by grahl · Pull Request #1 · grahl/cli · GitHub

This should help with sluggishness and system load overall. I did not expect it to have a measurable impact when PHPUnit wasn’t looking in /user but it seems to have helped:

Time: 6.16 minutes, Memory: 8.00 MB
Removing unnecessary app mounts

I have not done extensive tests on this but by default every service gets the “app” mount. That’s unnecessary, you can disable it with: app_mount: disabled