One of the great advantages of having a green field cloud-based infrastructure is being able tailor the app using specific features of the platform. Sometimes, cost isn’t an issue. But, many times – particularly for indie devs – it is. Scale isn’t the foremost concern here, and often times dependability isn’t, either. Rather, it’s flexibility and cost. In this post, I’m going to dissect a few ways to take advantage of Azure and save some coin in the process. Estimating Azure costs continues to be one of the most frequent questions I’m asked.
First a couple of housekeeping issues: Windows Azure has a pricing calculator that shows the current prices and allows you to turn the knobs and dials to forecast the price. I’m writing this blog post on 7/24/2013, and since prices are dynamic, this post will be dated as prices modulate so keep that in account. Also, I’m doing rough math to keep this simple, and picking zone 1 for bandwidth costs (which is everywhere except East/Southeast Asia where rates are slightly higher).
What hat are you wearing today?
I’m approaching this as an indie dev who wants to create application services and host content without incurring a big expense. I need reasonable reliability (no under the desk servers, but I don’t need geoloadbalancing, either), and I’m not willing to pay for 2+ servers for an SLA. In short, my apps currently don’t make enough money. These data points below are taken from my current apps you can see on my blog sidebar.
Windows Azure Virtual Machines cost $0.02/hr or about $15/mo. If you’re the kind of person who likes to install all kinds of stuff, this might be for you. It’s a good option to keep in mind because unlike most other offerings, this is completely customizable. I could load up this server and support all my apps, if I wanted to, but for now, this isn’t anything I’m interested in.
First, let’s look at Windows Azure Web Sites (WAWS). With WAWS, you can easily deploy web sites and apps, but lose some of the customization. You can either spin up an app based off an image (like WordPress) or deploy your own web site. You can host up to 10 sites for free, or upgrade to shared mode — required for custom domains and costs about $10/mo.
If we stick with Free, we’re metered to about 1 hour of CPU time per day (which means deploying your own chess engine might be a bad idea). This is also sub-metered to make sure we’re not gobbling up too much in any given block of time – here’s an image of the dashboard for my Dark Skies / Windows 8 app:
File system storage and memory usage you generally don’t have to worry about. Your app is unlikely to change its size footprint, and you’d have to have a specialized case to warrant memory concerns. The free tier is also limited to 165MB/day of outbound bandwidth per day. This is the one we need to watch. More users often mean more CPU, and can mean higher memory usage, but certainly will linearly impact the bandwidth our app uses. In addition, I can see most of these values plotted for the last week on the dashboard:
This WAWS has a very predictable usage pattern. I’m not concerned about the outbound bandwidth yet, but that’s by design. By knowing this value is metered strictly, it’s best to keep images and other static files (such as JS files) elsewhere, such as in blob storage, as those will tear up the 165 MB/day limit.
So let’s take a step back for a moment. What is this WAWS doing? It’s serving Windows 8 live tiles for Dark Skies, like so:
The ASP.NET MVC based site has an engine that determines the moon’s rise/set times, and passes this down to a view which looks like:
<tile> <visual> <binding template="TileWideSmallImageAndText03" branding="name"> <image id="1" src="http://lightpollution.blob.core.windows.net
/icons/80/waning_gibbous.png" alt="moon phase"/> <text id="1">Waning Gibbous Rises at 09:43 p.m. Sets at 09:41 a.m.⁺</text> </binding> <binding template="TileSquarePeekImageAndText04" branding="name"> <image id="1" src="http://lightpollution.blob.core.windows.net
/icons/150/waning_gibbous.png" alt="moon phase"/> <text id="1">Waning Gibbous Rises at 09:43 p.m., sets at 09:41 a.m.⁺</text> </binding> </visual> </tile>
There are a number of tiles that get served from this site, and at this point in time, it’s all it does.
Pretty simple for an entire website. All of the moon images are stored in blob storage instead of in the WAWS. This image is pulled by every Windows 8 app updating its live tile, which is about 1,100 requests per hour. The outbound text adds up to about 20MB/day, or about 600MB/mo. If we assume that each one of those requests are displaying a 10 KB image like in the tile above, that’s 1,100 x 24= 26,400 requests * 10 KB = 264,000 KB/day, or 264 MB/day. Ouch! Remember, we’re limited to 165MB/day – so we can keep within those limits by placing the images in blob storage. Blob storage isn’t free, so this would present a decision: do you put the images in blob storage, or keep them in the WAWS but upgrade to the shared tier? Here’s a quick look at the shared tier:
Using a Shared WAWS
There’s no limiting of bandwidth, and we’ll simply pay for what we use. In our above example, 264MB/day is about 7.5 GB/mo. If we look at the data transfer rate page, the first 5 GB/mo is free, followed by $0.12 / GB. Since our total outbound including the raw text puts us at 8 GB/mo, we’re only charged on 3 GB, and spending $0.36/mo on bandwidth. Remember, too, that we upgraded to Shared mode to unlock the restrictions, which is $9.68/mo.
All said, we’re looking at $10.04/mo if we’d like to put the entire site in a single WAWS.
In this example, let’s break out the images (as it currently is in production) and compare costs. Our WAWS is free, and looking at the meters, we’re comfortable within the usage restrictions. The only thing we need to worry about is our blob storage account. Blob storage, if you aren’t familiar with it, is a service that holds any kind of binary data, like files, images, and documents. It’s scalable and an easy way to separate the code of a website from the content, and compares to Amazon’s S3.
Looking at the storage pricing page, our images consume a a few MB at most, so we need to round this cost down to $0.01 as it’s just impossibly small at this scale. Transactions are incurred for every get request, at the cost of $0.01 per 100,000 transactions. Since we’ve got 26,400 requests/day, that’s 792,000 requests/mo, or about $0.08. The outbound bandwidth remains unchanged.
All said, we’re looking at $0.36/mo for bandwidth and $0.09/mo for storage, for a total of $0.45/mo.
Obviously it’s a big cost savings to stick with the free Windows Azure web site and offload the assets into blob storage. We don’t have an SLA on the free tier, but then, if a request fails, it’s a silent fail as the tile skips that update. The user isn’t likely going to notice.
The difference gets a little more interesting when looking at Windows Azure Mobile Services, and I’ll do that in the next post…