Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
To speed up LINQ, first find where the time goes: in-memory enumeration, EF Core translation, database execution, or data transfer. For EF Core, inspect the generated SQL and database execution plan before changing expression syntax; for LINQ to Objects, check repeated enumeration, sorting, and unnecessary materialization. No single LINQ trick is faster in every workload.
Start by identifying where the query runs
LINQ is an interface for describing operations, not one execution engine. With LINQ to Objects, operators work against in-memory data. With EF Core, a query is represented as an expression tree; the provider translates supported operations into database-specific commands, and database work generally begins when results are consumed. Microsoft’s explanation of EF Core query execution describes this translation and execution path.
This distinction determines what to optimize. A faster-looking C# expression may produce identical SQL, while a small change that affects translation can alter rows returned, columns transferred, or database roundtrips. Once a provider-backed query crosses into local enumeration, later operations run in memory instead of being translated.
For EF Core, inspect the database work first
When an EF Core query is slow, begin with its generated SQL and the database execution plan. Check whether the plan uses appropriate indexes or scans more data than expected. Then check how many rows and columns are read, whether results are bounded, and how many database calls the operation makes. Microsoft’s EF Core efficient querying guidance emphasizes indexes, projection, result size, and relationship-loading behavior.
#1 Best Overall
Return only the properties the caller needs
Loading full entities when the caller uses only a few fields can transfer unnecessary columns and create extra materialization work. Project the required values into a result type:
var summaries = await db.Orders
.Where(order => order.Status == OrderStatus.Open)
.Select(order => new OrderSummary(order.Id, order.CreatedAt))
.ToListAsync();
Keep the filter and projection in the provider-translated portion of the query so the database can do the filtering and return only the selected fields. The actual SQL and plan depend on the provider and database.
Bound large results, but account for pagination costs
Unbounded queries can make the database read and the application transfer far more data than a screen or operation needs. Filtering and pagination help manage result sizes. However, pagination is not a guarantee of lower total latency: fetching pages separately can add roundtrips, and performance depends on the query, data, and access pattern. Inspect the plan and measure the real workflow rather than assuming that adding Take alone fixes it.
Rank #2
Check relationship loading for N+1 calls
Lazy loading can issue another query when each related collection is accessed. In a loop, this can create an N+1 pattern: one query for the parent records and additional queries for related data. Use projections, eager loading, or explicit loading when you need to make relationship fetching intentional. Eagerly joining multiple collections can instead produce a cartesian explosion; EF Core split queries may help in some cases, but can require additional roundtrips. Compare the SQL, transferred rows, and call count for the actual result shape.
Use no-tracking for suitable read-only work
For read-only queries where change tracking is not needed, a no-tracking query can avoid tracking overhead. Tracking and identity resolution have value when entities will be updated or duplicate entity instances need to be reconciled. Choose based on what the caller does with the results, not as a blanket performance switch.
Keep database-side work on the database
EF Core can translate only operations supported by its provider in the relevant query position. If you call AsEnumerable or begin asynchronous enumeration with AsAsyncEnumerable, subsequent operators run locally. That can be intentional, but it may also mean the database returns many rows that the application then filters or transforms.
Apply translatable filters and projections before crossing to client-side processing. Use local evaluation only when the result set is appropriately limited and the operation cannot or should not run in the database. See Microsoft’s guidance on client versus server evaluation in EF Core.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
For LINQ to Objects, control enumeration and materialization
Most LINQ operators that return a sequence use deferred execution: they describe work that runs when the sequence is enumerated. Scalar operations such as Count and First execute immediately. ToList and ToArray also execute immediately, buffering the results. Microsoft’s LINQ to Objects overview explains these execution patterns.
Avoid repeating expensive enumeration
Enumerating a deferred query twice can repeat its work; if its source changes between enumerations, the results may change too. Materialize once when you need to reuse a stable snapshot or avoid repeating expensive work:
Rank #4
var matches = source.Where(IsMatch).ToList();
var count = matches.Count;
var first = matches.FirstOrDefault();
Do not materialize reflexively just to chain another operator. If the sequence is consumed once, keeping it deferred can avoid allocating a list. The right choice depends on reuse, snapshot requirements, and memory cost.
Remember that deferred does not always mean streaming
Some deferred operators must consume substantial input before they can produce output. For example, OrderBy needs to inspect and sort the full input before yielding ordered results. The LINQ to XML documentation on deferred execution and lazy evaluation discusses this distinction. Consider both when execution starts and how much input an operator must process.
Choose buffering or streaming intentionally
ToList and ToArray buffer all returned results, making them convenient for reuse but requiring memory for the complete result. Async enumeration can stream results as they are read, which may suit large result sets when the consumer can process them incrementally. Streaming does not guarantee lower total time, and EF Core may buffer internally in particular situations, including with retrying execution strategies and some split-query cases. Account for the query shape and execution strategy when evaluating memory use.
Best Value
Use advanced EF Core optimizations only when measurements point there
EF Core caches query shapes, and parameterizing runtime values can allow reuse of query and database plans. Explicit compiled queries can reduce EF-side overhead on hot paths, but that does not eliminate database execution, I/O, or transfer costs. Context pooling is another advanced option to consider only if profiling shows EF-side overhead matters. Microsoft’s advanced performance guidance says to “benchmark on your platform before making any decisions.” Its documented benchmark examples are not universal guarantees.
If the provider cannot generate the database-specific operation you need, raw SQL, database functions, or views may be options. Raw SQL introduces maintenance costs, so Microsoft treats it as a last resort rather than a default speed trick.
Quick Recap
A practical troubleshooting sequence
- Classify execution: determine whether the query is LINQ to Objects or provider-backed, and where client-side processing begins.
- For EF Core, inspect SQL and the plan: look for scans where indexes should help, excess columns or rows, and relationship-loading queries that multiply calls.
- Reduce unnecessary work: project only needed properties, filter before client evaluation, and bound results where the workload permits.
- For LINQ to Objects, inspect consumption: check for repeated enumeration, full-input operators such as sorting, and materialization that is not needed for reuse or snapshot semantics.
- Measure the revised workflow: compare representative latency, allocations, rows and columns transferred, and database roundtrips on the target platform and data.
- Try advanced options only if the profile supports them: compiled queries or context pooling are candidates when EF-side overhead remains material after database costs are understood.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Recommended Free Tools

