How does azure functions measure the GBs for billing?

Viewed 520

When running on consumption load in azure functions, how do they actually calculate the billable units?

Is it part of the SDK and events/timings are measured? Is it the host that profiles the CPU? Does it profile CPU and Memory every sec and store that? Average it?

I have not found any resources that talk about how it's actually measured.

I ask because it's possible to run code outside the context of "events" and would be nice to know how it's billed/measured.

1 Answers

This page: Consumption Plan Cost Billing FAQ has some details on the metrics involved but it doesn't disclose the actual calculation.

Once you take into account that memory usage can change over time, the calculation is best described as the integral of memory usage over time. The system does this calculation by sampling the memory usage of the process (and child processes) at regular intervals. As mentioned on the pricing page, memory usage is rounded up to the nearest 128 MB bucket (so if your process is using 160 MB you are charged for 256 MB). This process of calculating memory usage and rounding up takes concurrency (multiple concurrent function executions in the same process) into account.

They recommend using performance counters on the App Service for your own metrics so perhaps that is used for billing as well? Perhaps Paul Batum can share some insights?

Because Function Execution Units are a combination of execution time and your memory usage, they are not a great metric to use when you're only trying to understand just your memory usage (and potentially optimize your app to use less memory). For this we recommend using the performance counter data collected by App Insights when you enable it for Azure Functions. You can then access this data using the App Insights Analytics portal by running the following query:

performanceCounters
    | where name == "Private Bytes"
    | project timestamp, name, value, cloud_RoleInstance

Apparently the performance counter is incorrect in some cases as described in this GitHub issue.

Related