Skip to content
Effect Days 2026 Get your ticket

TxDeferred

Transactional deferred values for coordinating Effect transactions.

A TxDeferred<A, E> is a write-once cell whose completion is a Result<A, E> stored in transactional state. Readers can wait for the value from inside a transaction: while the cell is empty the transaction retries, and when another transaction completes the deferred the waiting transaction can resume with either the success value or the typed failure.

8 exports Added in v2.0.0 Source

Constructors

make

Added in v2.0.0 Source

Creates a new empty TxDeferred.

When to use

Use to create a transactional deferred that can be completed exactly once.

Signature

declare function make<A, E = never>(): Effect<TxDeferred<A, E>>

Example

(Creating a transactional deferred)

import { Effect, Option, TxDeferred } from "effect"
const program = Effect.gen(function*() {
const deferred = yield* TxDeferred.make<string, Error>()
return yield* TxDeferred.poll(deferred)
})
await Effect.runPromise(program) // => Option.none()

Getters

await

Added in v4.0.0 Source

Reads the deferred value. Retries the transaction if the deferred has not been completed yet.

Signature

declare function await<A, E>(self: TxDeferred<A, E>): Effect<A, E>

Example

(Awaiting a deferred value)

import { Effect, TxDeferred } from "effect"
const program = Effect.gen(function*() {
const deferred = yield* TxDeferred.make<number>()
yield* TxDeferred.succeed(deferred, 42)
return yield* TxDeferred.await(deferred)
})
await Effect.runPromise(program) // => 42

poll

Added in v2.0.0 Source

Reads the current state of the deferred without retrying. Returns None if not yet completed.

When to use

Use to inspect a TxDeferred without retrying when it is not completed yet.

Signature

declare function poll<A, E>(self: TxDeferred<A, E>): Effect<Option<Result<A, E>>>

Example

(Polling a deferred)

import { Effect, Option, Result, TxDeferred } from "effect"
const program = Effect.gen(function*() {
const deferred = yield* TxDeferred.make<number>()
const before = yield* TxDeferred.poll(deferred)
yield* TxDeferred.succeed(deferred, 42)
const after = yield* TxDeferred.poll(deferred)
return [before, after]
})
await Effect.runPromise(program) // => [Option.none(), Option.some(Result.succeed(42))]

Guards

isTxDeferred

Added in v4.0.0 Source

Determines if the provided value is a TxDeferred.

When to use

Use to narrow an unknown value before treating it as a transactional deferred.

Signature

declare function isTxDeferred(u: unknown): u is TxDeferred<unknown, unknown>

Example

(Checking transactional deferreds)

import { Effect, TxDeferred } from "effect"
const program = Effect.gen(function*() {
const deferred = yield* TxDeferred.make<number>()
return [TxDeferred.isTxDeferred(deferred), TxDeferred.isTxDeferred("not a deferred")]
})
await Effect.runPromise(program) // => [true, false]

Models

TxDeferred interface

Added in v4.0.0 Source

A transactional deferred is a write-once cell readable within transactions. Readers block (retry the transaction) until a value is committed, and writers succeed only on the first call; subsequent writes return false.

When to use

Use to coordinate transaction-local readers and one-time completion with a success or failure result.

Signature

interface TxDeferred<in out A, in out E = never> extends Inspectable, Pipeable {
readonly "~effect/transactions/TxDeferred": "~effect/transactions/TxDeferred";
readonly ref: TxRef<Option<Result<A, E>>>;
}

Example

(Completing a transactional deferred)

import { Effect, TxDeferred } from "effect"
const program = Effect.gen(function*() {
const deferred = yield* TxDeferred.make<number>()
// Complete the deferred
const first = yield* TxDeferred.succeed(deferred, 42)
// Second write is a no-op
const second = yield* TxDeferred.succeed(deferred, 99)
// Read the value
const value = yield* TxDeferred.await(deferred)
return [first, second, value]
})
await Effect.runPromise(program) // => [true, false, 42]

Mutations

done

Added in v2.0.0 Source

Completes the deferred with a Result. Returns true if this was the first completion, false if already completed.

When to use

Use to complete a TxDeferred with an already computed Result.

Signature

declare const done: {
<A, E>(result: Result<A, E>): (self: TxDeferred<A, E>) => Effect<boolean>;
<A, E>(self: TxDeferred<A, E>, result: Result<A, E>): Effect<boolean>;
}

Example

(Completing with a result)

import { Effect, Result, TxDeferred } from "effect"
const program = Effect.gen(function*() {
const deferred = yield* TxDeferred.make<number, string>()
const first = yield* TxDeferred.done(deferred, Result.succeed(42))
const second = yield* TxDeferred.done(deferred, Result.succeed(99))
return [first, second]
})
await Effect.runPromise(program) // => [true, false]

fail

Added in v2.0.0 Source

Completes the deferred with a failure. Returns true if this was the first completion, false if already completed.

When to use

Use to complete a TxDeferred with a typed failure value.

Signature

declare const fail: {
<E>(error: E): <A>(self: TxDeferred<A, E>) => Effect<boolean>;
<A, E>(self: TxDeferred<A, E>, error: E): Effect<boolean>;
}

Example

(Completing with a failure)

import { Cause, Effect, Exit, Option, TxDeferred } from "effect"
const program = Effect.gen(function*() {
const deferred = yield* TxDeferred.make<number, string>()
const first = yield* TxDeferred.fail(deferred, "boom")
const second = yield* TxDeferred.fail(deferred, "boom2")
const exit = yield* Effect.exit(TxDeferred.await(deferred))
return [first, second, exit, Exit.getCause(exit)]
})
await Effect.runPromise(program) // => [true, false, Exit.fail("boom"), Option.some(Cause.fail("boom"))]

succeed

Added in v2.0.0 Source

Completes the deferred with a success value. Returns true if this was the first completion, false if already completed.

When to use

Use to complete a TxDeferred with a successful value.

Signature

declare const succeed: {
<A>(value: A): <E>(self: TxDeferred<A, E>) => Effect<boolean>;
<A, E>(self: TxDeferred<A, E>, value: A): Effect<boolean>;
}

Example

(Completing with a success value)

import { Effect, TxDeferred } from "effect"
const program = Effect.gen(function*() {
const deferred = yield* TxDeferred.make<number>()
const first = yield* TxDeferred.succeed(deferred, 42)
const second = yield* TxDeferred.succeed(deferred, 99)
return [first, second]
})
await Effect.runPromise(program) // => [true, false]