Recommend a Serverless-Based Solution — Lesson
AZ-305 › Unit 4: Design infrastructure solutions › Design compute solutions › Recommend a serverless-based solution
Recommend a Serverless-Based Solution — Lesson
A fintech team builds a webhook receiver for a payment provider. Volume is bursty — silent for hours, then events in two minutes when reconciliation runs. The team originally builds it on a 2-instance App Service plan (/month, always on). The bill is fine, but the architect asks two questions during review: "What happens when reconciliation overlaps with a partner integration burst?" and "Why are you paying $24/7 for a workload that runs 4 hours a day?". A redesign onto `Azure Functions` Consumption plan cuts the bill to $$\sim $3/month and removes the capacity-overlap risk entirely. The Functions plan handles a 50{} burst without intervention. This lesson is about choosing serverless deliberately, configuring the right plan, and avoiding the traps that turn a $3$300$ surprise.
We will work through Azure's serverless story the way the AZ-305 exam expects you to: distinguishing Azure Functions plans (Consumption, Premium, Flex Consumption, Dedicated/App Service), comparing Logic Apps Consumption vs Standard, and integrating these with Container Apps consumption mode for hybrid serverless designs. Reference: the AZ-305 exam study guide, particularly Chapter 4 Skill 4.1 on serverless solutions and the Azure Functions plan documentation.
Why This Matters
Serverless is the cheapest model for sparse, event-driven workloads — but it has cliffs. Pick the wrong Functions plan, and your daily events run fine while the -event spike during quarter-end fails with cold starts. Use a Consumption-plan function for a workload that runs 1 hour every minute, and you pay 30% more than a Dedicated plan would have cost. The AZ-305 exam tests this LO because serverless is the place where pricing-shape mistakes cost the most relative to the workload's importance.
The career payoff is concrete: every CFO who scrutinises a cloud bill asks about serverless adoption, every "modernise this batch job" workshop reaches for Functions, and every webhook receiver or scheduled-job rewrite ends up here. If you can match a workload's burst shape, latency requirements, and runtime needs to the right Functions plan (Consumption vs Premium vs Flex), pick Logic Apps Consumption vs Standard correctly, and recognise when Container Apps consumption mode is the better serverless answer than Functions, you will pass this slice of the exam and design serverless like a senior architect.
Prerequisites
Before working through this lesson, make sure you can answer each prompt below in one or two sentences.
- Cold start basics. Can you explain what a cold start is and roughly how long it takes on each plan? — Self-check: which plan has near-zero cold start?
- Trigger types. Are you familiar with HTTP, Timer, Queue, Service Bus, Event Hub, Blob, and Event Grid triggers? — Self-check: which trigger is push vs pull?
App Service planbasics. Do you understand the plan-app relationship? — Self-check: how many functions can share one plan?Logic Appsworkflows. Have you seen the visual designer and connectors model? — Self-check: what is the difference between a managed and an in-app connector?- Concurrency models. Are you familiar with single-instance multi-execution vs scale-out concurrency? — Self-check: which is the default for HTTP Functions?
If any of these feels shaky, pause and review the Functions and Logic Apps intro modules in Unit 4 of the AZ-305 guide before continuing.
Learning Objectives
By the end of this lesson, you will be able to:
- Analyse a workload's burst shape, latency requirements, and runtime needs to determine if serverless is the right family.
- Evaluate trade-offs between
FunctionsConsumption, Premium, Flex Consumption, and Dedicated (App Service) plans for a given workload. - Choose between
Logic AppsConsumption (multi-tenant, pay-per-action) and Standard (single-tenant, predictable) for an integration workflow. - Design a serverless topology that bridges Functions, Logic Apps, and
Container Appsjobs across event-driven and scheduled work. - Recognise common cliffs — Consumption-plan 10-minute cap, cold-start latency on user-facing APIs, throttled Storage account behind a Function — and design around them.
- Configure identity (managed identity), networking (VNet integration, private endpoints), and observability (Application Insights) for serverless workloads.
Building Blocks
Read this section as a glossary. Each term follows the same shape: an everyday analogy, a formal definition, then the reason it matters for the exam.
Serverless compute — A model where the cloud provider runs the user's code without exposing the host. Like a vending machine: you press a button, you get the snack, you do not see the warehouse. Formally, an execution environment that scales transparently with demand and bills per request, per second, or per resource-second of execution. It matters because serverless is the cheapest model for sparse / event-driven workloads — its niche is well-defined.
Functions trigger — The event that causes a function to execute. Formally, an attribute that binds a function method to a source — HTTP request, queue message, timer, blob upload, Event Grid event, etc. It matters because the trigger drives scaling: HTTP triggers scale on concurrency; Queue triggers scale on queue depth; Timer triggers do not scale.
Functions Consumption plan — The original Functions pricing model: no idle cost, pay only for execution seconds and invocations. Formally, a plan that runs functions on multi-tenant infrastructure with auto-scaling to thousands of instances; max execution 10 minutes per invocation. It matters because Consumption is the right default for sparse and bursty workloads.
Functions Premium plan — A Functions plan with pre-warmed instances, VNet integration, and longer max execution. Formally, a plan with always-ready instances ( pre-warmed), VNet integration, and 60-minute (or unlimited with config) max execution. Higher cost than Consumption. It matters because user-facing APIs need pre-warmed instances to avoid cold starts.
Functions Flex Consumption — The newer Functions plan combining Consumption-style pricing with Premium-style features. Formally, a plan that supports per-invocation always-ready instances, VNet integration, and large instance memory, billed per-second. It matters because it bridges the Consumption/Premium gap and is increasingly the recommended default for new workloads (since GA in 2024).
Logic Apps Consumption — Multi-tenant Logic Apps with pay-per-action billing. Formally, runs in a shared Microsoft-operated environment, billed per action and per connector call. It matters because it is the right answer for low-volume integrations — typical bills are /month.
Logic Apps Standard — Single-tenant Logic Apps with predictable pricing. Formally, runs on an App Service plan (or WS1 plan), with VNet integration, source control, and stateful or stateless workflows. It matters because it is the right answer for higher-volume / production integrations where Consumption's per-action pricing would be unpredictable.
Connector — A pre-built integration with an external service. Like an electrical adapter for a foreign plug. Formally, a Logic Apps / Power Automate connector exposes a service's API as discrete actions and triggers (Salesforce, SharePoint, Teams, etc.). It matters because connectors are the value proposition of Logic Apps — they save weeks of custom integration code.
Container Apps consumption mode — A serverless mode of Azure Container Apps where containers scale to zero and bill per-second. Formally, the default scaling mode of ACA with minReplicas: 0. It matters because it is a serverless alternative to Functions for workloads packaged as containers — relevant when the team prefers containers to Functions runtimes.
Cold start — The latency a serverless invocation incurs when no warm instance exists. Formally, the time between request arrival and first byte of response when the platform must allocate, provision, and initialise a new worker. Consumption: ms typical (language-dependent). Premium / Flex with pre-warm: ms. It matters because user-facing APIs cannot tolerate Consumption cold starts; background processing usually can.
Deep Dive
1. The four Azure Functions plans
Functions runs on four distinct plans. Choosing the right plan is the heart of this LO.
| Plan | Cold start | Max execution | VNet integration | Pricing | Best for |
|---|---|---|---|---|---|
| Consumption | ms | 10 minutes | Not supported | Per-GB-second + invocations | Sparse / bursty / no-VNet workloads |
| Premium | ms with pre-warm | 60 minutes (unlimited config) | Yes | Per-instance-hour | User-facing APIs, longer runs, VNet |
| Flex Consumption | ms with always-ready | 60 minutes | Yes | Per-second (with always-ready overlay) | Modern default — flexible Consumption |
| Dedicated (App Service) | Warm always | Unlimited | Yes | Per-plan-hour | High utilisation, sharing with web app |
[!TIP] For new workloads in , default to
Flex Consumption. It combines Consumption's per-second pricing with Premium's pre-warmed instance behaviour and VNet integration. Consumption remains the right choice when you do not need VNet and cold-start is acceptable.
[!WARNING] Consumption plan has a hard 10-minute per-invocation cap. Workloads with long-running steps must either move to Premium / Flex / Dedicated or split the work via a queue and orchestrator (Durable Functions, Container Apps Jobs).
2. Functions vs Container Apps consumption mode — when each wins
Both are serverless container-ish hosts. The distinguishing factors:
| Capability | Functions | Container Apps (consumption) |
|---|---|---|
| Code packaging | First-class runtimes (.NET, Python, Node, Java) | Bring your own container |
| HTTP / queue / timer trigger | Built-in trigger model | KEDA scalers |
| Per-request billing | Per-GB-second + invocations | Per-second per replica |
| Dapr / sidecar pattern | Limited | First-class |
| Cold start (cold) | s | s |
| Best for | Quick to ship, runtime-bound | Custom container, sidecars, larger code |
A general rule of thumb: if the team writes a function-shaped handler in a supported runtime and the input is a typical Azure trigger (HTTP, Queue, Service Bus, Timer), Functions is the right host. If the team has an existing container or wants sidecars / Dapr / custom runtime, Container Apps is the right host.
// Functions Flex Consumption plan
resource plan 'Microsoft.Web/serverfarms@2023-12-01' = {
name: 'plan-func-flex'
location: location
kind: 'functionapp'
sku: { name: 'FC1', tier: 'FlexConsumption' }
properties: { reserved: true } // Linux
}
resource func 'Microsoft.Web/sites@2023-12-01' = {
name: 'func-orders'
location: location
kind: 'functionapp,linux'
properties: {
serverFarmId: plan.id
functionAppConfig: {
deployment: { storage: { type: 'blobContainer', value: deploymentContainerUrl, authentication: { type: 'SystemAssignedIdentity' } } }
scaleAndConcurrency: { maximumInstanceCount: 100, instanceMemoryMB: 2048 }
runtime: { name: 'python', version: '3.11' }
}
httpsOnly: true
}
identity: { type: 'SystemAssigned' }
}[!NOTE]
Flex Consumptionplans exposescaleAndConcurrency.maximumInstanceCountandinstanceMemoryMB— letting the architect cap scale-out and pick memory size per instance. Older Consumption plans did not allow either.
3. Logic Apps — Consumption vs Standard
Logic Apps is the canonical low-code workflow engine. It pairs naturally with Functions: Logic Apps for orchestration and connectors, Functions for custom code steps.
| Aspect | Logic Apps Consumption | Logic Apps Standard |
|---|---|---|
| Hosting | Multi-tenant, shared infrastructure | Single-tenant, runs on App Service plan |
| Pricing | Per-action and per-connector call | Per-plan-hour + per-call overhead |
| VNet integration | Limited (ISE retired) | Yes |
| Source control / CI-CD | Designer-first | Code-first (workflow.json + parameters) |
| Stateful workflows | Yes | Yes (stateful) or stateless |
| Best for | Low volume (< runs/month), business workflows | Higher volume, regulated / VNet-bound, dev-ops-first teams |
# Logic Apps Standard workflow.json sketch (stateful)
definition:
triggers:
when_blob_added:
type: ApiConnection
kind: Stateful
inputs:
host: { connection: { referenceName: azureblob } }
method: get
actions:
parse_csv:
type: ServiceProvider
inputs: { parameters: { content: "@triggerBody()" }, serviceProviderConfiguration: { operationId: parseCsv, serviceProviderId: "/serviceProviders/csv" } }
push_to_sb:
runAfter: { parse_csv: [Succeeded] }
type: ApiConnection
inputs:
host: { connection: { referenceName: servicebus } }
method: post
body: "@body('parse_csv')"[!IMPORTANT] Logic Apps Consumption pricing is per-action — a workflow with 100 actions executed times in a month is much more expensive than Standard. Calculate per-action cost before committing to Consumption for high-volume scenarios.
4. Triggers, bindings, and scale shapes
The trigger drives scale behaviour. Match scaling characteristics to the upstream:
[!TIP]
Event Hubtriggers cap scale-out at the number of partitions. A 4-partition Event Hub will never have more than 4 concurrent Functions reading from it. To scale higher, increase the partition count at Event Hub creation time (it cannot be changed later for Standard tier).
// Find functions over the last 7 days that hit the 10-minute Consumption limit
AppExceptions
| where TimeGenerated > ago(7d)
| where OuterMessage has "FunctionTimeoutException" or OuterMessage has "function ran out of time"
| project TimeGenerated, AppName, Method, OuterMessage
| order by TimeGenerated desc5. Identity, networking, and observability for serverless
Production-grade serverless is more than the runtime plan. The full picture:
| Layer | Best practice |
|---|---|
| Identity | System-assigned managed identity on the Function App / Logic App; no admin keys |
| Networking | Premium / Flex / Standard plans support VNet integration and private endpoints |
| Secrets | Reference Key Vault via @Microsoft.KeyVault(SecretUri=...) syntax |
| Observability | Application Insights connected by default; sample at for high-volume apps |
| Deployment | Bicep / ARM + zip deploy from a storage container; never edit in the portal |
[!TIP] Functions and Logic Apps Standard both honour
Key Vaultreferences. SetWEBSITE_RUN_FROM_PACKAGE=1and pull the package from a storage container behind a private endpoint to keep both the code path and the secrets path private.
Worked Examples
Easy — pick the Functions plan for a webhook receiver
Problem. A team builds a webhook receiver for a payment provider. Volume averages events/day with bursts up to events in two minutes once an hour. Each event runs 200 ms of code. The receiver does not need to be in a VNet. Recommend a Functions plan.
Solution. Consumption (or Flex Consumption if available in the region). Burst shape is canonical for serverless: idle most of the time, brief intense bursts. Consumption scales to thousands of instances quickly enough to absorb the burst. Total cost will be well under $10/month at this volume. Cold start on the first event of a burst is the trade-off — for a webhook receiver where the partner retries on , that is acceptable.
[!NOTE] If the team later needed VNet integration or sub-100-ms cold start, upgrading to
Flex Consumptionis a single plan change.
Medium — Logic Apps Standard for a regulated workflow
Problem. A bank needs to process KYC documents per month via a workflow: parse PDF, look up customer, write decision to a regulated system. The workflow runs in a VNet and must support code review / CI/CD. Recommend a Logic Apps configuration.
Solution. Logic Apps Standard on a WS1 plan. The volume ( runs ~ 10 actions each actions/month) makes Consumption pricing unpredictable and likely expensive. Standard runs on a predictable per-plan-hour fee, supports VNet integration for the regulated system, and stores the workflow as workflow.json files that fit GitHub / Azure DevOps source control. Stateful workflows preserve audit trail for KYC compliance.
plan: WS1 # ~$200/month per plan
workflows:
- kyc-onboarding: Stateful
- kyc-renewal: Stateful
vnetIntegration:
subnetId: /subscriptions/.../subnets/snet-logicapps[!NOTE] Logic Apps Standard supports multiple workflows on the same plan — sharing the fixed plan cost across all workflows.
Hard — hybrid Functions + Container Apps Jobs design
Problem. A startup needs (a) a webhook receiver for events/day, (b) a 20-minute PDF generation triggered by webhook events, and (c) a 4-hour nightly batch that crunches a 50 GB dataset. Cost matters. Recommend a serverless topology.
Solution. Three serverless pieces, each on the right plan:
| Workload | Service | Why |
|---|---|---|
| Webhook receiver | Functions Consumption | Bursty, sub-second, no VNet needed |
| PDF generation | Container Apps Job (queue-triggered) | 20 min exceeds Functions Consumption 10-min cap |
| Nightly batch | Container Apps Job (cron-triggered, or Azure Batch) | 4 h runtime; needs to scale up briefly then idle |
The Function pushes a message to a Service Bus queue; the Container Apps Job is triggered by queue depth and runs the long job. The nightly batch runs on a cron ACA Job (or Azure Batch if the parallelism is heavy). Total monthly cost: roughly depending on PDF volume — versus several hundred dollars on always-on infrastructure.
[!IMPORTANT] When a workflow has both a sub-second event and a long-running step, do not try to fit the long step into Functions. Hand off via a queue to a host that can run it (Container Apps Jobs, Durable Functions, Azure Batch).
Visual Explanations
Figure 1 — Functions plan decision flow
The first axis is VNet need; the second is cold-start tolerance. Premium is the right answer only when both axes demand it. Dedicated (App Service plan) is a fifth option for workloads that already share an App Service plan and have high sustained utilisation.
Figure 2 — End-to-end serverless event topology
The pattern reflects a common AZ-305 exam scenario: sub-second receipt on Functions, hand-off to a Service Bus queue, long-running execution on Container Apps Jobs (or Durable Functions), with Logic Apps orchestrating retries / partner notifications.
Figure 3 — When serverless is not the right answer
| Workload signal | Why serverless is wrong | Better choice |
|---|---|---|
| Sustained $24/7$ high volume | Per-second / per-invocation pricing exceeds plan-based | App Service / Container Apps with min replicas |
| Strict sub-50-ms latency end-to-end | Even pre-warmed cold start is ms | App Service Premium / AKS |
| Workload runs for hours per invocation | Functions cap at 10 min (Consumption) or 60 min (Premium/Flex) | Container Apps Jobs, Azure Batch |
| Stateful workflow requiring local disk | Serverless is stateless by design | VMs or stateful Container Apps |
| Massive data per invocation | Serverless instance memory is bounded | Container Apps with larger instances |
The exam will sometimes test these reverse cases — "why is the team's serverless rewrite failing?" — with the answer being one of these mismatches.
Common Mistakes
❌ Myth: "Serverless is always the cheapest option." ✅ Reality: Serverless is the cheapest option for sparse / bursty workloads. For $24/7$ steady workloads, per-second billing accumulates beyond the cost of a small App Service plan or Container Apps minimum replicas. Why it's tricky: The "no idle cost" pitch sounds universally cheaper. Always check the workload shape.
❌ Myth: "Consumption plan can run any workload — just split long jobs." ✅ Reality: Splitting a long job is correct, but the boundary is the 10-minute cap and the cold-start penalty. Some workloads do not split cleanly (large in-memory state, single-pass file processing). Why it's tricky: The advice to "split" is correct in principle but often requires workflow redesign that is non-trivial.
❌ Myth: "Logic Apps Consumption is always cheaper than Standard." ✅ Reality: Consumption is cheaper at low volumes; Standard wins above runs/month or where each run has many actions. Run the per-action arithmetic. Why it's tricky: The Consumption name suggests it scales cheaply; per-action pricing accumulates fast.
❌ Myth: "Functions Premium is always overkill — just use Consumption." ✅ Reality: Premium is the right answer for user-facing APIs (low cold start), workloads needing VNet integration (no other Consumption-flavoured option until Flex), and long-running invocations. Why it's tricky: "Premium" sounds like a luxury upgrade. For some workloads it is the only valid choice.
Practice Exercises
🟢 Exercise 1. A workload runs on a Timer trigger every minute, each run taking 50 ms. Recommend a Functions plan.
▶💡 Hint
60 invocations/hour, s of compute per hour.
▶✅ Solution
Consumption (or Flex Consumption). Total monthly billable compute is tiny ( s of execution); Consumption's per-GB-second pricing makes this a sub-/month workload. The Timer trigger does not scale, so a single warm instance is sufficient most of the time.
🟡 Exercise 2. A team needs a Function that calls a private SQL Managed Instance and must read secrets from Key Vault. The MI is in a VNet with no public endpoint. Recommend a plan.
▶💡 Hint
VNet integration is required.
▶✅ Solution
Flex Consumption (preferred for new workloads) or Premium. Both support VNet integration; Consumption does not. The Function App must be configured with vnetSubnetId pointing to a subnet delegated to Microsoft.Web/serverFarms. Key Vault references work over the private path; the MI is reachable over its private endpoint.
🟡 Exercise 3. A Logic Apps Consumption workflow runs times a month with 15 actions each. Recommend a re-platforming decision.
▶💡 Hint
Per-action arithmetic.
▶✅ Solution
Move to Logic Apps Standard. At $7.5M\sim $200$/month, scalable) handles the volume for a small flat fee. The workflow definition is portable between Consumption and Standard with minimal changes.
🔴 Exercise 4. A workload runs a 4-minute video transcoding step that occasionally spikes to 12 minutes for files. Recommend a serverless approach.
▶💡 Hint
12 minutes exceeds Consumption's 10-minute cap.
▶✅ Solution
Use Flex Consumption (max execution 60 minutes) for the transcoding function, or split the work: a Consumption-plan function enqueues the job to a Service Bus queue; a Container Apps Job consumes the queue and runs the transcoding (no time cap). The split approach also lets the architect right-size CPU/memory for the long step independently of the receive function.
🔴 Exercise 5. A team builds a Functions Consumption-plan app. During load tests, requests at 500 rps return 429 Too Many Requests errors from the downstream storage queue. Diagnose.
▶💡 Hint
Storage accounts have throughput limits.
▶✅ Solution
The downstream storage account is hitting its per-account throughput limits ( requests/second baseline; less for queue per partition). The Function scaled out and saturated the storage account. Fix options: (a) move the queue to Service Bus (higher throughput and explicit throttling semantics), (b) shard across multiple storage accounts, (c) introduce a concurrency limit on the Function via host.json to throttle outgoing storage calls.
🟢 Exercise 6. True or false: a Functions Consumption plan can use a Premium SSD-backed storage account for cold-start improvement.
▶💡 Hint
Consumption plans use a Microsoft-managed storage account.
▶✅ Solution
False. Consumption plans use a Microsoft-managed storage account behind the scenes; the customer cannot bring their own disk for the runtime. Cold-start improvement requires moving to Premium (always-warm instances) or Flex Consumption (always-ready instances).
🟡 Exercise 7. Design a Bicep snippet for a Logic Apps Standard plan and a stateful workflow with a Service Bus trigger.
▶💡 Hint
Look up Microsoft.Web/serverfarms with kind=elastic and Microsoft.Web/sites with kind=workflowapp.
▶✅ Solution
resource plan 'Microsoft.Web/serverfarms@2023-12-01' = {
name: 'plan-logic-std'
location: location
sku: { name: 'WS1', tier: 'WorkflowStandard' }
kind: 'elastic'
}
resource la 'Microsoft.Web/sites@2023-12-01' = {
name: 'logic-orders'
location: location
kind: 'functionapp,workflowapp'
properties: {
serverFarmId: plan.id
siteConfig: {
appSettings: [
{ name: 'AzureWebJobsStorage', value: storageConnString }
{ name: 'WEBSITE_CONTENTAZUREFILECONNECTIONSTRING', value: storageConnString }
{ name: 'WEBSITE_CONTENTSHARE', value: 'logic-orders' }
{ name: 'FUNCTIONS_EXTENSION_VERSION', value: '~4' }
{ name: 'APP_KIND', value: 'workflowApp' }
]
}
}
}Summary & Concept Map
The headline takeaways from this lesson:
- Serverless wins for sparse, bursty, event-driven workloads — and only those. Sustained $24/7$ workloads belong on plan-based hosts.
Functionshas four plans. Consumption (cheapest, 10-min cap, no VNet), Premium (pre-warmed, VNet), Flex Consumption (modern default), Dedicated (App Service plan).Logic AppsConsumption is cheap at low volume; Standard wins above runs/month or with VNet / CI-CD needs.Container Appsconsumption mode is the container-shaped serverless alternative. Use when the workload is in a container or needs sidecars / Dapr.- Watch the cliffs. Cold start, 10-minute Consumption cap, queue throughput limits, action-count pricing in Logic Apps Consumption.
- Production-grade serverless needs identity, networking, observability, and deployment automation just like any other workload. The runtime is serverless; the operational rigour is not.
Walk the map from workload signal to host: the first cut is whether serverless even fits; the second cut is containerised vs workflow vs code; below it, plan selection and per-action arithmetic decide cost.