Performance issues with Local on Windows 10

Here’s why changing ‘localhost’ in wp-config.php works. To be specific:

From

/** MySQL hostname */
define( 'DB_HOST', 'localhost' );

To

define( 'DB_HOST', '127.0.0.1' );

This isn’t a “trick”. Whenever a process sees a name, whether example.tld or localhost, it needs to do a DNS lookup to translate that to an IP Address. The first place it tries in Windows and *nix, including iOS, is /etc/hosts. From there it will attempt to resolve from wherever the local system gets DNS - your local network, your ISP, etc.

But if you look in Windows 10 “C:\Windows\System32\drivers\etc\hosts”, the line is commented out!

# localhost name resolution is handled within DNS itself.
#	127.0.0.1       localhost
#	::1             localhost

The reason for this goes back to Windows Vista, as explained by Sean Earp in this Serverfault thread:

I checked with a developer on the Windows team, and the actual answer is much more innocuous than the other answers to this post :slight_smile:
At some point in the future, as the world transitions from IPV4 to IPV6, IPV4 will be eventually be disabled/uninstalled by companies that want to simplfy network management in their environments.
With Windows Vista, when IPv4 was uninstalled and IPv6 was enabled, a DNS query for an A (IPv4) address resulted in the IPv4 loopback (which came from the hosts file). This of course caused problems when IPv4 was not installed. The fix was to move the always present IPv4 and IPv6 loopback entries from the host into the DNS resolver, where they could be independently disabled.

So even ‘localhost’ goes through a DNS resolution, which takes time. If you hard-set the hostname to an IPv4 address 127.0.0.1, there is no call to DNS - and your DB queries should all be lightning fast as mine are now.

Looking further in /etc/hosts, Local itself modifies the file for local resolution, which is how we can use a ‘foo.local’ domain reference on localhost. Here is their change to the file:

## Local by Flywheel - Start ##
::1 foo.local #Local Site
127.0.0.1 foo.local #Local Site
::1 www.foo.local #Local Site
127.0.0.1 www.foo.local #Local Site
## Local by Flywheel - End ##

So all we need to do is to use “foo.local”? No, I wish.

I tried a new site in Local and set the database host to “foo.local”. It turns out that it still needs to do a DNS query, no surprise, even if just to /etc/hosts. That extends page load time to anywhere from 4 to 13 seconds on my brand new super laptop. I am truly surprised by that and wonder if rebooting to reload ‘hosts’ into cache might help. I don’t have time for further investigation.

When using 127.0.0.1, my page load time went down to around 36ms … this is when using Firefox Developer Tools where caching is disabled. I’m happy with that.

So using the IP address is part of the solution.

As others have noted, xdebug is also activated by default in sitepath\site\conf\php\php.ini.hbs. Just go to the line under [debug] and add a semicolon before it:
;zend_extension = php_xdebug.dll
Restart the site in Local to ensure the INI config file is re-read.

Combining the two of those fixes this issue in a new Windows/Local installation.

Other suggestions relate to OPcache. Since OPcache is already enabled by default in PHP as configured by Local, this isn’t actually a factor. But I’ll comment on it here anyway. A commonly referenced thread says to use this in the above noted php.ini.hbs:

opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=64
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.use_cwd=1
opcache.validate_timestamps=1
opcache.revalidate_freq=5
opcache.enable_file_override=0
opcache.dups_fix=1

As I said OPcache is already enabled - the first two lines above are already in the config file. The value of all of the other settings are subject to your own preferences, but note the “use_cwd=1” setting. I can’t explain this, but when use_cwd is explicitly set to 1, the Local site always aborts with a (Apache) server error 503. And yet, according to the PHP documentation, the value is 1 by default.

So for anyone reading this, 1) you don’t need to enable OPcache, it’s already enabled, and 2) if you do copy/paste the other params and it then aborts with this new 503 error, the solution to this one is to disable that one line with a semicolon until WPEngine offers a suggestion:

;opcache.use_cwd=1

I hope that helps others here.

And since we’re here, I really want to thank WPEngine for all they do, including providing free personal licenses so that we can try and discuss Local like this. I hope someone there looks at this and translates it into internal action items:

  1. If IPV4 is available, default to 127.0.0.1 rather than localhost.
  2. Check to see if IPV4 is available before setting /etc/hosts with 127.0.0.1.
  3. I would suggest for IPV6 a default to ::1 but on someone’s system it might be ::2 or something else. It might be helpful to offer a dropdown for the database host during installation and post-install maintenance. And/or ping ‘localhost’ during installation to see how it resolves and just use the IPv4/6 that comes back. Be sure to change wp-config.php with whatever the value is.
  4. Consider turning off xdebug by default. For all of the people who get stuck on this setting, only more advanced users actually need it. This would be another nice option in the install/config screen.
  5. Please look at the use_cwd thing.

Thanks!

11 Likes