TypeOrm
  • Getting Started
  • About
  • Connection
    • Working with Connection
    • Using ormconfig.json
    • Connection Options
    • Multiple connections
    • Connection APIs
  • Entity
    • What is Entity?
    • Embedded Entities
    • Entity Inheritance
    • Tree Entities
    • View Entities
    • Separating Entity Definition
  • Relations
    • What are Relations?
    • One-to-One
    • Many-to-one and One-to-Many
    • Many-to-Many
    • Eager and Lazy Relations
    • Relations FAQ
  • Entity Manager and Repository
    • What is EntityManager
    • Working with Repository
    • Find Options
    • Custom Repositories
    • Entity Manager API
    • Repository API
  • Query Builder
    • Select using Query Builder
    • Insert using Query Builder
    • Update using Query Builder
    • Delete using Query Builder
    • Working with Relations
    • Caching Results
  • Advanced Topics
    • Using CLI
    • Logging
    • Listeners and Subscribers
    • Indices
    • Transactions
    • Migrations
  • Guides
    • Active Record vs Data Mapper
    • Working with MongoDB
    • Using Validation
    • Example with Express
    • Usage with JavaScript
    • Migration from Sequelize
  • Help
    • FAQ
    • Supported Platforms
    • Decorators reference
    • Roadmap
    • Changelog
Powered by GitBook
On this page

Was this helpful?

  1. Query Builder

Caching Results

Caching queries

You can cache results selected by these QueryBuilder methods: getMany, getOne, getRawMany, getRawOne and getCount.

You can also cache results selected by these Repository methods: find, findAndCount, findByIds, and count.

To enable caching you need to explicitly enable it in your connection options:

{
    type: "mysql",
    host: "localhost",
    username: "test",
    ...
    cache: true
}

When you enable cache for the first time, you must synchronize your database schema (using CLI, migrations or the synchronize connection option).

Then in QueryBuilder you can enable query cache for any query:

const users = await connection
    .createQueryBuilder(User, "user")
    .where("user.isAdmin = :isAdmin", { isAdmin: true })
    .cache(true)
    .getMany();

Equivalent Repository query:

const users = await connection
    .getRepository(User)
    .find({
        where: { isAdmin: true },
        cache: true
    });

This will execute a query to fetch all admin users and cache the results. Next time you execute the same code, it will get all admin users from the cache. Default cache lifetime is equal to 1000 ms, e.g. 1 second. This means the cache will be invalid 1 second after the query builder code is called. In practice, this means that if users open the user page 150 times within 3 seconds, only three queries will be executed during this period. Any users inserted during the 1 second cache window won't be returned to the user.

You can change cache time manually via QueryBuilder:

const users = await connection
    .createQueryBuilder(User, "user")
    .where("user.isAdmin = :isAdmin", { isAdmin: true })
    .cache(60000) // 1 minute
    .getMany();

Or via Repository:

const users = await connection
    .getRepository(User)
    .find({
        where: { isAdmin: true },
        cache: 60000
    });

Or globally in connection options:

{
    type: "mysql",
    host: "localhost",
    username: "test",
    ...
    cache: {
        duration: 30000 // 30 seconds
    }
}

Also, you can set a "cache id" via QueryBuilder:

const users = await connection
    .createQueryBuilder(User, "user")
    .where("user.isAdmin = :isAdmin", { isAdmin: true })
    .cache("users_admins", 25000)
    .getMany();

Or with Repository:

const users = await connection
    .getRepository(User)
    .find({
        where: { isAdmin: true },
        cache: {
            id: "users_admins",
            milliseconds: 25000
        }
    });

This gives you granular control of your cache, for example, clearing cached results when you insert a new user:

await connection.queryResultCache.remove(["users_admins"]);

By default, TypeORM uses a separate table called query-result-cache and stores all queries and results there. Table name is configurable, so you could change it by specifying a different value in the tableName property. Example:

{
    type: "mysql",
    host: "localhost",
    username: "test",
    ...
    cache: {
        type: "database",
        tableName: "configurable-table-query-result-cache"
    }
}

If storing cache in a single database table is not effective for you, you can change the cache type to "redis" or "ioredis" and TypeORM will store all cached records in redis instead. Example:

{
    type: "mysql",
    host: "localhost",
    username: "test",
    ...
    cache: {
        type: "redis",
        options: {
            host: "localhost",
            port: 6379
        }
    }
}

In case you want to connect to a redis-cluster using IORedis's cluster functionality, you can do that as well by doing the following:

{
    type: "mysql",
    host: "localhost",
    username: "test",
    cache: {
        type: "ioredis/cluster",
        options: {
            startupNodes: [
                {
                    host: 'localhost',
                    port: 7000,
                },
                {
                    host: 'localhost',
                    port: 7001,
                },
                {
                    host: 'localhost',
                    port: 7002,
                }
            ],
            options: {
                scaleReads: 'all',
                clusterRetryStrategy: function (times) { return null },
                redisOptions: {
                    maxRetriesPerRequest: 1
                }
            }
        }
    }
}

Note that, you can still use options as the first argument of IORedis's cluster constructor.

{
    ...
    cache: {
        type: "ioredis/cluster",
        options: [
            {
                host: 'localhost',
                port: 7000,
            },
            {
                host: 'localhost',
                port: 7001,
            },
            {
                host: 'localhost',
                port: 7002,
            }
        ]
    },
    ...
}

If none of the built-in cache providers satisfy your demands, then you can also specify your own cache provider by using a provider factory function which needs to return a new object that implements the QueryResultCache interface:

class CustomQueryResultCache implements QueryResultCache {
    constructor(private connection: Connection) {}
    ...
}
{
    ...
    cache: {
        provider(connection) {
            return new CustomQueryResultCache(connection);
        }
    }
}

You can use typeorm cache:clear to clear everything stored in the cache.

PreviousWorking with RelationsNextAdvanced Topics

Last updated 4 years ago

Was this helpful?

"options" can be or depending on what type you're using.

node_redis specific options
ioredis specific options