Getting Started
Database Drivers
Schema Integrations
Seed Generators
Utilities and Testing
The following files were used as context for generating this wiki page:
Query Caching in Drizzle ORM provides a standardized mechanism to intercept database execution paths, checking a cache layer before executing a query against the underlying driver. This architecture decouples the database driver from the caching strategy, allowing for consistent query result memoization across diverse targets like PostgreSQL, MySQL, and SQLite.
The system is fundamentally driven by queryWithCache, a method typically exposed via the PreparedQuery classes of individual drivers. This method acts as a control-flow interceptor: it evaluates the current query and its parameters, checks if a cache hit exists, and either returns the cached data or proceeds to the provided driver execution callback to fetch fresh results and cache them.
By utilizing this abstraction, developers ensure that expensive or frequent read operations are optimized without modifying the core query execution logic. The integration relies on a Cache interface, defaulting to a NoopCache if no provider is specified, ensuring the system remains functional even without an explicit caching backend.
queryWithCache MechanismThe queryWithCache method is the core orchestrator. While the implementation varies slightly by driver, the pattern remains consistent: receive an execution task as an asynchronous callback, and wrap it with a cache lookup.
When a query is prepared, the caching configuration—including options for controlling the cache—is passed down to the prepared query instance. Upon execute(), the system invokes queryWithCache, passing the query string and parameters. The implementation effectively performs a check-then-store loop, where it first looks for the data in the provided cache instance. If the cache result is empty, the original client.query (or equivalent) is executed, and its result is pushed back into the cache for future requests.
// Example pattern found across multiple implementations (e.g., node-postgres)
return this.queryWithCache(rawQuery.text, params, async () => {
return await client.query(rawQuery, params);
});Sources: drizzle-orm/src/node-postgres/session.ts:148-150
Caching is initialized at the driver session level. Every session constructor accepts an optional options object containing a cache implementation. If a session is initiated without one, NoopCache is instantiated, providing a safe, no-operation interface that maintains structural compatibility without performing side effects.
Sources: drizzle-orm/src/singlestore/session.ts:13-18, drizzle-orm/src/bun-sql/session.ts:105-108
Prepared queries act as the container for caching configurations. When a query is executed, the resulting object is a PreparedQuery instance. During this instantiation, the cache configuration is injected into the constructor.
This is where the distinction between "raw" query execution and prepared execution occurs. In the execute path, the PreparedQuery uses its held configuration to determine how to interact with the cache orchestrator. By attaching this to the prepared query instance, Drizzle preserves the necessary state to execute the cached lookup at runtime, long after the original build-time configuration has passed.
Sources: drizzle-orm/src/singlestore/session.ts:236-248, drizzle-orm/src/postgres-js/session.ts:141-152
The driver-specific sessions are responsible for mapping the session-wide cache instance to the prepared queries they generate.
The dependency flow is:
Drizzle instance initialized with sessionOptions (including Cache).Session receives Cache and passes it to prepareQuery.PreparedQuery inherits the Cache reference.PreparedQuery.execute() calls this.queryWithCache(...).This hierarchy ensures that all queries executed within a single session instance utilize the same cache instance, enabling session-wide optimizations.
Sources: drizzle-orm/src/node-postgres/session.ts:233-246, drizzle-orm/src/neon-serverless/session.ts:220-233
The caching system is designed for maximum compatibility across disparate drivers, leading to the following trade-offs:
Sources: drizzle-orm/src/singlestore/session.ts:101-103, drizzle-orm/src/node-postgres/session.ts:208-219
Tip
Always check if your specific driver and database version support the prepared query format you are using, as some serverless drivers (like PlanetScale) may impose limitations on how queries are executed within transactions versus standard queries, potentially affecting the efficacy of the query cache.
NoopCacheThe NoopCache class implements the Cache interface with empty methods. This design ensures that the session-wide reference to a Cache object is always defined, preventing null-pointer exceptions in the PreparedQuery execution logic without requiring the user to explicitly handle cases where caching is disabled.
Sources: drizzle-orm/src/singlestore/session.ts:13-18