---
title: Caching overview
description: Avoid repeated lookups by reusing values your app has already loaded.
pagination: false
sidebar:
  icon: zap
---

A cache temporarily stores a value so later requests can reuse it without repeating the original work. Product prices, search results, and calculated summaries are common examples. Keep the original data in your database or another source you can read again.

Use caching when a lookup is expensive and a slightly older result is acceptable. Skip it when every request must see the latest value.

> **Start here**
>
> Start with [Cache product prices](/guides/caching/cache-product-prices) for installation, a
> working lookup, and verification. Use [Define a cache](/docs/modules/caching/define) for
> configuration and the [Cache reference](/docs/api/cache) for exact contracts.

## Pre-setup

Use Redis in local Docker. Start from an existing RELKIT app and a running Docker daemon.

1. **Install Redis and Docker support**

    {/* Generated by apps/docs/scripts/generate.ts. Do not edit. */}

    From this guide's application/package root, install only its selected requirements:

    ```sh
    bun add @relkit/docker@0.7.12 @relkit/redis@0.8.1
    ```

    Keep these owner-specific versions and the lockfile together. Runtime SDKs belong in `dependencies`; build/type tooling belongs in `devDependencies`. Installing an adapter does not supply its optional SDK peers or enable the feature's configuration.

2. **Configure the requests profile**

    > **Merge with your application**
    >
    > The root configuration helper is [`defineApp`](/docs/learn/concepts/application), not
    > `defineConfig`. Merge the capability entries below into your existing `relkit.config.ts`; keep its
    > ID, environment, profiles, and other settings. The empty `defineEnv({})` in a standalone example
    > means this local provider needs no application variables. Keep your existing environment contract.

    ```ts title="relkit.config.ts"
    /** Local Redis supplies the connection for the requests cache profile. */
    import { defineApp, defineEnv } from "@relkit/app/config";
    import { docker } from "@relkit/docker";
    import { redis } from "@relkit/redis";

    export default defineApp({
      env: defineEnv({}),
      cache: { requests: docker(redis()) },
      defaults: { cache: "requests" },
    });
    ```

    The examples use `profile: "requests"`. Docker supplies the Redis connection; this path adds
    no `defineEnv` fields. If a scaffold used a different profile, align its `profile` with this
    configuration. [Connected Redis](/docs/modules/caching/define) uses an explicit secret binding.

3. **Check and start after defining the cache**

    Check Docker before continuing. After adding the resource and its service registration, run from the app root:

    ```sh title="Terminal — application root"
    docker version
    bun run check
    bun run typecheck
    bun run dev
    ```

    `check` validates the graph; it starts no containers. `dev` starts only Docker recipes used by
    that graph, waits for readiness, and binds their generated connection values. An unused profile
    alone does not start a container. Keep the server running and use `bun run relkit local status`
    in another terminal to inspect the services. [Local Docker](/docs/modules/integrations/local-docker)
    covers detached startup and stopping services while retaining their volumes.

## The Caching API

Usually, caching means connecting a Redis client, choosing keys, serializing values, and checking for missing entries. With RELKIT, define the key and value shapes, give your function access, and use `getOrSet()` to load missing values.

| API                                          | What you use it for                                    |
| -------------------------------------------- | ------------------------------------------------------ |
| [`defineCache`](/docs/api/cache#definecache) | Define the cache's keys, values, and expiration time.  |
| `dependencies.cache`                         | Give a function access to a cache.                     |
| `context.cache.prices.getOrSet(key, load)`   | Reuse a saved value or load and save it when missing.  |
| `context.cache.prices.set(key, value)`       | Save or replace a value.                               |
| `context.cache.prices.delete(key)`           | Remove a value so the next lookup can load fresh data. |

You can use caches in event functions too, and in ordinary functions called by jobs and tools.

## Try it in your app

Follow the [cached-price example](/guides/caching/cache-product-prices) for the first working cache. It runs
with Docker Redis and no cloud credentials. Use [Define a cache](/docs/modules/caching/define) when you need
to choose keys, values, and expiration for your own data.

After the separate [Inspector setup](/docs/modules/operations/inspector), open **Cache** and select your cache
to see keys and their remaining lifetime. Choose **View value** to inspect a saved value.
