A Prisma client abstraction that simplifies caching.
| Source | Shields |
|---|---|
| Project | |
| Health | |
| Publishers | |
| Repository | |
| Activity |
To implement a cache and divert the prisma client's internals we use readonly singleton instances for the client and cache:
import { Prisma } from 'cached-prisma';
const client1 = new Prisma().client;
const client2 = new Prisma().client;
client1 === client2;import { Prisma } from 'cached-prisma';
const cache1 = new Prisma().cache;
const cache2 = new Prisma().cache;
cache1 === cache2;Caches must implement safe read and write methods:
export type Maybe<T> = T | null;
export interface Cache {
read: (key: string) => Maybe<string>;
write: (key: string, value: string) => void;
}
export interface AsyncCache {
read: (key: string) => Promise<Maybe<string>>;
write: (key: string, value: string) => Promise<void>;
}To control the caching mechanism you can extend the Prisma class:
import { LruCache } from 'cached-prisma';
class CustomPrisma extends Prisma {
cacheFactory = () => new LruCache(10);
}The default cache is a fixed size queue that pops values as it surpasses its maximum length.
new LruCache(100);Memcached support is provided out of the box:
import { Memcached } from 'cached-prisma';
class CustomPrisma extends Prisma {
cacheFactory = () => new Memcached('127.0.0.1:11211', 10);
}Note that the second parameter to the Memcached constructor is the storage lifetime of each write in seconds.
We cache the following methods which do not mutate state:
- findUnique
- findMany
- findFirst
- queryRaw
- aggregate
- count
After any of the following state mutating methods we flush the cache:
- create
- createMany
- delete
- deleteMany
- executeRaw
- update
- updateMany
- upsert
If you provision a database and a memcached instance there is a crude performance profiler included as a sanity check:
tsc -p profilers
node dist/profilers/time.js1000 prisma reads:
┌─────────┬─────────────────┬─────────────┐
│ (index) │ 0 │ 1 │
├─────────┼─────────────────┼─────────────┤
│ 0 │ 'Without cache' │ 2.535861637 │
│ 1 │ 'LruMap cache' │ 0.080468443 │
│ 2 │ 'Memcached' │ 0.032572969 │
└─────────┴─────────────────┴─────────────┘
1000 prisma read and writes:
┌─────────┬─────────────────┬──────────────┐
│ (index) │ 0 │ 1 │
├─────────┼─────────────────┼──────────────┤
│ 0 │ 'Without cache' │ 10.244921313 │
│ 1 │ 'LruMap cache' │ 10.869037333 │
│ 2 │ 'Memcached' │ 9.9422369 │
└─────────┴─────────────────┴──────────────┘To run unit tests:
grunt testThis repository's documentation is hosted on readthedocs.
To run linters:
grunt lintTo run formatters:
grunt formatThis repository uses github actions to lint and test each commit. Formatting tasks and writing/generating documentation must be done before committing new code.
This repository adheres to semantic versioning standards. For more information on semantic versioning visit SemVer.
Bump2version is used to version and tag changes. For example:
bump2version patchPlease read this repository's CHANGELOG for details on changes that have been made.
Please read this repository's guidelines on CONTRIBUTING for details on our code of conduct and the process for submitting pull requests.
- Joel Lefkowitz - Initial work - Joel Lefkowitz
Lots of love to the open source community!

