Scott Hanselman

Pinching pennies when scaling in The Cloud

March 30, '13 Comments [44] Posted in Azure | Javascript
Sponsored By
The new Hanselminutes Site

Running a site in the cloud and paying for CPU time with pennies and fractions of pennies is a fascinating way to profile your app. I mean, we all should be profiling our apps, right? Really paying attention to what the CPU does and how many database connections are main, what memory usage is like, but we don't. If that code doesn't affect your pocketbook directly, you're less likely to bother.

Interestingly, I find myself performing optimizations driving my hybrid car or dealing with my smartphone's limited data plan. When resources are truly scarce and (most importantly) money is on the line, one finds ways - both clever and obvious - to optimize and cut costs.

Sloppy Code in the Cloud Costs Money

I have a MSDN Subscription which includes quite a bit of free Azure Cloud time. Make sure you've turned this on if you have MSDN yourself. This subscription is under my personal account and I pay if it goes over (I don't get a free pass just because I work for the cloud group) so I want to pay as little as possible if I can.

One of the classic and obvious rules of scaling a system is "do less, and you can do more of it." When you apply this idea to the money you're paying to host your system in the cloud, you want to do as little as possible to stretch your dollar. You pay pennies for CPU time, pennies for bandwidth and pennies for database access - but it adds up. If you're opening database connection a loop, transferring more data than is necessary, you'll pay.

I recently worked with designer Jin Yang and redesigned this blog, made a new home page, and the Hanselminutes Podcast site. In the process we had the idea for a more personal archives page that makes the eponymous show less about me and visually more about the guests. I'm in the process of going through 360+ shows and getting pictures of the guests for each one.

I launched the site and I think it looks great. However, I noticed immediately that the Data Out was REALLY high compared to the old site. I host the MP3s elsewhere, but the images put out almost 500 megs in just hours after the new site was launched.

You can guess from the figure when I launched the new site.

I used way too much bandwidth this day

I *rarely* have to pay for extra bandwidth, but this wasn't looking good. One of the nice things about Azure is that you can view your bill any day, not just at the end of the month. I could see that I was inching up on the outgoing bandwidth. At this rate, I was going to have to pay extra at the end of the month.

Almost out of outbound bandwidth

I thought about it, then realized, duh, I'm loading 360+ images every time someone hits the archives page. It's obvious, of course, in retrospect. But remember that I moved my site into the cloud for two reasons.

  • Save money
  • Scale quickly when I need to

I added caching for all the database calls, which was trivia, but thought about the images thing for a while. I could add paging, or I could make a "just in time" infinite scroll. I dislike paging in this instance as I think folks like to CTRL-F on a large page when the dataset isn't overwhelmingly large.

ASIDE: It's on my list to add "topic tagging" and client-side sorting and filtering for the shows on Hanselminutes. I think this will be a nice addition to the back catalog. I'm also looking at better ways to utilize the growing transcript library. Any thoughts on that?

The easy solution was to lazy load the images as the user scrolls, thereby only using bandwidth for the images you see. I looked at Mike Tupola's jQuery LazyLoad plugin as well as a number of other similar scripts. There's also Luis Almeida's lightweight Unveil if you want fewer bells and whistles. I ended up using the standard Lazy Load.

Implementation was trivial. Add the script:

<script src="//ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2.min.js" type="text/javascript"></script>
<script src="/jquery.lazyload.min.js" type="text/javascript"></script>

Then, give the lazy load plugin a selector. You can say "just images in this div" or "just images with this class" however you like. I chose to do this:

<script>
$(function() {
$("img.lazy").lazyload({effect: "fadeIn"});
});
</script>

The most important part is that the img element that you generate should include a TINY image for the src. That src= will always be loaded, no matter what, since that's what browsers do. Don't believe any lazy loading solution that says otherwise. I use the 1px gray image from the github repo. Also, if you can, set the final height and width of the image  you're loading to ease layout.

