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


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
Scenario | Recommendation |
Simple read-only list (flat entities) | Use AsNoTracking() |
Complex graphs with reused references | Use AsNoTrackingWithIdentityResolution() |
You plan to modify and save entities | Don'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.
Method | Tracking | Identity Resolution | Performance |
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! 🚀
Subscribe to my newsletter
Read articles from Morteza Jangjoo directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
