Cogito ergo sum

How to speed up Vagrant on Windows 10 using NFS7 min read

Background

At work (FlexKids) I have a Windows 10 machine (at home I use both Ubuntu and Windows).
We don’t only Windows, we use OSX and Linux as well. To overcome this (not the only reason) we use Vagrant, Virtual box (CentOs 7) as a development environment. Thus we can ensure we all have the same dev-env.
All OSX users in my team don’t experience any performance issues, while I and other people who use Windows 10 have severe performance issues with Vagrant on Windows. Running simple commands like  php artisan db:seed costs a lot of time. In addition, calling the endpoints using Postman takes more than 4 seconds which is crazy if you know that on OSX it takes barely 1 second to call the same endpoint.

In the beginning I thought it has to do with my setup and my machine specifically, because I use the machine I used during my graduation internship at Flexkids last year (was building a facial recognition API using TensorFlow and Flask ). I have used the vagrant machine to test my project for building and deployment purposes.
So I have deleted that old vagrant box and created a new vagrant box with zero customizations, however I had the same performance issues!  Then I have decided to search online to find if people had the same issues as I do.
I have discovered it’s a known issue, if you don’t use NFS shared folders to sync between the host and the guest machine using Vagrant and VirtualBox, you will experience performance issues.

Vagrant

Vagrant can work with a couple of protocols/mechanisms for syncing folders:

  1. NFS
  2. rsync
  3. SMB
  4. VirtualBox

 

NFS

It’s an acronym for Network File System (NFS) and it’s a distributed file system protocol which was developed by Sun Microsystems back in 1984. NFS allows us to access files over a network just like we access a local storage connected to our computer. NFS is faster than any other protocol and it’s It’s cross-platform protocol. NFS works also on Windows and OSX. NFS has many versions, the latest version is NFSv4.
It’s noteworthy that the official vagrant website says that NFS folders on windows doesn’t work :

Vagrant on NFS on Windows
https://www.vagrantup.com/docs/synced-folders/nfs.html

rsync

It’s a protocol for transferring and synchronizing files between a computer and and external hard drive and also over a computer network. It’s cross-platform protocol. rsync is developed by Wayne Davison back in 1996. rsync is only one-way.

SMB

It’s an acronym for Server Message Block (SMB), it’s used for file sharing and syncing. In addition, it’s also used for Network browsing and printing over a network. SMB is mainly used on Microsoft Windows. SMB was developed by Barry Feigenbaum at IBM back in 1983.

VirtualBox

I know it’s confusing to see VirtualBox, but if you use Vagrant with VirtualBox on Windows 10 and you don’t specify the sync type, then it will used VirtualBox shared folders as default synced folder type (which is extremely slow -_- )

To pump the performance of Vagrant on Windows 10, two things need to be done: the first one is editing your vagrant file; the second is to install Vagrant WinNFSd plugin. Note that we can’t use NFS Out-of-the-box with Vagrant on Windows 10.

1) Vagrant file

If you use Vagrant, then you must have vagrantfile which resides in the same folder as your vagrantbox. In vagrantfile you can specify many settings for your vagrant box. A clean vagrant file would look like (only synced_folder section)

Vagrant.configure("2") do |config|
  # other config here

  config.vm.synced_folder "src/", "/var/www"
end

You notice there is no sync type is specified, that means VirtualBox will be used if the host machine is Windows and you use VirtualBox. Using vagrant with these configurations is extremely slow, so we will just edit that section and add more options to ensure a better performance.

# use NFS for Windows, OSX and Linux
   config.vm.synced_folder 'src/', "/var/www",
     type:"nfs",
     mount_options: %w{rw,async,fsc,nolock,vers=3,udp,rsize=32768,wsize=32768,hard,noatime,actimeo=2}

So we use now nfs as sync protocol for syncing files and folders between the guest and the host machine. As you see we have also added a bunch of options mount_options

rw read and write (two-ways synchronization)

async asynchronous mode

fsc force nfs to use fs-cache

nolock selects whether to use the NLM sideband protocol to lock files on the server. When using the nolock option, applications can lock files, but such locks provide exclusion only against other applications running on the same client. Remote applications are not affected by these locks.

vers=3 use the third version of nfs.

udp use udp protocol, you can also use tcp for transferring the files. TCP could be also used, and many claims tcp works faster. So you have to try both of them and see what works better in your case.

