As developers we always seek to have the most efficient environment, and that often means buying a high-end laptop. We're going to see in this post that using VS Code Remote Development with Azure can provide a much better environment, for a lower cost.
I believe this is a revolution for consulting companies and freelancers, and that this could change the way we work in the future.
But let's start with a story!
I currently bought myself a Surface Go for my own personal use. This was before I worked at Microsoft, and in fact is totally unrelated to my work activities. My reasons were that :
- It's extremely light and small
- It's very cheap, on Amazon there are always discounts and you can get them for less than $500
- It has Windows 10 with its applications store, including Netflix (a must-have for anyone with kids, as we all know how those offline "Paw Patrol" episodes are useful when traveling)
- It has a UBS-C port, so I can just plug it into my monitor I have for work (Dell UltraSharp 27 - U2719DC) and everything works out-of-the-box
Very important note : there are 2 editions of the Surface Go, use the high-end one. Not only do you have double the RAM and disk, but also you have a real SSD disk which is much faster.
Of course, as a developer, I'm also using it to code, so the question is : how good is this for coding ?
I set up everything using the awesome Chocolatey package manager, including :
- AdoptOpenJDK JDK distribution.
- Cmder terminal emulator.
- Visual Studio Code Insiders, which gives daily builds of VS Studio Code, and is the way to get access to Visual Studio Code remote extensions at the time at this writing.
As the lead of the JHipster project, I'm of course doing those performance tests with a JHipster application, but there's nothing really specific to JHipster here, so they should be the same for about any Java process, or even any process that uses quite a lot of CPU, RAM and disk.
I created a simple project at https://github.com/jdubois/simple-jhipster-app, which you can test on your own machine easily :
- Clone the project :
git clone firstname.lastname@example.org:jdubois/simple-jhipster-app.git
- Run the Maven wrapper :
From a performance point of view, this doesn't look very good :
- Maven takes a long time to run
- Spring Boot starts in 13.5 seconds
Let's see how we can improve this!
Thankfully, for work I have a mid-range (core i5) Surface Book, so it should be better with that hardware, isn't it?
I've installed the same setup on this machine : starting the Spring Boot application takes now 12 seconds, instead of 13.5 seconds! What we are doing is a bit dependant on the CPU, but most of our problems are probably I/O related, and both hardware have the same memory and probably a similar SSD.
So, first interesting lesson from a cost perspective : buying a $500 Surface Go is a very good deal here, as it costs a quarter of the price of the Surface Book, and is also quarter of the weight in your backpack!
As Spring Boot applications are also normal "Main" Java classes, it is possible to simply run the application by running its
main method, in the
SimpleApp class. It's much easier than running Maven, but also much faster. And you can also debug the application with one click!
We are now gaining the Maven start-up time, but the application still starts in 13.5 seconds.
This will allow us to work on a SSH machine, that will be provided by Azure.
Let's create the virtual machine on Azure :
- Go to the Azure portal.
- Create a new virtual machine.
- Choose the default machine type, D2Sv3 at the time of this writing. This costs $0,1120 per hour.
- Add your public key on the first screen, and in the networking screen, don't forget to open the SSH port in the
Select inbound portsdrop-down list.
- Keep all the other options by default, and create the machine.
Once the machine is created, let's configure it with our usual working environment. I personally have my own setup script, which you can of course reuse :
- The script is available at https://github.com/jdubois/jdubois-configuration/blob/master/install.sh
- Login to your new Azure virtual machine using SSH :
ssh username@machine-ip(please note you can find your machine's IP address on its "overview" page on the Azure portal), and become root :
- Once you are logged in, run my installation script as root :
sh -c "$(curl -fsSL https://raw.githubusercontent.com/jdubois/jdubois-configuration/master/install.sh)"
Congratulations, your Azure machine is ready!
Let's go back to VS Code and connect to it. As we will use this SSH connection quite often, I recommend that you create a
.ssh/config file in your home folder, with a setup similar to this one :
Host jdubois-azure HostName 220.127.116.11 User julien
Once you are connected to the Azure virtual machine :
- Use the extension management tab to install the "Java Extension Pack" from Microsoft again, but this time on the remote SSH host.
- Use the command palette to do a Git clone of our sample application
- Run the
SimpleAppclass as we did before.
As a result, our application now starts in 10.3 seconds! That's a bit better than on our Surface Go, but clearly the default Virtual Machine isn't the best option for us.
Please note that if you want to access your application locally on http://localhost:8080, the "Remote Development" tab gives you a graphical utility to create an SSH tunnel.
As we are using Virtual Machines, there are a few very interesting things we can do to optimize both our costs and performance :
- Those machines should only run when you use them, so you should turn them on and off when you work, like a normal computer in fact! Please note that there is an "Auto-shutdown" menu on the Azure portal, and it's probably a good idea to shut down machines automatically for the night or the week-end, in case you forget to do so.
- There is a "Size" menu, which allows you to change the machine type you are using, in order to tune it depending on your desired cost and performance. This doesn't work for all machines, unfortunately : they need to be in the same region, and in the same family.
Let's run our test again, and see the best performance we can get for our application, and calculate its daily associated cost (we are considering here that you work 10 hours per day, 240 days per year). Here are the results, with the associated cost (for the "West Europe" region), with the machines which looked the most promising :
|Machine type||Application start-up time||Daily cost (10 hours)||Yearly cost (240 days)|
|D2S v3 (default)||10.3 seconds||1.20||288|
|F2s v2||5.8 seconds||0.97||233|
|F4s v2||4.0 seconds||1.94||466|
|F8s v2||3.4 seconds||3.88||931|
|H8 Promo||2.9 seconds||6.20||1,488|
Let's study those numbers :
- The default machine (D2S v2) isn't very interesting : it's 30% faster than the Surface Go, so it's not really worth the price and the trouble.
- The "F" machines, which are the "compute-optimized" machines on Azure. Starting with the "F4s" they also have access to premium SSD and accelerated networking, so you get more than just CPU power when you upgrade.
- The "H" machines are for "High performance compute", so basically they have better CPUs than the "F" machines. However, they are much more expensive, and as we saw earlier we are not that much CPU-dependant. Currently there is a "Promo" on some of them, which makes their price more attractive, and in that case they can be an interesting alternative to "F" machines.
As a result, it does seem the "F" machines are the best deal. I would personally use either F4s v2 or F8s v2, and use the "resize" feature to switch depending on my needs. As I have an MSDN subscription, I have $130 of Azure credits every month, so even the H8 Promo could work!
Clearly, running our application on "F" machines types is much faster than on the Surface Go, for a reasonable price. Also, we are able to "resize" and shutdown those machines in order to adapt to the cost and performance we require.
For consulting companies and freelancers, I believe there is here a very compelling alternative to the usual $2,500 Macbook Pro that everybody currently buys :
- The upfront cost is very cheap (about $500), so buying one isn't such a big decision as with a MacBook Pro.
- It's the usual CAPEX vs OPEX calculation we do with the cloud : as a consultant, I'd rather not spend those $2,500 when I start my business, but rather spend a few Dollars each day, depending on my billable work.
- I believe those few Dollars per day could be billed to customers : this doesn't cost much (compared to how much consultants bill their time!), wins time on people on-boarding, and gives better security (code isn't copied on everyone's laptop).