They overlap, and they are still different jobs

A Logic Apps workflow can call an Azure Function, and a Standard workflow can run a script for one step. They are still different jobs. Logic Apps connects systems and runs a process. Azure Functions runs code you want to test and review. If the value is the connection, start with a workflow. If the value is a calculation, a library or a rule the team will unit test, start with code.

Choose Logic Apps when the value is the connection

Logic Apps is a workflow service. You describe a process: when a message arrives, validate it, call another system, and if that call fails, retry and tell someone. The Logic Apps overview distinguishes two resource types, and the distinction matters more than the logo.

  • A Consumption workflow runs in multitenant Azure Logic Apps. One workflow sits on the resource. You pay per execution. It is the quicker way to stand up an irregular integration, and the limits and the cold-start behaviour are part of that trade. Read the current limits rather than trusting a number from an old post.
  • A Standard resource can hold several stateful and stateless workflows. It runs in single-tenant Azure Logic Apps, in an App Service Environment, or on infrastructure you host with the hybrid option. Virtual network integration is a Standard concern. The workflows are definition files, so they can go through the same review as the rest of the solution. You pay for the hosting plan, and stateful runs also create storage transactions.
  • Connectors are the reason to be here. Authentication, paging and a large set of SaaS and Azure operations already exist. Rebuilding those in C# means you now own token refresh, throttling and the next API change.
  • EDI and partner agreements belong with an integration account linked to the workflow: schemas, maps, and protocols such as AS2, EDIFACT, X12 and RosettaNet. That is a different design from an internal JSON API. Do not force both through the same pattern.
  • Put Azure API Management in front when other teams need a published contract. The workflow can stay an implementation detail.

Standard workflows can also run a short C# or PowerShell script inline, and both Consumption and Standard can call Azure Functions. A script step is for a step. It is not a place to hide a domain model. If the script needs its own tests, its own dependencies and its own release, it wants to be a Function or another service.

Choose Functions when the value is the code

Azure Functions is event-driven code. A trigger starts a function: an HTTP call, a message on a queue, a timer, a blob, an event. Bindings connect that function to a service without you hosting the listener, and the interesting logic stays in the language you already use. For a .NET estate that language is usually C#.

Microsoft documents more than one hosting plan, including Consumption and plans that keep instances warm, with different cold-start, networking and pricing behaviour. The lineup has changed before and it will change again. Use the current Azure Functions hosting documentation when you compare plans. This note deliberately has no prices in it.

  • Domain rules, calculations and transformations that depend on a library belong in a function, with unit tests around the cases that have hurt you before.
  • A tight loop over data, or anything where a workflow action would be an awkward unit of work, belongs in code. Measure it. Do not accept a slogan about which product is faster.
  • Durable Functions is the code-centric way to orchestrate a long-running process: fan-out, a wait for an external event, a series of steps you would rather read as C#. The orchestrator has rules, including staying free of non-deterministic calls such as direct I/O. Read the Durable Functions guidance before you commit to it. It is not an unopinionated state machine.
  • If the team's review habit is a pull request on a .NET project, Functions fit that habit. A workflow definition can be reviewed too, but it is a different artefact and a different failure mode.

Use them together on purpose

The combination that ages well is a workflow as the spine and a function as the step that is awkward in the designer. The Logic App owns the connectors, the branches and the "tell a person when this fails" path. The Function owns the code you do not want expressed as a chain of conditions. Azure Service Bus often sits between a caller that must return and work that can wait, so a slow system does not become the caller's timeout.

API Management can front either runtime when other teams need a stable contract. The same split appears when an estate leaves BizTalk Server: orchestrations tend toward Logic Apps, and custom functoids, pipeline components and rules that are really code tend toward Functions. The longer version is migrating from BizTalk to Azure Integration Services.

Signs the split is wrong

  • A workflow nobody can change without tracing a long chain of conditions. That behaviour wants to be code, with tests, even if a workflow still calls it.
  • A Function whose only job is to call three systems that already have connectors, including the paging and the OAuth. You have taken on maintenance the connector was going to do. Build it when an operation is missing, when you must use a library, or when you have measured a reason.
  • Treating a Standard workflow and a Function as the same project because both can contain C#. Sharing a language is not sharing an operating model.
  • Retries with no idempotency story. Logic Apps and Functions will both try again. If the downstream system inserts a row on every call, a retry is a duplicate business transaction. Agree the key, or the receiver's behaviour, before you turn retry on.
  • A Consumption workflow used as the runtime for a whole application, or a Function used as a place to draw an integration diagram. Each tool gets worse at the other's job.

A .NET team's default

If the estate is already C# and ASP.NET Core, Functions fit the same language, the same test tools and the same review. Logic Apps still earns a place at the boundary, where the work is "when this message arrives, call that system, and tell someone if it fails". Bespoke .NET development is the home for the application itself. Enterprise integration is the home for the contracts and the message flows between applications. The platform underneath both is Azure.

We are not ranking the two on speed or cost. Cost follows the plan, the number of executions, the storage a stateful workflow uses and the connectors. Check Microsoft's pricing pages when you estimate, and again before a number goes in front of a finance partner.

Sources