AZ-104
Deep Dive
Azure Functions is Azure's serverless platform: you run code on demand without managing infrastructure. The AZ-104 mainly tests hosting plans, common triggers, and the difference from other compute services.
Contents
Azure Functions lets you run small pieces of code (functions) in response to events, without provisioning or managing servers. It's Azure's serverless service — you pay only for actual executions.
Event-driven
They run in response to events: HTTP request, message in a queue, new blob, timer, etc.
Serverless
You don't manage VMs or App Service Plans (in Consumption). Azure scales automatically from 0 to N instances.
Pay-per-execution
On the Consumption plan: you pay per number of executions and CPU time. 1M executions/month free.
Supported languages (runtime v4)
The hosting plan determines scaling, cost, and available features. It's one of the most heavily tested concepts about Functions on the AZ-104.
| Plan | Scaling | Cold Start | Max timeout | VNet Integration | Cost |
|---|---|---|---|---|---|
| Consumption | 0 → unlimited (automatic) | ⚠️ Yes | 5 min (configurable up to 10 min) | ❌ No (egress only via VNet triggers) | Per execution + GB-s |
| Flex Consumption | 0 → 1000 instances (automatic, granular) | ⚠️ Reduced | 30 min | ✅ Yes (ingress and egress) | Per active instance-second |
| Premium (EP1/EP2/EP3) | Manual + automatic. Pre-warmed instances. | ✅ No cold start | Unlimited | ✅ Full | Per instance/hour (always on) |
| Dedicated (App Service) | Manual. Shares instances with App Service. | ✅ No cold start | Unlimited | ✅ Full | Per App Service Plan |
Consumption
Sporadic workloads. Tight budget. You don't need VNet or long-running executions.
Premium
Cold start is critical to avoid. You need VNet Integration. Long-running executions. Predictable traffic.
Dedicated
You already have an underutilized App Service Plan. You want always-on at controlled cost.
A trigger defines the event that activates the function. Each function has exactly 1 trigger.
| Trigger | When it fires | Example use |
|---|---|---|
| HTTP Trigger | HTTP GET/POST/etc. request (it's an API/webhook) | Serverless REST API, third-party webhooks |
| Timer Trigger | CRON expression: "0 */5 * * * *" (every 5 min) | Periodic cleanup jobs, automated reports |
| Blob Trigger | New blob in a container or modification of an existing blob | Processing images on upload, transforming CSV data |
| Queue Trigger (Storage) | New message in an Azure Storage Queue | Asynchronous processing, worker patterns |
| Service Bus Trigger | Message in a Service Bus Queue or Topic/Subscription | Enterprise integration, guaranteed messaging |
| Event Hub Trigger | Event in an Azure Event Hub (massive streaming) | IoT telemetry, real-time log analytics |
| Event Grid Trigger | Azure Event Grid event | Reacting to changes in Azure resources (blob deleted, VM stopped) |
| CosmosDB Trigger (Change Feed) | Change in CosmosDB documents | Syncing data, invalidating cache |
Bindings are declarative connections to external services. They're defined in function.json(or via attributes in C#/Python). They avoid writing manual connection code.
Input Binding
Reads additional data when the function runs. E.g.: reading a blob or a CosmosDB row when an HTTP request comes in.
Trigger
The event that activates the function. It's a special type of binding. Each function has exactly 1 trigger.
Output Binding
Writes data when the function completes. E.g.: sending a message to a Queue, writing to CosmosDB, calling another service.
// function.json — HTTP trigger + Blob output binding
{
"bindings": [
{
"type": "httpTrigger", // Trigger
"direction": "in",
"authLevel": "function",
"methods": ["post"]
},
{
"type": "http", // HTTP output (response)
"direction": "out",
"name": "$return"
},
{
"type": "blob", // Output binding: writes a blob
"direction": "out",
"name": "outputBlob",
"path": "output/{rand-guid}.json",
"connection": "StorageConnectionString"
}
]
}Durable Functions is an extension of Azure Functions that lets you write stateful workflows in a serverless environment. It solves the problem of coordinating multiple functions with state.
Orchestrator Function
Coordinates the execution of activity functions. Defines the flow: sequential, parallel, conditional. It should have no direct I/O — everything goes via await ctx.callActivity().
Activity Function
Individual unit of work. Performs the actual task (calling an API, processing data, writing to a DB). No state of its own — the orchestrator manages the state.
Entity Function (Grain)
Represents a stateful object that persists between invocations. Lets you model actors or entities with mutable state.
Client Function
Starts, terminates, sends events to, or queries the state of an orchestration. Can be any type of trigger (HTTP, Queue, etc.).
Common Durable Functions patterns
| Aspect | Azure Functions | App Service | Logic Apps |
|---|---|---|---|
| Model | Serverless / Microservice | PaaS, full app | Serverless visual workflow |
| Code | Your own code (C#/Python/JS) | Full custom code | No-code / low-code |
| Execution | Event-driven, short-lived | Always-on, request-response | Event-driven, workflow steps |
| State | Stateless (Durable for stateful) | Stateful | Stateful (workflow state) |
| Scaling | Automatic (Consumption) | Manual / auto-scale | Automatic |
| Minimum cost | Free (1M executions/month) | Plan B1: ~$13/month | Per action: ~$0.000025/action |
| Best for | Micro-tasks, serverless APIs, integration | Web apps, full REST APIs | System integration, no-code orchestration |
On the Consumption plan, when a function hasn't been invoked recently, its instance is deactivated. The next invocation suffers a cold start: the time it takes to spin up the instance before running the code.
Factors that affect cold start
Cold start mitigations
Scaling in the Consumption Plan
Azure scales automatically from 0 up to 200 instances (per plan) based on load. Scaling happens per Function App, not per individual function. All functions within the same Function App share the same instances.
Consumption plan doesn't support VNet Integration (inbound)
On Consumption, functions don't have VNet Integration for inbound traffic — you can't expose a function on a private VNet. For private access you need Premium Plan or Dedicated (App Service). Consumption can access services in a VNet via Virtual Network triggers in some cases.
Consumption plan timeout is 5 minutes by default (10 min max)
On Consumption, the default timeout is 5 minutes, configurable up to 10 minutes. Premium and Dedicated have no timeout limit. If your function takes longer than 10 minutes on Consumption, it will fail — use Premium or Durable Functions.
Each function has exactly 1 trigger, but can have multiple bindings
A trigger activates the function. Input/output bindings are additional. You can have: 1 HTTP trigger + 1 Blob input binding + 2 output bindings (Queue + CosmosDB). You cannot have 2 triggers on the same function.
Premium Plan eliminates cold start but is NOT "free"
Premium Plan has pre-warmed instances that eliminate cold start. However, you always have at least 1 active instance, so the minimum cost is that of that instance (approx. $175+/month for EP1). There is no option to scale to 0 on Premium.
Did you get this topic?
Test what you just learned
A company has an Azure Function with an HTTP Trigger that processes critical orders and cannot tolerate cold starts. The function needs to access resources in a private VNet. It's currently on the Consumption plan. Which hosting plan is correct?
Put what you learned to the test with original AZ-104 exam questions.
Start AZ-104 mock examUnlimited mock exams with the Pro plan
Log in to track your progress.