The setup of always running functions with Premium plans consists of two steps:
Note #1: There are two similar-looking properties minimumElasticInstanceCount
(= always ready instances) and preWarmedInstanceCount
(= pre-warmed instances) - see according explanation on MSDN.
Note #2: You can achieve a similar availability behaviour by using a dedicated App Service plan as used for regular Web Apps and then set the property alwaysOn
to true. See this documentation for more details. With that approach you’re losing the “serverless” manner and need to define scaling by your own.
Often the decision for premium plan instead of the regular consumption plan is just because of the cold start behaviour. The cost impact is considerable, not only is the “Free Grant” (1 million requests per month) lost, the always on behaviour also generates minimal costs of ~ 130 CHF/month. Details to pricing of Function Apps see here: https://azure.microsoft.com/en-us/pricing/details/functions A great and simple alternate may be to deploy an Application Insights Availability Test which calls the Function every 5 minutes and may with that keep it alive and responsive (without consuming too much resources).
Snippet: appinsights-classic-standard-availability-test-with-alert-rule
Or “quick & dirty” snippet for a classing PING test (without costs):
var availabilityTestDisplayName = 'Status API'
var availabilityTestShortName = 'status'
var availabilityTestName = '${resourceNamePrefix}-${toLower(availabilityTestShortName)}-at-${resourceNameSuffix}'
var availabilityTestUrl = uri('https://${apiFuncName}.azurewebsites.net', 'api/status')
var availabilityTestFrequencySeconds = 300
var availabilityTestTimeoutSeconds = 120
resource availabilityTestRes 'microsoft.insights/webtests@2022-06-15' = {
name: availabilityTestName
location: resourceLocation
tags: {
'hidden-link:${appInsightsRes.id}': 'Resource'
}
properties: {
SyntheticMonitorId: availabilityTestName
Name: availabilityTestDisplayName
Enabled: true
Frequency: availabilityTestFrequencySeconds
Timeout: availabilityTestTimeoutSeconds
Kind: 'ping'
RetryEnabled: true
Locations: [
{
Id: 'emea-nl-ams-azr' // West Europe
}
{
Id: 'emea-fr-pra-edge' // France Central
}
{
Id: 'emea-ru-msa-edge' // UK South
}
{
Id: 'emea-gb-db3-azr' // North Europe
}
{
Id: 'emea-ch-zrh-edge' // France South (Formerly France Central)
}
]
Configuration: {
WebTest: '<WebTest Name="${availabilityTestDisplayName}" Enabled="True" CssProjectStructure="" CssIteration="" Timeout="${availabilityTestTimeoutSeconds}" WorkItemIds="" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010" Description="" CredentialUserName="" CredentialPassword="" PreAuthenticate="True" Proxy="default" StopOnError="False" RecordedResultFile="" ResultsLocale=""><Items><Request Method="GET" Version="1.1" Url="${availabilityTestUrl}" ThinkTime="0" Timeout="${availabilityTestTimeoutSeconds}" ParseDependentRequests="False" FollowRedirects="True" RecordResult="True" Cache="False" ResponseTimeGoal="0" Encoding="utf-8" ExpectedHttpStatusCode="200" ExpectedResponseUrl="" ReportingName="" IgnoreHttpStatusCode="False" /></Items></WebTest>'
}
}
}