<a href="/363/html5-javascript-chrome-and-the-web-platform-with-paul-irish" class="showCard">
<img data-original="/images/shows/363.jpg" class="lazy" src="/images/grey.gif" width="212" height="212" alt="HTML5, JavaScript, Chrome and the Web Platform with Paul Irish" />
<span class="shownumber">363</span>
<div class="overlay">HTML5, JavaScript, Chrome and the Web Platform with Paul Irish</div>
</a>

The image you're going to ultimately load is in the data-original attribute. It will be loaded when the area when the image is supposed to be enters the current viewport. You can set the threshold and cause the images to load a littler earlier if you prefer, like perhaps 200 pixels before it's visible.

$("img.lazy").lazyload({ threshold : 200 });

After I added this change, I let it run for a day and it chilled out my server completely. There isn't that intense burst of 300+ requests for images and bandwidth is way down.

image

10 Websites in 1 VM vs 10 Websites in Shared Mode

I'm running 10 websites on Azure, currently. One of the things that isn't obvious (unless you read) in the pricing calculator is that when you switch to a Reserved Instances on one of your Azure Websites, all of your other shared sites within that datacenter will jump into that reserved VM. You can actually run up to 100 (!) websites in that VM instance and this ends up saving you money.

Aside: It's nice also that these websites are 'in' that one VM, but I don't need to manage or ever think about that VM. Azure Websites sits on top of the VM and it's automatically updated and managed for me. I deploy to some of these websites with Git, some with Web Deploy, and some I update via FTP. I can also scale the VM dynamically and all the Websites get the benefit.

Think about it this way, running 1 Small VM on Azure with up to 100 websites (again, I have 10 today)...

1 VM for $57.60

...is cheaper than running those same 10 websites in Shared Mode.

10 shared websites for $93.60

This pricing is as of March 30, 2013 for those of you in the future.

The point here being, you can squeeze a LOT out of a small VM, and I plan to keep squeezing, caching, and optimizing as much as I can so I can pay as little as possible in the Cloud. If I can get this VM to do less, then I will be able to run more sites on it and save money.

The result of all this is that I'm starting to code differently now that I can see the pennies add up based on a specific changes.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web
Saturday, March 30, 2013 9:22:21 AM UTC
Shouldn't we all do these kind of optimizations for a lower 'data transfer out'? It will make people who have to pay for their 'data transfer in' (mobile data plans etc.) a lot happier I would imagine.
Saturday, March 30, 2013 9:25:45 AM UTC
I take it that azure benefits is another one of the MSDN things that is allowed for production use, like Office? Windows etc. are only for development right?
Mark Adamson
Saturday, March 30, 2013 10:29:46 AM UTC
I remember that Clemens Vasters once said that cloud brings a kind of new economy in the SW development world. If you have 2 solutions delivered on a big box both can perform similarly good. But one of those can use a lot more resources because it is not optimized.

And the customer/owner doesn't see any difference in cost.

But if you are in a cloud the company that has more optimized solution has direct benefits (in $$$) if they have a more optimized solution.
Petar Repac
Saturday, March 30, 2013 11:48:47 AM UTC
Where is the database hosted? On the same VM?
Edward
Saturday, March 30, 2013 3:55:28 PM UTC
What about using a service like CloudFlare to distribute static content and cache it on their servers? Even their free edition would do that and you wouldn't have to mess about with a lot of small opimizations.
Saturday, March 30, 2013 4:36:49 PM UTC
Scott-- How did you handle the image loading on the RSS/ATOM feed side? Do not the image links in the feed still point to the image src?
Saturday, March 30, 2013 4:46:05 PM UTC
Client side sorting?

Look into http://listjs.com/
Peter
Saturday, March 30, 2013 11:11:49 PM UTC
I'm curious, hopefully this never happens to you or me, but what do you do in the scenario where someone tries to be malicious and through a DOS/DDOS or even a simple script keeps pulling down the images from your site?

It seems like someone would easily be able to spike your outgoing bandwidth leaving you with few options.

Option 1: price cap - however this would effectively shut down your site/sites

Option 2: IP blocking - is this possible with Azure (and can it be done dynamically)? Also, it does not protect the site if the malicious user detects this and switches their IP

Are there other options?
Bart
Sunday, March 31, 2013 12:24:01 AM UTC
Hi Scott,

