# State Management

Most programs need to keep track of something that changes over time: a counter,
an accumulated list, a cache, a connection pool. In ordinary imperative code you
would reach for a mutable variable — but as soon as that state is shared across
concurrent fibers, plain mutation becomes a source of lost updates and race
conditions.

Effect provides a small family of fiber-safe mutable references that let you keep
state without leaving the world of effects. Every read and write is an effect, so
state changes compose with the rest of your program and stay safe under
concurrency.

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

const program = Effect.gen(function*() {
  // A reference to a single mutable value, created inside an effect.
  const counter = yield* Ref.make(0)

  // Reads and writes are effects, so they sequence like any other step.
  yield* Ref.update(counter, (n) => n + 1)
  yield* Ref.update(counter, (n) => n + 1)

  return yield* Ref.get(counter) // 2
})
```

## Choosing a reference

The three references differ in what kind of update they serialize and whether
they let others observe changes. Pick the simplest one that fits.

- **[`Ref`](https://effect.plants.sh/state-management/ref/)** — a plain atomic cell. Each individual
  operation (`get`, `set`, `update`, `modify`) is atomic, which is enough for
  state whose next value is a *pure* function of the current value. This is what
  you reach for most of the time.

- **[`SynchronizedRef`](https://effect.plants.sh/state-management/synchronized-ref/)** — like `Ref`, but
  its update functions may themselves run effects, and those effectful updates are
  serialized so they never interleave. Use it when computing the next value
  requires an effect (a network call, a database lookup) that must not race with
  other updates.

- **[`SubscriptionRef`](https://effect.plants.sh/state-management/subscription-ref/)** — a reference you
  can *observe*. In addition to holding the current value, it exposes a
  [`Stream`](https://effect.plants.sh/streaming/) of changes, so other parts of the program can react to
  every update. Use it for shared state that drives a UI, a dashboard, or any
  reactive consumer.

## Notes on usage

Every reference operation is an effect, including construction with `make`, so a
reference is created inside an `Effect.gen` block or provided through a
[service](https://effect.plants.sh/services-and-layers/). A `Ref` is frequently wrapped in a service so
several subprograms can share the same state.

A single reference is always atomic for one operation, but a group of references
is not updated transactionally. When you need several pieces of state to change
together as one consistent unit, reach for [transactions
(STM)](https://effect.plants.sh/transactions/) instead.