Skip to main content

Command Palette

Search for a command to run...

Entity Framework Core - Caching L1 & L2

Published
3 min read

Caching in Entity Framework (EF) is a technique used to store data in memory to minimize database traffic and improve application performance. By reducing the number of round-trips to the database, you can significantly speed up data retrieval.

There are two distinct levels of caching in Entity Framework: First-Level (L1) and Second-Level (L2).


1. First-Level Caching (L1)

Scope: Per DbContext Instance

Status: Built-in and Enabled by Default

First-level caching is integral to how Entity Framework operates. It acts as a transaction buffer and an identity map.

  • How it works: When you query the database for an entity (e.g., User with ID 1), the DbContext stores that entity in its internal memory. If you request the same entity again within the same DbContext lifespan, EF will return the entity from memory rather than querying the database again.

  • Identity Resolution: It ensures that within a single context, only one object instance exists for a specific database record. This prevents inconsistencies where you might have two different objects representing the same row in the database.

  • Lifetime: The cache is destroyed as soon as the DbContext is disposed. In a typical web application, this means the cache lives only as long as the HTTP request.

Note: You can bypass L1 caching using .AsNoTracking(). This is useful for "read-only" scenarios where you don't need to update the data, making the query faster and using less memory.

2. Second-Level Caching (L2)

Scope: Global / Application-wide

Status: Requires Third-Party Configuration (in EF Core)

Second-level caching stores data across all DbContext instances. If User A retrieves a list of products, and then User B requests the exact same list, L2 caching allows User B to receive the data from the cache (e.g., Redis, Memory) without touching the database.

  • How it works: When a query is executed, an interceptor checks the cache provider (like Redis or in-memory cache).

    • Cache Hit: If the results are found, they are returned immediately.

    • Cache Miss: The query is executed against the database, and the results are then stored in the cache for future requests.

  • Implementation: Unlike L1, L2 caching is not built-in directly to the core of EF Core. You typically need to use a library (such as EFCoreSecondLevelCacheInterceptor) to enable this functionality.


Key Differences at a Glance

FeatureFirst-Level (L1)Second-Level (L2)
ScopeLocal (Current DbContext instance)Global (Application-wide)
DurationRequest/Context lifespanConfigurable (minutes, hours, etc.)
PurposeConsistency & Transaction IntegrityPerformance & Load Reduction
SetupAutomatic (No setup required)Manual (Requires external library)
StorageApplication Memory (RAM)Memory, Redis, SQL Server, etc.

When to Use Which?

Rely on L1 Caching when:

  • You are performing transactional updates.

  • You need to load an entity, modify it, and save it within a single request.

  • You want to ensure you are working with the absolute latest data during a complex operation.

Implement L2 Caching when:

  • You have data that changes infrequently (e.g., Country lists, Categories, Configuration settings).

  • You have high-traffic "read" pages where the database is becoming a bottleneck.

  • You are okay with slight data staleness (e.g., a user might see a product price update 5 minutes late).

Summary

  • L1 is about correctness and managing the transaction scope.

  • L2 is about speed and offloading work from the database server.

More from this blog

E

EF Core

31 posts