Next optimization. Serve the images with long duration cache headers. That way a specific client browser instance will only request the image once.

Makes your site much snappier, will delight mobile users and anyone else who pays for incoming bandwidth, and reduces your outgoing bandwidth cost too.

Best article I've seen is here: http://blog.httpwatch.com/2007/12/10/two-simple-rules-for-http-caching/

- Richard
Sunday, March 31, 2013 9:20:52 AM UTC
Scott,

I don't think you can run a 100 websites on one VM. Either you're running out of memory running all of those side by side, or your warm up times make using those sites a pain.

Why not host your blog completely statically? I run my brother's photography website completely statically off S3/CloudFront, and keep the "content management" part on a VM where warm up times don't matter.
Dave Van den Eynde
Monday, April 01, 2013 12:26:28 AM UTC
Careful doing that with just one instance. When I done that I noticed that my site would go offline periodically for 10-15 minutes every so often (patches maybe?).
Daniel
Monday, April 01, 2013 7:05:20 AM UTC
"I have a MSDN Subscription which includes quite a bit of free Azure Cloud time ... This subscription is under my personal account and I pay if it goes over (I don't get a free pass just because I work for the cloud group) so I want to pay as little as possible if I can."

Bla bla bla... How stupid do you think are the ones who read your blog ???
msdn
Monday, April 01, 2013 8:46:54 AM UTC
@msdn firstly, why so mean? Secondly, Scott is making the point his azure web sites are for out of his pocket, not Microsoft as many probably asume.
Monday, April 01, 2013 9:01:16 AM UTC
I am also curious as to what happens if you're under a DDoS attack ? Do you get charged for this or is there some sort of a traffic analysis that would recognize such an event ?
Azure looks cooler and cooler everytime I read about it, it does look a little bit expensive at first, but I think all the cool stuff makes it worth.
Dimitar Dimitrov
Monday, April 01, 2013 10:33:05 AM UTC
MSDN & Tim - ya, not sure what that was about. Does he/she think we get unlimited azure time? I get zero for free. The sites I run are all moonlighting so the account is my personal account. I am not sure why that's controversial.

As for DDoS, yes I would need to hook up cloudflare or throttle the traffic if that happened.

Dave - yes, Jekyll or something like that would work also, but I consider aggressive caching to be close to running static. Great point though!

Edward - DB is either SQL compact or its in a DB in the same data center, so you're not charged for bandwidth between the site and DB.

Anil - yes, images (for now) are served normally in RSS.
Monday, April 01, 2013 1:10:40 PM UTC
" DOS/DDoS, "

very good point , I think azure should have max daily /monthly limit so that no one wake up to find he has a big bill waiting him there because some one consume his resources , it could be web spider .
Sam
Monday, April 01, 2013 3:00:48 PM UTC
Scott,

How are you handling your caching? Just doing ASP.NET Caching? Or something else?
Eric
Monday, April 01, 2013 5:30:09 PM UTC
It's silly of Microsoft not to give you some free Azure access. You're an MS employee, and through this blog you do a lot of free advertising for Azure. It's in the company's best interests to have you continue writing your blog and hosting your sites with Azure.
Sam
Monday, April 01, 2013 5:53:52 PM UTC
Off topic:

Have you ever heard complaints about ajax.aspnetcdn.com being blocked anywhere? We do parts catalogs for car dealerships and I used to use a script tag similar to your example:

<script src="//ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2.min.js" type="text/javascript"></script>

For some customers, inside their dealership the site didn't work. We tracked it down to ajax.aspnetcdn.com wasn't resolving or was outright blocked. Now we host jquery-x.x.x.min.js ourselves as a result.
Brian
Monday, April 01, 2013 11:54:21 PM UTC
Try using the Google PageSpeed service https://developers.google.com/speed/pagespeed/service. Since I started using it my Azure bandwidth dropped dramatically and the performance is superfast too :)
Tuesday, April 02, 2013 2:15:30 AM UTC
Hi Scott,

Just looking at the archives page on hanselminutes.com, you could further cut down on bandwidth by reusing the same 3 images once you hit show #248.

