An Azure service that provides customers with a serverless container experience.
The current evidence does not establish an OOM kill; enable scale-controller logs, correlate each timer InvocationId with instance-level memory and lifecycle events, and use Azure support when no customer-visible signal supplies a termination reason.
1. Capture worker lifecycle evidence
Enable verbose scale-controller logging temporarily:
az functionapp config appsettings set \
--name <FUNCTION_APP_NAME> \
--resource-group <RESOURCE_GROUP_NAME> \
--settings SCALE_CONTROLLER_LOGGING_ENABLED=AppInsights:Verbose
Verbose logs record reasons for scale-controller worker-count changes and are written under ScaleControllerLogs; this feature is preview and increases telemetry cost, so disable it after capturing the problem ^1^.
Query count changes:
traces
| extend d = todynamic(tostring(customDimensions))
| where d.Category == "ScaleControllerLogs"
| where message == "Instance count changed"
| project timestamp,
Reason=tostring(d.Reason),
Previous=tostring(d.PreviousInstanceCount),
Current=tostring(d.CurrentInstanceCount)
| order by timestamp asc
This identifies scaling decisions, but it is not documented as a complete termination ledger for OOM, host faults, maintenance, or infrastructure replacement.
For each unexplained replacement:
- Function App → Diagnose and solve problems.
- Run Function App Down or Reporting Errors (Preview) for the affected interval. It checks startup/offline history, deployments, scaling, high memory/CPU, host health, and stuck executions ^2^.
- Query
AzureActivityfor start, stop, write/configuration, and trigger-sync operations. These are control-plane records, not evidence of every platform recycle ^3^. - If neither diagnostics nor telemetry supplies a cause, open an Azure support case with UTC timestamps, region, app name,
cloud_RoleInstance, deployment IDs, and invocation IDs. A definitive host/container termination reason may require platform-side evidence unavailable to the app.
2. Distinguish interruption from missing telemetry
Excluding Request from sampling is necessary but not sufficient. Host.Results produces invocation records in requests, and it must remain at Information; setting it to Error records only failed invocations. Function start/completion traces also require the Function category at Information ^4^.
Use:
{
"logging": {
"logLevel": {
"default": "Warning",
"Host.Results": "Information",
"Function": "Information",
"Worker": "Information"
},
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request;Exception"
}
}
}
}
Verify actual sampling rather than assuming all trace/checkpoint records survived:
union requests, dependencies, exceptions, traces
| where timestamp between (datetime(<START_UTC>) .. datetime(<END_UTC>))
| summarize RetainedPercentage=100/avg(itemCount)
by itemType, bin(timestamp, 5m)
A value below 100 means that telemetry type was sampled ^5^.
Correlate one timer execution by InvocationId:
let invocation = "<INVOCATION_ID>";
union traces, requests, exceptions, dependencies
| where tostring(customDimensions["InvocationId"]) == invocation
| project timestamp, itemType, operation_Id, cloud_RoleInstance,
message, name, success, resultCode, customDimensions
| order by timestamp asc
Every invocation has an InvocationId; operation_Id correlates the wider logical operation ^6^.
Interpretation:
- Start and checkpoint records, followed by a normal
requestsresult: completed invocation. - Start/checkpoints but no completion or
Host.Results, coincident with instance disappearance or host shutdown: consistent with interruption, but not proof of OOM. - Missing traces while the request result exists and trace retention is below 100%: telemetry loss is more likely.
- No records anywhere: cannot distinguish “never triggered” from loss without an external durable audit record.
3. Interpret NoScriptHost and HTTP/2 faults
NoScriptHost means the health check found no available script host; it does not identify why. Investigate adjacent startup, storage, deployment, and worker logs.
The EventStream HTTP/2 fault can occur during normal shutdown when the language worker exits before its gRPC channel closes gracefully; maintainers describe this as noisy shutdown telemetry rather than proof of an application networking failure ^7^. Associate it with a timer only when the same timestamp, cloud_RoleInstance, operation_Id, or InvocationId overlaps that execution. Otherwise treat it as host/worker lifecycle evidence, not the timer’s exception.
4. Measure total instance memory
Use Function App → Monitoring → Metrics:
- Metric: Memory working set and Average memory working set
- Split/filter by: Instance
- Add Automatic Scaling Instance Count
- Use the smallest available time grain around each replacement
These Flex Consumption metrics represent app-level memory and can be filtered per instance ^3^. Python RSS omits the Functions host and other processes. A 512-MB instance also has a separate 272-MB platform buffer, while function code and the host share instance resources ^8^.
5. Profile without risking the five-minute production timer
Do not deploy memory-profiler to the production app; Microsoft explicitly limits it to development environments ^9^.
Instead:
- Clone the app into an isolated staging/canary Function App.
- Replay production-shaped dashboard and hourly chart inputs repeatedly.
- Decorate internal synchronous processing functions—not the trigger entry point—with
@memory_profiler.profile. - Compare line-level increments across successive invocations.
- Separately capture Python
tracemallocsnapshot deltas around logical phases to identify allocation tracebacks. - Test suspected fixes under the same sequence and concurrency.
For immediate reliability while investigating, make each refresh idempotent and write start/phase/commit records to external storage. Timer retries only act on uncaught exceptions, and a timer retry does not resume on a new instance after instance failure ^10^. If 512 MB remains too tight, temporarily test 2,048 MB—Microsoft recommends that size for most Flex workloads—without treating the improvement as proof of an OOM root cause ^8^.
References
- How to configure monitoring for Azure Functions
- Troubleshoot Azure Functions app down or reporting errors
- Azure Functions monitoring data reference
- How to configure monitoring for Azure Functions
- Troubleshoot Azure Monitor Application Insights logs in Azure Functions
- Analyze Azure Functions telemetry in Application Insights
- Host can log a grpc ConnectionAbortedException during normal ... - GitHub
- Azure Functions Flex Consumption plan hosting
- Profile Python apps memory usage in Azure Functions
- Azure Functions error handling and retries (programming-language-javascript)