Quick answer: Azure Functions is Microsoft’s serverless platform for running small pieces of code in response to triggers, such as an HTTP request, a timer, a new file in storage or a message on a queue. You write the function, usually in C# on .NET Core 3.1 with the current version 3 runtime, and Azure handles the servers and scaling. It suits background jobs, integrations, scheduled tasks and lightweight APIs. It is a poor fit for long-running processes, chatty workloads where cold starts hurt, or apps that need full control of the hosting environment.
What “serverless” means in practice
There are still servers. You just do not manage them. With Azure Functions you deploy code, tell Azure what should trigger it, and Azure starts instances when there is work and removes them when there is not. On the Consumption plan you pay per execution and for the memory and time your code uses, rather than for a server that sits idle most of the day.
For a business app, that changes how you think about background work. Instead of a Windows service on a VM that runs a nightly job, or a scheduled task on a web server, you deploy a function with a timer trigger. Instead of a polling loop that checks a folder for new files, you write a function triggered by blob storage.
Common business uses
Azure Functions is at its best for small, well-defined jobs. Typical examples:
- Scheduled jobs: Nightly report generation, data cleanup, sending reminder emails, syncing records between systems.
- Integrations: Receiving webhooks from a payment provider, CRM or ecommerce platform, then updating your own database. Our guide to API integration covers the broader patterns.
- File processing: Resizing images, parsing CSV uploads, extracting data from documents dropped into storage.
- Queue processing: Taking orders or events from a queue and processing them one by one, with automatic retries.
- Lightweight APIs: Simple HTTP endpoints for a mobile app or a website form, where a full web application would be overkill.
- Glue between legacy and cloud: Moving data out of an older system into a newer one without changing the old system much.
If you are moving an older .NET application to the cloud, functions are often a good home for the scheduled tasks and background services that used to live on the same server. Our article on Azure migration covers that larger move.
Triggers and bindings
Every function has exactly one trigger. Common triggers include:
- HTTP: Runs when a request hits the function’s URL.
- Timer: Runs on a schedule written as a CRON expression.
- Queue Storage and Service Bus: Runs for each message on a queue or topic.
- Blob Storage: Runs when a file is added or changed in a container.
- Cosmos DB: Runs when documents change.
- Event Grid and Event Hubs: Runs for events from Azure services or high-volume event streams.
Bindings are a shortcut for reading and writing data. An output binding can write a message to a queue or a row to Table Storage just by returning a value, without you writing the connection code. They save boilerplate, but for complex database work most teams still use Entity Framework Core or Dapper directly inside the function.
A simple example
Here is a timer function in C# that runs every night at 2 a.m. UTC and calls a service to sync invoices:
public class NightlyInvoiceSync
{
private readonly IInvoiceService _invoices;
public NightlyInvoiceSync(IInvoiceService invoices)
{
_invoices = invoices;
}
[FunctionName("NightlyInvoiceSync")]
public async Task Run([TimerTrigger("0 0 2 * * *")] TimerInfo timer, ILogger log)
{
var count = await _invoices.SyncFromAccountingAsync();
log.LogInformation("Synced {Count} invoices", count);
}
}
This uses dependency injection, which Azure Functions supports through a startup class, much like an ASP.NET Core app. That lets you share services, configuration and data access code between your functions and your main web application.
Hosting plans
Choosing the right plan matters more than most first-time users expect.
Consumption plan
You pay only when functions run. Azure includes a monthly free grant of executions and compute time, which covers many small business workloads entirely. The trade-offs are cold starts, a default timeout of 5 minutes that can be raised to 10, and limited networking options.
Premium plan
Premium keeps instances warm, so there are no cold starts for your baseline, and it supports longer executions, more powerful instances and virtual network connectivity. You pay for the pre-warmed instances whether or not they are busy. It suits APIs where latency matters or functions that need to reach resources inside a private network.
Dedicated (App Service) plan
Functions can run on an App Service plan you already pay for. This is predictable and useful if you have spare capacity, but you lose automatic scale to zero, and scaling works like a normal web app.
Cold starts
On the Consumption plan, if a function has not run for a while, Azure removes its instance. The next request has to wait for a new instance to start and load your code. For .NET functions this can add a few seconds.
That rarely matters for timers, queues or file processing. It can matter for HTTP endpoints that a customer is waiting on. Options include moving to the Premium plan, keeping dependencies light so startup is quick, or using functions only for background work and keeping customer-facing endpoints in a regular ASP.NET Core Web API.
Durable Functions for multi-step workflows
Plain functions are stateless and short-lived. When a process has several steps, waits for something, or needs to fan out work and gather the results, Durable Functions helps. It is an extension that lets you write an orchestrator function in normal C# that calls activity functions in sequence or in parallel, with state saved automatically between steps.
Examples:
- An order process that charges a card, reserves stock, books shipping and sends a confirmation, with compensation if a step fails.
- An approval workflow that waits up to three days for a manager to approve a request.
- A batch job that splits a large import into chunks and processes them in parallel.
Durable Functions has rules you must follow, especially that orchestrator code must be deterministic, so read the documentation before building something critical with it.
Monitoring and reliability
Connect your function app to Application Insights. You get logs, failures, durations and dependency calls in one place, which is essential because there is no server to log into when something goes wrong.
A few reliability habits:
- Make functions idempotent, so running the same message twice does not double-charge or duplicate records. Queue triggers retry on failure.
- Use poison queues to catch messages that fail repeatedly, and alert someone.
- Keep secrets out of code. Use application settings with Key Vault references and managed identities where possible.
- Set sensible timeouts for outbound calls so a slow partner API does not consume your whole execution window.
Where Azure Functions is the wrong tool
- Long-running jobs: Hours-long processing is better suited to a background worker on a VM, a container or Azure Batch.
- Heavy, constant traffic: If a function runs nonstop at high volume, a dedicated service may be cheaper and simpler.
- Complex web applications: A full app with many pages, sessions and shared state belongs in ASP.NET Core on App Service or containers.
- Tight latency on the Consumption plan: Cold starts make it a poor choice for customer-facing requests that must always be fast.
Development workflow
Visual Studio 2019 and Visual Studio Code both have Azure Functions tooling. The Azure Functions Core Tools let you run and debug functions locally, including with the storage emulator. Deploy through Visual Studio for small projects, but for anything serious use a pipeline in Azure DevOps or GitHub Actions so every release is repeatable.
Treat function apps like any other application: version control, code review, automated tests for business logic, and separate environments for testing and production. Keep business logic in ordinary classes you can unit test in .NET, with the function itself as a thin wrapper.
Comparing with AWS Lambda
AWS Lambda is the best-known alternative. Both platforms support .NET and offer similar pay-per-use pricing. For a .NET shop already on Microsoft tooling, Azure Functions usually fits more naturally with Visual Studio, Azure SQL, Active Directory and existing Azure subscriptions. Our AWS vs Azure comparison covers the wider decision.
FAQ
Is Azure Functions cheap?
For small and bursty workloads, very often yes, and many stay within the free grant. Costs grow with heavy, continuous use, or when you choose Premium for warm instances.
Which .NET version should I use?
At the time of writing, the version 3 runtime with .NET Core 3.1 is the supported long-term option for C# functions. Check Microsoft’s documentation before starting a new project, since support for newer releases is being added.
Can functions talk to an on-premises database?
Yes, through options such as Hybrid Connections or virtual network integration, which generally require the Premium or Dedicated plan.
Can I move existing scheduled tasks to functions?
Usually. Move the logic into a class library, call it from a timer function, and test it carefully against production-like data.
Next step
List the scheduled tasks, background services and integration scripts running on your servers today. Most of them are good candidates for Azure Functions, and moving them can reduce server maintenance.
If you want help designing or moving these jobs as part of a larger .NET project, see our Custom development services.