It looks like you're cycling through the same 3 images, but rendering each from a different URL which means browsers are going to request those images instead of using one from cache (as they would if you reused the images).
Bennor McCarthy
Tuesday, April 02, 2013 5:49:24 AM UTC
Eric - Yes, setting it in the web.configs for HTTP and using in-memory caching.

Brian - wow, NEVER heard that, but you can ask @damianedwards as he runs it

Salman - Thanks for the tip!

Bennor - That's true! I should, but soon I'll have unique images for all the shows. I'm doing it a little at a time.

Sam - Yes, but if it was free, it wouldn't really be the service that the public (you) use and I wouldn't have written this post! ;)
Tuesday, April 02, 2013 11:58:50 AM UTC
Indeed, interesting story - if you pay and see the numbers you think differently as you mentioned: if it would have been for free - we won't have seen this post - most probably.

There are different opinions to this topic. Personally I prefer the optimization base line idea - as this isn't only valid for your servers but also 'smart' clients on mobile networks - nonetheless the bandwidth is growing constantly there too.

I once heard (sorry no references and most probably its not valid anymore) at SAP people shouldn't think to much about memory or cpu power - as this may be just there. Which is kind of true if we look around for today's systems and networks. But if we look back, what people did achieve and still do within embedded systems with much less memory and bandwidth available - just imagine what we really could do with today's net, severs and clients. Amazing! (Curiosity may be a valid current example - even far away from a everyday web coders live - in some points.)

So: thanks for the post and thanks for highlighting how important optimization may and should still be - besides the pennies (and energy) it may safe in the long run.


Tuesday, April 02, 2013 3:15:28 PM UTC
Hi Scott,

Just a note to say the main site looks nice, but the way the blog posts flow at http://www.hanselman.com/blog is quite jarring (the background on the title of each post). I don't know how many people actually read your stuff that way rather than via RSS, etc.

Keep up the good work!
Jed
Tuesday, April 02, 2013 4:48:40 PM UTC
Scott,

I read your blog in a browser, but the podcast is always in my mobile phone.

When you changed the design my phone took a long time to load your site. Your optimizations will help not only your resource consumption but also me as the user. I personally prefer no pictures at all when I use is the phone.
Tuesday, April 02, 2013 7:11:33 PM UTC
Wow great new look for your website!
This article just got put in my +Pocket (which I learned about from you)
I can't wait to read this article since I had a bit of a bad experience the last time I tried to learn about some of the cloud services stuff out there.

I was doing a tutorial on Amazon AWS and got interrupted halfway through. A month later I got a bill for $150 :(
Thursday, April 04, 2013 3:04:44 PM UTC
Hey Scott, just noticed that your audio element on hanselminutes is preloading the mp3. How does this affect your amazon bill?

Clicking the comments link downloads it again. It looks funny in fiddler, cause when I load the page I see 3 simultaneous mp3 downloads, maybe there are multiple streams in IE or maybe it's just how fiddler works.

Curious what your thought's are with using preload=metadata? Would be nice to set an initial buffer size.
Martin
Thursday, April 04, 2013 5:12:51 PM UTC
Damien,

They block ALL CDN's here at my customer site, which as you can imagine is very frustrating since tons of sites fail to render at all. For example http://www.outlook.com does not render, IMO all sites should implement a failsafe that if the cdn fails to load your content you fallback to a local copy. There is javascript out there that does this that I implemented on my site, works decently enough.

Eric Malamisura
Thursday, April 04, 2013 5:35:44 PM UTC
Martin - Oops! My mistake. Changed to metadata. Thanks!
Friday, April 05, 2013 8:11:40 AM UTC
Hi Scott

Great blog post, I too am into penny-pinching when it comes to cloud-hosting, and I've done quite a bit of optimising over the years to keep my sites resource-efficient, and people will be quite surprised how much you can get out of a Small instance (hell I've got 2 production sites running on a XS instance - not busy sites mind ;-)).

