Logic Apps vs. Durable Functions: What I Wish I Knew Before Choosing
A .NET developer's honest take after building real orchestrations with both

There's a question I've been asked more than once by teammates and colleagues venturing into Azure integration work:
"Should I use Logic Apps or Durable Functions for this?"
I used to answer confidently with a checklist. Now, after having actually shipped orchestrations using both — some that went well, some that did not — I give a longer, more honest answer. This post is that answer.
A Quick Framing Before We Dive In
If you're coming from a .NET background like me, your instinct might be to reach for Durable Functions the moment someone says "orchestration." It's code. It's C#. It feels like home.
But that instinct can cost you. Equally, reaching for Logic Apps because "it has a designer" can trap you in a visual maze that becomes unmaintainable after two months of change requests.
The truth is: both tools are genuinely good at different things, and the hardest part isn't learning the API — it's developing the judgment to tell which problem you're actually solving.
The Fundamental Difference Nobody Explains Clearly
Both Logic Apps and Durable Functions solve the same core problem: how do you coordinate long-running, multi-step processes reliably?
But they come from opposite directions.
Logic Apps is an integration platform with orchestration capability bolted on. Its DNA is connecting systems — think of it as a smarter, more scalable cousin to BizTalk or SSIS. It's declarative, configuration-driven, and happy in a world of managed connectors.
Durable Functions is a compute framework with durable state. Its DNA is code — specifically the virtual actor / reliable execution pattern. It doesn't know anything about your systems; it just knows how to orchestrate your code reliably across machine restarts.
Once you internalize that distinction, a lot of the "which one?" question starts answering itself.
When Logic Apps Actually Wins
I used to underestimate Logic Apps. I'd look at the visual designer and think "this isn't real engineering." That was arrogant and wrong.
There are scenarios where Logic Apps is the clearly correct tool:
1. You're primarily connecting external systems with existing connectors
Logic Apps has hundreds of managed connectors — Office 365, ServiceNow, Salesforce, SAP, Dynamics, and so on. If your orchestration is mostly "get data from System A, transform it, push it to System B," Logic Apps eliminates enormous amounts of boilerplate. The connector handles auth, retry, pagination, and schema discovery.
I've seen teams write hundreds of lines of C# to do something that a Logic App accomplishes in a drag-and-drop workflow. The code approach isn't necessarily better; it's just more familiar.
2. Your stakeholders need to own or understand the workflow
This is underrated. In one project I worked on, the business team needed to adjust notification routing rules periodically. In a Durable Function, that means a pull request, a code review, a deployment pipeline, and a deployment window. In a Logic Apps Standard workflow, with the right parametrization, it can mean editing a JSON config or even adjusting conditions in the designer.
Not every change should require engineering. Logic Apps lets you draw that boundary more cleanly.
3. You need deep Azure service integration with minimal code
Logic Apps has first-class built-in connectors for things like Service Bus, Event Grid, Blob Storage, and Cosmos DB — with triggers, not just actions. Writing a Durable Function triggered by a Service Bus message, then fanning out to multiple parallel activities, then waiting for an external event — that's doable, but you're building a lot of infrastructure in code. Logic Apps does a lot of that wiring declaratively.
When Durable Functions Actually Wins
That said, there are scenarios where Durable Functions is unmistakably the right call.
1. Your orchestration logic is genuinely complex
By "complex" I mean: conditional branching based on runtime data, dynamic fan-out where you don't know the number of parallel tasks upfront, human-in-the-loop approval with arbitrary timeout behavior, or recursive orchestration patterns.
In Logic Apps, deeply nested conditionals inside loops get painful fast. The visual designer becomes a liability at a certain complexity threshold — you're scrolling endlessly, collapsing and expanding nodes, and losing track of the overall flow. I've been there. It's not fun.
In a Durable Function orchestrator, this is just C#:
[Function("ProcessOrders")]
public static async Task RunOrchestrator(
[OrchestrationTrigger] TaskOrchestrationContext context)
{
var orders = await context.CallActivityAsync<List<Order>>("GetPendingOrders", null);
var tasks = orders.Select(order =>
context.CallActivityAsync<bool>("ProcessOrder", order));
var results = await Task.WhenAll(tasks);
if (results.Any(r => !r))
{
await context.CallActivityAsync("NotifyFailures", results);
}
}
That fan-out pattern — calling activities in parallel for an unknown number of items, then aggregating — is natural in C#. In Logic Apps, you'd use a For Each loop, which is fine for simple cases but loses clarity fast when the per-item logic is non-trivial.
2. You need fine-grained control over retry and error handling
Durable Functions gives you per-activity retry policies, custom exception types, and the ability to implement compensation logic (saga pattern) with the full expressiveness of C#. When an activity fails, you decide exactly what that means: retry with exponential backoff, compensate previous steps, alert a dead-letter queue, or escalate.
Logic Apps has retry policies too, but they're configured at the action level and the branching logic for error paths can get tangled quickly.
3. Your team is code-first and clean architecture matters to you
This is personal, but it matters. Durable Functions live in your codebase. They're testable. You can mock TaskOrchestrationContext. You can write unit tests for your orchestrator logic. You can enforce clean architecture — keep your domain logic in your domain layer, your orchestration as an application-layer concern, your activities as thin infrastructure adapters.
Logic Apps lives in JSON and the Azure Portal. You can source-control the ARM/Bicep definitions, but they're not the kind of thing you write domain logic in. If your orchestration is your business logic, that's a problem.
The Gray Area: Where I've Struggled
Here's the part they don't tell you in the documentation.
Hybrid scenarios are genuinely hard
I've worked on systems where the right answer was both — Logic Apps for the integration/connectivity tier, Durable Functions for the complex coordination logic, with HTTP or Service Bus as the handoff point. This is architecturally clean but operationally complex. You now have two runtimes to monitor, two deployment pipelines, and two sets of retry semantics to reason about when something goes wrong.
Be honest with yourself about whether that complexity is justified.
Logic Apps Standard vs. Consumption matters enormously
Logic Apps Standard (the newer, workflow-per-plan model) is a very different product from Logic Apps Consumption. Standard runs on the same underlying infrastructure as Azure Functions, supports stateful and stateless workflows, and has much better local development support via the VS Code extension. Consumption is the old model — simpler to start with, but you give up a lot of control.
If you're evaluating Logic Apps today, you're probably looking at Standard. Don't conflate the two when reading older blog posts (including documentation that's even slightly dated).
Testing is still a pain point for Logic Apps
This is a genuine weakness. Durable Functions has proper unit testing support. Logic Apps workflows are harder to test in isolation — you're often testing against Azure resources in a dev environment, or relying on the "Run Trigger" / "Resubmit" tooling in the portal. The ecosystem around Logic Apps testing has improved, but it's still not where the .NET testing culture wants it to be.
Cost model differences surprise people
Logic Apps Consumption charges per action execution. Durable Functions charges for compute + storage (the orchestration state is persisted in Azure Storage or MSSQL). For high-throughput orchestrations with many steps, the Logic Apps cost model can balloon unexpectedly. For long-running orchestrations with lots of wait states, Durable Functions' storage-centric billing is often more economical. Run the numbers for your specific workload — don't assume.
A Decision Framework I Actually Use
When someone asks me now, here's roughly how I think about it:
| Question | Points toward... |
|---|---|
| Are most steps calling managed connectors (O365, SAP, Salesforce, etc.)? | Logic Apps |
| Is the workflow primarily defined by when and what (integration mapping), not how? | Logic Apps |
| Do non-technical stakeholders need to own or modify the workflow? | Logic Apps |
| Is the orchestration logic complex (dynamic fan-out, custom compensation, recursive patterns)? | Durable Functions |
| Does the workflow embed core business/domain logic? | Durable Functions |
| Does the team care about testability, code review, and clean architecture? | Durable Functions |
| Is the team already writing Azure Functions for other workloads? | Durable Functions |
| Do you need very fine-grained control over retry, timeout, and error handling? | Durable Functions |
Neither column is an absolute. It's a tiebreaker exercise, not a checklist.
What I'd Tell Myself Three Years Ago
Stop treating the visual designer as a signal of quality. A Logic Apps workflow that cleanly orchestrates an ERP integration is a better engineering decision than a 600-line Durable Function that reinvents connector logic. Tools aren't better because they look like code.
Stop treating "it's code" as automatically maintainable. A Durable Function orchestrator with tangled nested conditions and no tests is harder to maintain than a well-structured Logic Apps workflow. "It's C#" doesn't save you from bad design.
Think about who will operate this in production. Observability, resubmit behavior, monitoring — both tools have this, but differently. Logic Apps has excellent built-in run history in the portal. Durable Functions requires Application Insights, OpenTelemetry, or a custom monitoring story. If the team running this day-to-day isn't developers, that matters.
Think about the seam, not just the component. In most real systems, orchestration is one layer in a larger architecture. Where does this workflow start? What triggers it? What does it call? Who owns the downstream systems? Sometimes those constraints make the decision for you before you even think about features.
Closing Thoughts
I don't think there's a universally correct answer here, and I'd be suspicious of anyone who tells you there is. Both Logic Apps and Durable Functions are mature, production-grade tools. The question is about fit — fit with your team's skills, your organization's operational model, your architecture's boundaries, and the actual nature of the problem you're solving.
The developers I've seen make the worst decisions are the ones who decided before they understood the problem. The ones who made the best decisions spent time mapping the problem first — who owns it, what changes, how complex is the logic, who operates it — and let those answers drive the tool choice.
That's the habit worth building.
Thanks for reading. If you've got war stories of your own — especially around hybrid architectures or migrations between the two — I'd genuinely love to hear them in the comments.






