# When to Use Clean Architecture (And When Not To)

> A five-endpoint CRUD API with four projects, domain events, and a CQRS pipeline is over-engineering, not discipline. Clean Architecture pays off on complex domains, long-lived codebases, and multi-team projects. Here is a decision framework for spotting which one you have, and a migration path for when you guess wrong.

Published: 2026-08-11. Author: Milan Jovanović.

Canonical: https://milanjovanovic.tech/blog/when-to-use-clean-architecture

Use Clean Architecture when the domain has complex business rules, the project will live for years, multiple teams share the codebase, or testability is a hard requirement.
Skip it for simple CRUD apps, prototypes, small microservices, and internal tools, where a single well-organized project is faster to build and just as maintainable.

Clean Architecture is the default recommendation in the .NET space, and that is exactly the problem.
Defaults get applied without asking whether the project has the problems the architecture solves.
Here is a decision framework for telling the two apart, and a migration path for when you guess wrong.

## Clean Architecture Is Not Always the Answer

[Clean Architecture](https://milanjovanovic.tech/blog/clean-architecture-and-the-benefits-of-structured-software-design) is an architectural style that protects complex business logic from infrastructure concerns behind clear layer boundaries.

Teams apply it to every project, regardless of complexity. A five-endpoint CRUD API with four separate projects, domain events, a CQRS pipeline, and architecture tests.

That's over-engineering.

Clean Architecture solves specific problems. When those problems don't exist, the architecture adds cost without benefit.

## When Clean Architecture Shines

### Complex Business Logic

If your domain has real business rules - not just CRUD operations - Clean Architecture protects that logic from infrastructure concerns.

**Signals you need it:**
- Business rules that span multiple entities
- Domain invariants that must always hold
- Complex calculations or state machines
- Rules that change independently from infrastructure

```csharp
// This is domain complexity worth protecting
public class LoanApplication : AggregateRoot
{
    public ApplicationStatus Status { get; private set; }
    public decimal Amount { get; private set; }

    public Result Approve(CreditScore score, DebtToIncomeRatio ratio)
    {
        if (Status != ApplicationStatus.UnderReview)
            return Result.Failure(LoanErrors.NotUnderReview);

        if (score.Value < 650)
            return Result.Failure(LoanErrors.CreditScoreTooLow);

        if (ratio.Value > 0.43m)
            return Result.Failure(LoanErrors.DebtRatioTooHigh);

        Status = ApplicationStatus.Approved;
        RaiseDomainEvent(new LoanApprovedDomainEvent(Id, Amount));

        return Result.Success();
    }
}
```

### Long-Lived Projects

Projects expected to last years benefit from clean boundaries. Requirements change, frameworks evolve, team members rotate. Clean Architecture makes the codebase resilient to these changes.

If the project has a 6-month lifespan and will be replaced, the investment doesn't pay off.

### Multiple Teams

When multiple teams work on the same codebase, clear boundaries prevent them from stepping on each other. The Domain layer is the stable core everyone agrees on.

### High Testability Requirements

If comprehensive testing is a hard requirement (regulated industries, financial systems, healthcare), Clean Architecture makes the domain layer trivially testable - no mocks for databases or HTTP needed.

I've written more about [**why Clean Architecture is great for complex projects**](https://milanjovanovic.tech/blog/why-clean-architecture-is-great-for-complex-projects) if you recognize your project in these signals.

## When to Skip Clean Architecture

### Simple CRUD Applications

If your application is mostly reading and writing data with minimal business logic:

```csharp
// This doesn't need Clean Architecture
app.MapPost("/api/todos", async (TodoRequest request, AppDbContext db) =>
{
    var todo = new Todo { Title = request.Title, IsComplete = false };
    db.Todos.Add(todo);
    await db.SaveChangesAsync();
    return Results.Created($"/api/todos/{todo.Id}", todo);
});
```

For CRUD, a single project with Minimal APIs and EF Core is faster to build, easier to understand, and perfectly maintainable.

### Prototypes and MVPs

Speed matters more than architecture when you're validating an idea. Build the simplest thing that works. Refactor into Clean Architecture later if the project survives.

### Small Microservices

A microservice with a narrow responsibility (send emails, resize images, generate PDFs) doesn't need four projects and a domain model. Keep it simple.

### Internal Tools

Admin dashboards, migration scripts, and one-off data tools don't justify the ceremony. Ship fast, iterate, replace.

## The Decision Framework

![A decision tree: a complex, long-lived, multi-team, high-testability project points to Clean Architecture, a CRUD, MVP, or small-service project points to keeping it simple, and mixed answers point to starting simple and migrating later](https://milanjovanovic.tech/blogs/articles/when-to-use-clean-architecture/decision-framework.png)

Ask these questions.

Questions where "yes" points to Clean Architecture:

- Does the domain have complex business rules?
- Will the project live for 2+ years?
- Do multiple teams contribute to the same codebase?
- Is testability a hard requirement (regulated industry, financial, healthcare)?

Questions where "yes" points to a simpler structure:

- Is it mostly CRUD?
- Is it a prototype or MVP?
- Is it a small, focused microservice?
- Is it an internal tool you'd rather replace than maintain?

If you answer "yes" to most of the first group, Clean Architecture is a good fit.
If you answer "yes" to most of the second group, keep it simple.
Mixed answers usually mean: start simple, and let the migration path below carry you.

## Alternatives to Clean Architecture

### Vertical Slice Architecture

[Vertical Slice Architecture](https://milanjovanovic.tech/blog/vertical-slice-architecture) organizes code by feature instead of by layer. Each feature contains everything it needs - from request to response.

**Best for:** Medium-complexity applications where features are independent and don't share much domain logic.
I compare the two approaches head-to-head in [**Vertical Slice Architecture vs Clean Architecture**](https://milanjovanovic.tech/blog/vertical-slice-vs-clean-architecture).

### Simple Layered Architecture

The classic three-layer approach: Presentation → Business → Data. Less ceremony than Clean Architecture, still provides some separation.

**Best for:** Applications with moderate complexity that don't need the full rigor of Clean Architecture.

### Single Project

Everything in one project, organized by feature folders.

**Best for:** Small applications, prototypes, microservices, and internal tools.

## The Migration Path

You don't have to start with Clean Architecture. Start simple and evolve:

1. **Start:** Single project with feature folders
2. **Grow:** Extract a Domain project when business logic appears
3. **Mature:** Add Application and Infrastructure projects when needed
4. **Scale:** Add architecture tests to enforce boundaries

This is cheaper than starting with four empty projects and hoping you'll need them.

## Common Objections

**"But what if we need Clean Architecture later?"**
You'll know. When business logic starts leaking into controllers or database code infects your domain, it's time. Refactoring from a well-organized simple project to Clean Architecture is straightforward.

**"Clean Architecture is industry standard."**
It's one approach among many. [Hexagonal Architecture](https://milanjovanovic.tech/blog/clean-architecture-vs-onion-vs-hexagonal), Vertical Slices, and even well-structured monoliths are all valid. Choose based on your specific needs.

**"My team expects Clean Architecture."**
Make the decision based on the project, not on habits. If the team knows Clean Architecture well and the project benefits from it, great. If it's adding overhead, question it.

## Summary

Clean Architecture is a tool, not a dogma. Use it when your domain is complex, the project is long-lived, and testability matters. Skip it when simplicity serves you better.

The best architecture is the one that makes your team productive and your software maintainable - whatever that looks like for your specific project.

Thanks for reading, and stay awesome!

---

## Frequently asked questions

### When should you use Clean Architecture?

When the domain has complex business rules, the project will live for years, multiple teams share the codebase, or testability is a hard requirement. Those are the problems the architecture actually solves.

### Is Clean Architecture overkill for CRUD applications?

Usually yes. If the application mostly reads and writes data with minimal business logic, a single well-organized project with Minimal APIs and EF Core is faster to build and just as maintainable.

### Can you migrate to Clean Architecture later?

Yes, and it is often the better path. Start with a single project organized by feature, extract a Domain project when real business logic appears, then add Application and Infrastructure projects as needed.

### What are the alternatives to Clean Architecture?

Vertical Slice Architecture organizes code by feature instead of by layer. A simple three-layer architecture offers lighter separation. And a single project with feature folders is fine for small apps, prototypes, and focused microservices.

### Does Clean Architecture slow down development?

It adds upfront cost: more projects, more abstractions, more mapping. On complex, long-lived systems that cost pays for itself in testability and changeability. On simple projects it is pure overhead.
