Most common Azure cost tools
Cost is always an important factor for your cloud project, whether you’re starting a greenfield cloud project or migrating an existing solution. Your idea might be brilliant, but nobody will build and maintain a solution that might never generate profit (or even takes too long to break even if subsequent profits aren’t spectacular). Your project feasibility study probably already includes an estimate to build, but hopefully also an estimate to host and maintain the solution. For Azure, hosting and running costs can be calculated by using the Azure Cost Calculator. This however starts from the premise that you have a rough idea of how you will build the solution (services used) and even how much data and traffic you will generate. If your solution fixes a specific problem then this might be easy to guesstimate, but it will be more challenging for startups etc.
If we ignore the cost to build and focus at the cost to host your solution, then most of the cost in Azure, and cloud in general, is operating expenses (OPEX). Some companies prefer CAPEX, other prefer OPEX, but one thing is sure: a monthly bill is right in the face and a recurring reminder of how much your solution costs the company. While this monthly bill is a good finger on the pulse, nobody wants to be surprised when costs are higher than expected. Luckily Microsoft provides us with Azure Cost Management tooling where you can track the cost during the month and intervene before the billing date. There’s even the option to set budget alerts so you don’t have to check the graphs on a regular base. This to make your life a lot easier, but also because incorrect usage of cloud can cost a lot of money very fast. One could easily burn a few thousand dollars in a matter of hours or even minutes.
But this still leaves us unsure between rough upfront guesstimates in the Cost Calculator, in which you might have forgotten hidden costs, and an actual running cost months or possibly years later, at which point its very costly to rebuild part of the solution.
Defining the cost problem
Every problem has multiple solutions, one better than the other. The same counts for Azure services available to solve part of your problem, each with their own cost. And sometimes you’ll take the best possible fit, but often you’ll take the best fit … at a certain cost. During your architectural design you will have to take cost into account as well and this brings us back to the Azure Cost Calculator mentioned above to make the first rough decisions.
For one of my customers I took this approach and listed all possible Azure services solving the problem and started eliminating those that were a less than optimal fit and those costing a multiple of another solution while not bringing the extra added value to justify this price bump. In the end there were two possible implementation scenarios left and I tried to calculate a total cost for both. There were however a few uncertainties left, some of them which could have a huge impact on the total cost. One of them is the transaction cost on Azure Blob Storage, which handled incorrectly could triple the overall cost on its own due to the large volumes the solution had to handle.
So my initial calculation included both worst-case and more cost-efficient version of that specific solution. With the note that testing the cost should be one of the very first tasks during the architectural design phase, to validate as it decided if this option was still viable or whether we had to fall back to the second option.
Validating cost assumptions during design phase
So how does one test cost assumptions during design phase? Well it can be quite simple as Azure already provides us the tools in Cost Management. First of all we need to use the services we want to assess, which can easily be done with a throw-away proof-of-concept (PoC). In said problem, I created an Azure Function that writes and reads from Azure Blob Storage. Since it’s a PoC, you can (and should) cut corners to win time: hardcode connection strings, start with e.g. an easy HTTP trigger which takes away the need to create a file upfront and right-click deploy (or even run locally).
For the function I only validated if I could trigger multiple functions in parallel and if they could handle large files without running out of memory (hint: don’t read the whole file into memory). The cost part of these functions I had covered by making valid assumptions in duration and amount of executions. As mentioned before, it was the amount of transactions on Azure Blob Storage that were the unknown factor.
To validate my cost of Azure Blob Storage I created a storage account for each scenario I wanted to test: storage tiers, different SDK calls, compressed vs uncompressed, streaming options, … This is an important step as it will allow us to correctly compare the options. The next step is to open up the Azure Cost Calculator or go to the service’s price documentation and start calculating the volumes (size, time, transaction count, …) which will give you a noticeable cost, but of course without breaking the bank.
Looking at Azure Blob Storage pricing we can see that for a given configuration (LRS, Hierarchical Namespace in West Europe) write operations in Hot tier will cost us €0.0617 per 10K and read operations €0.0053.
If writing/reading a file line by line triggers a transaction for each line, writing 1 millions lines would give us approximately €6.17 in transaction costs for writing and €0.53 for reading. If our code is less efficient, we’ll pay more and if it’s more efficient through e.g. buffering it will cost us less. Tune the numbers until you reach a cost large enough to see a difference (e.g. difference between 1 and 2 cents can’t be used as correct measure).
Execute the different options you want to test, each on their own service copy and come back the next day (as it takes some time for metrics to propagate, I took 24h to be sure). Open up Cost analysis on the resource group (or subscription) where your service lives and modify the view on top from Accumulated costs to Cost by resource.
Find the resources you’re testing against in the grid and open the drill down for details. Below are the details for one of the storage accounts I tested against and which shows that the Azure SDK optimizes file access by default, reducing the amount of worst-case transactions in my case by a factor of 2,000 (validated by App Insights) and resulting in <€0.01 for the write operations.
You can redo the same test with new volumes to verify your conclusions if necessary.
Writing this blog post took almost longer than creating a small PoC to validate my cost assumptions and possibly show hidden costs I forgot to add in the Azure Cost Calculator.
This specific scenario was executed in the first week of the project, saving the customer over €100,000 per year in possible storage transaction costs when done incorrectly or at least similar costs in refactoring part of the solution after getting a first invoice once deployed to production.
Thanks to the effect of this exercise, the customer added ‘cost testing’ with noticeable volumes as part of the acceptance criteria for each sprint delivery and I’ll be promoting the same exercise at other customers.