I actually have a question about the MSDN benefits, I'm a VS Ultimate subscriber and we are looking to host our large government website in Azure, however I wanted to use my MSDN Azure subscription to set it up for testing, will my account allow me to use a Small VM instance (1) within the subscription for free? It says 1500 compute hours, but does that cover VMs? And if so, what size VM, it's a little confusing.

PS Liking the new site design btw

Thanks
Kev
Mantorok
Friday, April 05, 2013 8:23:09 AM UTC
Kev - This says a small, yes...it's "compute hours." http://www.windowsazure.com/en-us/pricing/member-offers/msdn-benefits/
Friday, April 05, 2013 10:38:13 AM UTC
Hi Scott

Thanks for clearing up, does having 1500 compute mean I could potentially have 2 x Small running for a month?

Kev
Mantorok
Friday, April 05, 2013 4:13:47 PM UTC
I'm not a pricing expert, but that sounds right.
Saturday, April 06, 2013 4:37:11 PM UTC
Great new site, nice work.

Out of interest, doesn't using lazyload affect the browser caching? On face value, you're saving on first visits, but losing on returns - or am I missing something?
Matt
Sunday, April 07, 2013 1:24:55 AM UTC
Matt - It *should* cache the imgs the same way. If they are already there, it should return a 301, not modified.
Monday, April 08, 2013 9:18:27 PM UTC
Hi Scott - Why aren't those images coming from Azure CDN? Am I missing anything here?
Girish
Monday, April 08, 2013 9:57:10 PM UTC
Girish - I haven't gotten that far, but it's only $0.06 a gig where they are so I'm not worried about it.
Wednesday, April 10, 2013 7:59:42 PM UTC
Hi Scott,
[hair splitting mode on]
301 is permanent redirect, not modified is 304
[hair splitting mode off]
Thursday, April 11, 2013 5:19:58 PM UTC
Stefan! - Good eye, thanks! :)
Thursday, April 11, 2013 11:45:18 PM UTC
10 WEBSITES IN 1 VM VS 10 WEBSITES IN SHARED MODE


This is something I've been wondering about for a while now. The number of websites I could run in the 1 VM is what has concerned me the most. I'm probably only ever going to have 5 - 10 sites. I'm interested where you got the info "running 1 Small VM on Azure with up to 100 websites". If I can see that on the Azure site then I will feel more comfortable giving it a go for my sites.
Tim Murphy
Friday, April 12, 2013 12:30:34 AM UTC
Tim - "Load balance up to 100 Web Sites across instances dedicated to your apps. Includes custom domain names, built-in FTP, Git, TFS, and Web Deploy support."

http://www.windowsazure.com/en-us/pricing/calculator/ click on Reserved tab.

Friday, April 12, 2013 1:10:18 AM UTC
Scott,

Thanks for the quick reply. I have been looking at Virtual Machines calculator, http://www.windowsazure.com/en-us/pricing/calculator/?scenario=virtual-machines, hence why I couldn't find the info.

Sorry to hit you with another question.

Do you get Remote Desktop access with Web Sites - Reserved? I will want to remote in to setup RavenDB.

If Web Sites - Reserved does not have a Remote Desktop then why not use Virtual Machines. The Small option has same CPU & RAM Web Sites - Reserved. I assume you don't get custom domain names, built-in FTP, Git, TFS, and Web Deploy support built in but that's not hard to implement.

Tim
Tim Murphy
Wednesday, April 17, 2013 4:29:56 PM UTC
Scott,

Is there any advantages to going with a small VM vs reserved websites? It looks like they are both a VM and their prices is within a few dollars of each other. Thanks!
Sunday, June 09, 2013 8:58:37 PM UTC

Howdy Scott,

So, last week (3 Jun 2013) ScottGu announced new pricing model for MSDN Subscriptions (see here). Some great improvements, but it does add some restrictions to our use of this Azure/MSDN Subscription offer. Looks to me that the new "Dev/Test" only model precludes the use of our Azure/MSDN Subscription offer from running production sites--is that right, Scott? That would mean we wouldn't be able to run, say, a virtual ASP.NET conference anymore? That's a real shame.

Cheers,

Jon
Jon Pawley
Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.