EF Core tracks entity results by default. That is useful when you will change an entity and call SaveChanges, but it adds change-tracking work to a query that only needs to display or serialize data.
Put AsNoTracking() on read paths that do not modify the returned entities:
var recentOrders = await db.Orders
.AsNoTracking()
.Where(order => order.CustomerId == customerId)
.OrderByDescending(order => order.CreatedAt)
.Take(50)
.ToListAsync(cancellationToken);
This is a query-level decision, so the intent stays close to the code that knows whether the result is read-only. It also avoids turning off tracking for a whole DbContext and then relying on every write path to remember AsTracking().
For a load-change-save update, leave tracking enabled and use the same context to load and save the entity:
var order = await db.Orders.SingleAsync(
order => order.Id == orderId,
cancellationToken);
order.Status = OrderStatus.Shipped;
await db.SaveChangesAsync(cancellationToken);
For set-based updates that do not need entity materialization, consider ExecuteUpdate or ExecuteDelete instead of loading tracked entities.
A no-tracking entity is not watched by the context, so changing it later will not be detected automatically. Avoid routinely loading an entity with AsNoTracking() and attaching it again just to update it. If a query projects exclusively into non-entity values, such as a DTO made only from scalar values, EF Core has no entity instance to track. A DTO projection can still contain a full entity, though, and EF Core tracks that embedded entity by default unless AsNoTracking() is applied. Keep it on read queries that return entity instances, or may do so later, as a defensive boundary.
One caveat: normal no-tracking queries do not perform identity resolution. If the same entity appears multiple times in a result graph, EF Core can materialize multiple instances. For read-only object graphs where that matters, consider AsNoTrackingWithIdentityResolution().
Use AsNoTracking() for list, detail, search, and reporting queries that do not write through the returned entities. Keep normal tracking for load-change-save workflows, and measure before changing the default tracking behavior for an entire context.