Making Entity Framework Faster: Practical Tips From Production

Making Entity Framework Faster: Practical Tips From Production

Barış TanerBarış Taner
January 2, 2026
3 min read
Backend.NETPerformance

Making Entity Framework Faster: Practical Tips From Production

I remember the first time someone said "Entity Framework is slow" during a production incident.

At that moment, I believed it too.

But after working on real systems, debugging slow endpoints, and staring at SQL logs late at night, I realized something important:

Entity Framework usually isn't the problem. How we use it is.

This post isn't a list of tips copied from documentation. These are things that actually helped me make Entity Framework faster in production.


Stop Treating Entity Framework Like Magic

Entity Framework makes database access feel simple, but it doesn't remove complexity.

Every LINQ query:

  • becomes SQL
  • hits the database
  • allocates memory

Once I started asking "what SQL will this generate?", performance issues became much easier to understand.

csharp
optionsBuilder
    .LogTo(Console.WriteLine)
    .EnableSensitiveDataLogging();

Use AsNoTracking for Read-Only Queries

Before:

csharp
var users = await context.Users
    .Where(u => u.IsActive)
    .ToListAsync();

After:

csharp
1var users = await context.Users
2    .AsNoTracking()
3    .Where(u => u.IsActive)
4    .ToListAsync();

AsNoTracking is now my default unless I need updates.

Load Less Data

Before:

csharp
var orders = await context.Orders
    .Include(o => o.Customer)
    .ToListAsync();

After:

csharp
1var orders = await context.Orders
2    .AsNoTracking()
3    .Select(o => new OrderDto
4    {
5        Id = o.Id,
6        Total = o.Total,
7        CustomerName = o.Customer.Name
8    })
9    .ToListAsync();

Be Careful With Include

Include is convenient but dangerous when overused.

If a query is slow, this is the first thing I question.

Watch Out for N+1 Queries

csharp
1var orders = await context.Orders.ToListAsync();
2
3foreach (var order in orders)
4{
5    Console.WriteLine(order.Customer.Name); // ⚠️ N+1 query!
6}

This can silently generate one query per row.

Fix it:

csharp
1var orders = await context.Orders
2    .Include(o => o.Customer)
3    .ToListAsync();
4
5foreach (var order in orders)
6{
7    Console.WriteLine(order.Customer.Name); // ✅ Single query
8}

DbContext Lifetime Matters

Long-lived DbContexts slowly get heavier:

  • more tracked entities
  • more memory
  • slower queries

Short-lived contexts fixed this for us.

Indexes Beat EF Tweaks

One missing index fixed issues that hours of EF tuning couldn't.

EF can't save you from a slow database.

Raw SQL Is Not a Failure

csharp
1var results = await context.Reports
2    .FromSqlRaw(
3        "SELECT Id, Total FROM Orders WHERE CreatedAt >= @date",
4        new SqlParameter("@date", date)
5    )
6    .AsNoTracking()
7    .ToListAsync();

Pragmatism beats purity.

Final Thoughts

Entity Framework is fast enough for real systems.

Most performance problems are self-inflicted — and that's good news, because it means we can fix them.

The tips above aren't theoretical. They're the ones that actually moved the needle in production.

Start with logging your SQL. You'll be surprised what you find.

Share: