Increasing Vagrant performance (synced folders)Jul 4, 2014, 9:48:15 AM
I have started development of PHP web apps with Vagrant and consider that it is a great way to go, but one thing that is annoying - poor performance of web application inside Vagrant.
The reason is slow performance of disk system in shared/synced folders.
Default VM Shared Folders
By default when you configure Vagrant like
config.vm.synced_folder "./", "/var/www"
it uses a standard VirtualBox synced folders mechanism, but it is slow. And you see it as a long response time for a web app (mostly it is because of autolading classes and all hard disk related operations).
There are couple ways to handle it :
If to change sync configuration to rsync
config.vm.synced_folder "./", "/var/www", type: "rsync"
it will not mount synced folder, but will make initial sync of files to local VB storage. And the interesting thing is that VB virtual file system is very fast (unlike shared) and you will see blazing fast performace of app.
But there are tricky places :
to make automatic sync of changes on Host system to VB you need to run
vagrant rsync-autoeach time you are running Vagrant box
after each file change it take 2-3 sec. to sync it to VB
this sync is one-direction only, you are not able to sync back changes from VB to Host (Vagrant developer considers to implement dual-side sync in future, but currently no)
So currently I consider
rsync way as not really universal, but the fastes.
Another way is to use NFS mounted disk, Vagrant also natively supports it
config.vm.synced_folder "./", "/var/www", type: "nfs"
Now it will look in the same way as with Default VB sharing, no need to wait for sync and manually start sync. And performance will be better (but not so good as with rsync).
The only thing - it will not work on Windows and on Linux requires to have NFS packages installe don Host and Vagrant machines.
sudo apt-get install nfs-kernel-server nfs-common portmap.
sudo apt-get install nfs-common portmap.
Also NFS requires Private network (not public or bridget), it should be something like
config.vm.network :private_network, ip: "10.10.11.11"
So after one-time configuration it will work automatically and reliable (this is my choice at the moment for a local development on Linux Host).
Update 2014.08.14 : After some time working on NFS I have faced slowdown once again. In code I have found that mostly it is in functions that uses FS lock. The following config fixed it :
config.vm.synced_folder "./", "/var/www", type: "nfs", nfs_version: "4,nolock"
PHP opcode caching (or similar)
Another speedup option that plays well with above solutions - to use opcode cache in RAM. For PHP there are couple of options APC or Zend Opcache. I am not sure, but for other script languages there could be similar solutions.
For example to enable APC on Ubuntu :
~~~ sudo apt-get install php-apc sudo service apache2 restart ~~~ On Vagrant you will see significant PHP application speedup with APC.
Also you can consider this disk performance issue as a good indicator of your app disk usage :) If it is slow on Vagrant - so it is a possible bottleneck on Production.
Automatic system resources setup
Also don't forget to adjust CPU and RAM for better performance.
Thanks to stefanwrobel.com for automated receipt.
config.vm.provider "virtualbox" do |v| host = RbConfig::CONFIG['host_os'] # Give VM 1/4 system memory & access to all cpu cores on the host if host =~ /darwin/ cpus = `sysctl -n hw.ncpu`.to_i # sysctl returns Bytes and we need to convert to MB mem = `sysctl -n hw.memsize`.to_i / 1024 / 1024 / 4 elsif host =~ /linux/ cpus = `nproc`.to_i # meminfo shows KB and we need to convert to MB mem = `grep 'MemTotal' /proc/meminfo | sed -e 's/MemTotal://' -e 's/ kB//'`.to_i / 1024 / 4 else # sorry Windows folks, I can't help you cpus = 2 mem = 1024 end v.customize ["modifyvm", :id, "--memory", mem] v.customize ["modifyvm", :id, "--cpus", cpus] end