If you're like myself, my first naïve attempt at a small indy cloud app was burning money faster than a bachelor party in Vegas. Here are a few tips that can save you big on your cloud apps:
- If you already have a redundant data solution store your data on-premesis
You may already be at a small company with a data backup solution with associated infrastructure and such. One thing you may notice is that cloud data isn't super cheap. 1TB of locally redundant data may cost you upwards of $70/mo and even more for geo-redundant. If you already have your own storage infrastructure in place it may make more sense for you to use Azure cloud storage as sort of a temporary buffer, not a final storage place and then pull the data down on-premises.
Otherwise just be very mindful about what you store in the cloud and understand if you need to be able to access that data readily, from anywhere.
- Pay close attention to your VM sizes for Worker/Web Roles
The most expensive thing in the cloud are compute hours. When you create a cloud service in Visual Studio, adding a worker/web role will default to a Small VM size. What it doesn't tell you is that this Small VM will set you back about $70 bucks a month.
Try out an Extra Small VM for size see if that fits your services needs and move up as appropriate.
Did you know, that a Small VM (2ghz, 1.75gb memory) cost about $70/mo vs an Extra Small at about $30/mo?
- Combine worker roles into a single role instance
You shouldn't think of Azure worker roles as a single task in your app. Remember, each role => 1 VM and VMs aren't cheap! By default your starting code for a Worker role is really setup to do only one task forever:
Don't do this!
Having a single task that your worker leads to either a monstrously large and unorganized task or a worker for each simple task.
Instead, do this:
Sub-divide the worker role instance. Create an interface, call it IWorkerRole with a few interfaces to start, stop and run a subworker.
Now, implement this interface for however many (sub)workers you want like below:
In my example I have ProcessingWorker1, ProcessingWorker2 and ProcessingWorker3. You can imagine these things can be doing things such as caching, listening to a service bus or cleaning up a database.
*Note: Be sure to catch all exceptions (and report them to an error log trace) at the base of every OnRun() on the processing worker. If you don't do this, any one processing worker will take down the rest, putting a halt to any work until the entire instance restarts.
Get the full template starter project here: https://github.com/sedouard/MultiWorkerRole