EF Core: Boost Read-Only Performance with AsNoTrackingWithIdentityResolution()

Morteza JangjooMorteza Jangjoo
3 min read

When working with Entity Framework Core (EF Core), performance and memory efficiency can be key concerns, especially when dealing with large data sets or read-heavy operations. One simple yet powerful method to improve performance is using .AsNoTracking().

In this article, I’ll walk you through what AsNoTracking() does, when to use it, and how it affects your EF Core queries with a practical example.


🧠 What is AsNoTracking()?

By default, EF Core tracks all entities retrieved from the database using its Change Tracker. This allows EF Core to detect changes and update the database when SaveChanges() is called.

However, not all queries require tracking — especially when you're just reading data without intending to modify it. That’s where .AsNoTracking() comes in.

When you apply .AsNoTracking() to a query, EF Core:

  • Skips the Change Tracker

  • Does not cache the entity

  • Improves performance and reduces memory usage


🧪 Example: With and Without AsNoTracking()

Let’s say we have a Blog entity:

Using AsNoTracking():

var posts = await _context.Posts
    .Include(p => p.Author)
    .AsNoTracking()
    .ToListAsync();

In this case, if an author has written multiple posts, EF Core may return multiple Author instances with the same data — each one tied to a different Post.

Using AsNoTrackingWithIdentityResolution():

var posts = await _context.Posts
    .Include(p => p.Author)
    .AsNoTrackingWithIdentityResolution()
    .ToListAsync();

Now, all posts written by the same author will reference the exact same Author object in memory — without enabling full tracking. Cleaner and more consistent.


📊 When to Use It

ScenarioRecommendation
Simple read-only list (flat entities)Use AsNoTracking()
Complex graphs with reused referencesUse AsNoTrackingWithIdentityResolution()
You plan to modify and save entitiesDon't use either — use default tracking

💡 Performance Considerations

While AsNoTrackingWithIdentityResolution() is still faster than full tracking, it is slightly slower than plain AsNoTracking(), because it requires some internal caching to ensure identity resolution.

MethodTrackingIdentity ResolutionPerformance
Default✅ Yes✅ Yes🚫 Slowest
AsNoTracking()❌ No❌ No✅ Fastest
AsNoTrackingWithIdentityResolution()❌ No✅ Yes⚡ In between

✅ Summary

AsNoTrackingWithIdentityResolution() strikes a great balance between performance and consistency when reading related data without needing tracking.

Use it when:

  • You load complex object graphs

  • You don’t plan to update the data

  • You want to avoid duplication in memory

Don’t use it if:

  • You’re updating entities (use full tracking instead)

  • You don’t need related entities or identity resolution (then AsNoTracking() is faster)


🧠 Final Thought

Knowing when to use tracking, AsNoTracking(), or AsNoTrackingWithIdentityResolution() is key to building fast and reliable EF Core applications. The right choice can save both memory and headaches — especially in high-traffic APIs or data-heavy dashboards.

I’m Jangjoo and Happy querying! 🚀

0
Subscribe to my newsletter

Read articles from Morteza Jangjoo directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Morteza Jangjoo
Morteza Jangjoo