Azure Functions is Microsoft's serverless compute service. You write code that responds to events — an HTTP request, a message arriving in a queue, a file uploaded to Blob Storage — and Azure handles all the infrastructure: provisioning servers, scaling to handle load, and shutting down when idle. You pay only for the time your code actually runs. This model is ideal for event-driven workloads, background jobs, scheduled tasks, and APIs with unpredictable traffic.
Hosting Plans
Azure Functions can run on three hosting plans, each with different cost and scaling behavior:
- Consumption Plan: True serverless. Scale from zero to thousands of instances automatically. Pay per execution and execution time. Free grant of 1 million executions per month. Cold start latency on the first invocation after idle.
- Flex Consumption Plan (Preview): Consumption model with always-ready instances to eliminate cold starts. More predictable performance.
- Premium Plan: Pre-warmed instances (no cold starts), VNet integration, unlimited execution duration. Higher base cost.
- Dedicated (App Service) Plan: Runs on VMs you already pay for. Good when you need functions alongside a web app on the same plan.
For most use cases, start with the Consumption Plan — the free grant covers enormous traffic volumes and the automatic scaling is unmatched.
Creating a Function App
A Function App is the container for one or more individual functions. It shares a storage account, application settings, and scaling configuration across all functions inside it.
# Create prerequisites
az group create --name rg-functions-demo --location eastus
az storage account create
--resource-group rg-functions-demo
--name stfuncsdemo2026
--sku Standard_LRS
# Create a Python 3.11 Function App on Consumption plan
az functionapp create
--resource-group rg-functions-demo
--consumption-plan-location eastus
--runtime python
--runtime-version 3.11
--functions-version 4
--name funcapp-demo-2026
--storage-account stfuncsdemo2026
--os-type linux
Writing Your First HTTP-Triggered Function
Install the Azure Functions Core Tools locally to develop and test functions before deploying:
# Install Azure Functions Core Tools
npm install -g azure-functions-core-tools@4
# Initialize a new Python function project
func init myproject --python
cd myproject
# Create an HTTP-triggered function
func new --name HttpHello --template "HTTP trigger" --authlevel anonymous
The generated function_app.py (Functions v2 model) looks like this:
import azure.functions as func
import logging
app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)
@app.route(route="HttpHello")
def HttpHello(req: func.HttpRequest) -> func.HttpResponse:
logging.info("HTTP trigger function processed a request.")
name = req.params.get("name") or "World"
return func.HttpResponse(f"Hello, {name}!", status_code=200)
# Run locally
func start
# Test it
curl "http://localhost:7071/api/HttpHello?name=Azure"
Triggers and Bindings
Triggers and bindings are Azure Functions' superpower — they connect your code to Azure services with minimal boilerplate:
- HTTP Trigger: Invoked by an HTTP request. Returns an HTTP response. Used for APIs and webhooks.
- Timer Trigger: Runs on a CRON schedule. Example:
0 0 * * * *runs every hour. - Blob Trigger: Fires when a file is created or modified in a Blob Storage container.
- Queue Trigger: Processes messages from an Azure Storage Queue or Service Bus Queue.
- Event Grid Trigger: Responds to Azure events (VM created, resource deleted, etc.).
- Cosmos DB Trigger: Fires when documents are inserted or updated in a Cosmos DB container.
Input and output bindings let you read and write to services (Blob Storage, Cosmos DB, Service Bus) without writing SDK connection code — you declare the binding in code and Azure injects the data.
Deploying to Azure
# Deploy the local project to the Function App
func azure functionapp publish funcapp-demo-2026
# Stream live logs from the deployed function
func azure functionapp logstream funcapp-demo-2026
Durable Functions: Stateful Workflows
Durable Functions extend Azure Functions with stateful, long-running workflow patterns. The orchestrator pattern is most common:
- Orchestrator function: Defines the workflow sequence using
yield context.call_activity(). - Activity functions: Individual units of work called by the orchestrator (send email, process image, call API).
Durable Functions handle retries, timeouts, and checkpointing automatically — the orchestration survives VM restarts because its state is persisted to Azure Storage.
Application Settings and Key Vault Integration
# Set environment variables for the Function App
az functionapp config appsettings set
--resource-group rg-functions-demo
--name funcapp-demo-2026
--settings
ENVIRONMENT=production
COSMOS_ENDPOINT="https://mycosmosaccount.documents.azure.com:443/"
# Reference a Key Vault secret directly in settings
# Format: @Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/MySecret/)
az functionapp config appsettings set
--resource-group rg-functions-demo
--name funcapp-demo-2026
--settings "API_KEY=@Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/APIKey/)"
Key Takeaways
Azure Functions is the ideal compute model for event-driven, intermittent, or unpredictable workloads. The Consumption Plan scales automatically and costs almost nothing for moderate traffic. Master triggers and bindings to connect your functions to the rest of your Azure environment with minimal code, and use Durable Functions when you need to coordinate multi-step workflows with state.