# Caching

Most real programs repeat work: the same user is fetched twice, the same
configuration is parsed on every request, the same database connection is opened
by a dozen fibers at once. Effect's caching modules let you compute a value once
and reuse it — safely under concurrency, with control over lifetime, capacity,
and resource cleanup.

There are two families of tools here, and they solve different problems:

- **Memoizing values** — store the *result* of a lookup effect keyed by input.
  Concurrent misses for the same key share a single in-flight computation, and
  both successes and failures are cached. This is [`Cache`](https://effect.plants.sh/caching/cache/) (and
  `ScopedCache` when the cached values own resources).
- **Sharing resources** — store a *live resource* (a connection, client, or
  session) and track how many fibers are using it, releasing it automatically
  when the last borrower lets go. This is [`RcMap` and `RcRef`](https://effect.plants.sh/caching/reference-counting/).

A third tool, [`Resource`](https://effect.plants.sh/caching/resource/), sits in between: it keeps a
single value loaded in memory and lets you *refresh* it on demand or on a
schedule.

## Which tool do I reach for?

| You want to…                                                             | Use                                                          |
| ------------------------------------------------------------------------ | ----------------------------------------------------------- |
| Cache lookups by key, deduplicate concurrent misses, cap size with a TTL | [`Cache`](https://effect.plants.sh/caching/cache/)                                   |
| Cache lookups whose values acquire scoped resources                      | [`ScopedCache`](https://effect.plants.sh/caching/cache/)                             |
| Memoize a *single* effect (no key)                                       | `Effect.cached` — see [Cache](https://effect.plants.sh/caching/cache/)              |
| Share one scoped resource across many fibers, ref-counted                | [`RcRef`](https://effect.plants.sh/caching/reference-counting/)                      |
| Share scoped resources *by key*, ref-counted                             | [`RcMap`](https://effect.plants.sh/caching/reference-counting/)                      |
| Keep a value loaded and refresh it manually or on a schedule             | [`Resource`](https://effect.plants.sh/caching/resource/)                             |

## A first taste

The simplest cache is keyed by an input and backed by a lookup effect. Concurrent
requests for the same key only run the lookup once.

```ts
import { Cache, Effect } from "effect"

const program = Effect.gen(function*() {
  // A cache mapping user ids to (here, trivially computed) names.
  // The lookup runs at most once per key until the entry is evicted.
  const cache = yield* Cache.make({
    capacity: 1000,
    lookup: (id: number) => Effect.succeed(`user-${id}`)
  })

  const a = yield* Cache.get(cache, 1) // miss: runs the lookup
  const b = yield* Cache.get(cache, 1) // hit: returns the cached value
  return [a, b]
})
```

## In this section

- **[Cache and ScopedCache](https://effect.plants.sh/caching/cache/)** — memoize lookups by key, with
  capacity limits, fixed or dynamic TTLs, and scoped-resource variants. Also
  covers the no-key `Effect.cached` helpers.
- **[Reference counting](https://effect.plants.sh/caching/reference-counting/)** — `RcMap` and `RcRef`
  share scoped resources and release them when the last reference goes away.
- **[Resource](https://effect.plants.sh/caching/resource/)** — keep a single value loaded and refresh it
  manually or automatically with a [`Schedule`](https://effect.plants.sh/scheduling/).

<br />

Caching builds on a few concepts covered elsewhere: lookup functions are
ordinary [Effects](https://effect.plants.sh/essentials/), TTLs use [`Duration`](https://effect.plants.sh/data-types/), scoped
resources rely on [scopes](https://effect.plants.sh/resource-management/), and automatic refresh uses
[`Schedule`](https://effect.plants.sh/scheduling/).