rsize=32768 the number of transferred bytes for writing. The value specified by this option is the maximum size that could be used; however, the actual size used may be smaller. Note: Setting this size to a value less than the largest supported block size will adversely affect performance.

wsize=32768 the number of transferred bytes for writing. The value specified by this option is the maximum size that could be used; however, the actual size used may be smaller. Note: Setting this size to a value less than the largest supported block size will adversely affect performance.

hard determines the recovery behavior of the NFS client after an NFS request times out. When hard is specified NFS requests are retried indefinitely.

noatime setting this value disables the NFS server from updating the inodes access time. As most applications do not necessarily need this value, you can safely disable this updating.

actimeo=2 the absolute time for which file and directory entries are kept in the file-attribute cache after an update.

2) Vagrant WinNFSd

WinNFSd is a vagrant plugin adds support for NFS to Windows. Here is a link to official Github repository https://github.com/winnfsd/vagrant-winnfsd.
To install the plugin, within the command line prompt (or GitBash if installed) just run the following command vagrant plugin install vagrant-winnfsd

After that just run the following command  vagrant reload to reload your vagrant box.

Last words

For me using NFS on Windows 10 with Vagrant was really great, because overall performance just got better. Normally I had to wait more than 40 seconds for some http requests to the API inside the vagrant box, after using nfs I don’t have to wait more than a couple of seconds!

During my research on which mount_options to use, I stumbled upon many blog posts and some times with contradicted claims about some options, for example using udp or tcp. At the end you, you have to test it and try it out by yourself to know which options works better.

A little nice to have ….

If you want to ensure that vagrant-winnfsd is installed and enabled every time you run your vagrant box, just add the following to your vagrant file, just before the code block config.vm.synced_folder

# On Windows we must check if the plugin vagrant-winnfsd if installed. This plugin must be installed to be able to use NFS
 if Vagrant::Util::Platform.windows? then
    unless Vagrant.has_plugin?("vagrant-winnfsd")
      raise  Vagrant::Errors::VagrantError.new, "vagrant-winnfsd plugin is missing. Please install it using 'vagrant plugin install vagrant-winnfsd' and rerun 'vagrant up'"
    end
 end 

# use NFS for Windows, OSX and Linux 
    config.vm.synced_folder 'src/', "/var/www", 
      type:"nfs", 
      mount_options: %w{rw,async,fsc,nolock,vers=3,udp,rsize=32768,wsize=32768,hard,noatime,actimeo=2}

 

Related/used resources

  • https://www.cyberciti.biz/faq/linux-unix-tuning-nfs-server-client-performance/
  • https://linux.die.net/man/5/nfs
  • https://www.jeffgeerling.com/blogs/jeff-geerling/nfs-rsync-and-shared-folder
  • https://blog.theodo.com/2017/07/speed-vagrant-synced-folders/
  • https://www.vagrantup.com/docs/synced-folders/nfs.html#enabling-nfs-synced-folders

About the author

Peshmerge Morad

Data Science student and a software engineer whose interests span multiple fields.

4 comments

Leave a Reply to Danny Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  • sadly, winnfsd dont support newest vagrant version.
    and have issues with composer, dump command. To use composer dump you have to restart vagrant without nfs

  • Thanks for your insights. Helped me a lot to get things up and running.

    I’m using PHP with composer and I’ve found that the option ‘noatime’ was breaking the ‘composer dump-autoload’ command.

    This github issue helped me single out the option that was messing with me:
    https://github.com/composer/composer/issues/5707

    Other search terms for anyone running into the same problem:
    – Error “Argument 1 passed to Composer\Autoload\ClassLoader::addClassMap()”
    – Empty autoload_classmap.php

  • Thanks for this post, it helper and contrary to what Dmitri said, it seems to be working fine with vagrant 2.2.10.

    One thing I think might be a mistake in the Vagrantfile definitions:

    This line:

    mount_options: %w{rw,async,fsc,nolock,vers=3,udp,rsize=32768,wsize=32768,hard,noatime,actimeo=2}

    is in fact an array with a single string element.

    Shouldn’t it be like this (spaces instead of commas)?:

    mount_options: %w[rw async fsc nolock vers=3 udp rsize=32768 wsize=32768 hard noatime actimeo=2]

Cogito ergo sum