mcpField
E
effect-ts-concurrency

effect-ts-concurrency

github.com/mrevanzakDevelopment897 installsUpdated 40w ago
Repository

About effect-ts-concurrency

A skill guide to concurrency in Effect-TS for developers coordinating parallel work, background fibers, or rate-limited operations. It covers bounded parallelism and signaling with semaphores and Deferred.

Key features

  1. 01Bounded parallel execution
  2. 02Fiber-based background work
  3. 03Semaphore-based concurrency limits
  4. 04Deferred-based signaling

Use cases

  1. 01Processing collections with a concurrency cap
  2. 02Limiting API or database request rates
  3. 03Coordinating background tasks
  4. 04Signaling between concurrent operations

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/mrevanzak/effect-ts-skills --skill effect-ts-concurrency

After installing, type/effect-ts-concurrencyin Claude Code to confirm it loaded.

Details

From the project README

Effect-TS Concurrency

Overview

Effect-TS provides lightweight fibers for high-performance concurrency. The core principle is explicit control: always bound parallelism to prevent resource exhaustion.

When to Use

  • Processing large arrays of effects (e.g., Effect.all, Effect.forEach)
  • Rate limiting external API calls or database connections
  • Coordinating work between background processes (fibers)
  • Signaling completion or state changes across different parts of the app

When NOT to use:

  • Simple sequential operations
  • When standard Promise.all is sufficient (though Effect is usually preferred for consistency)

Core Pattern: Bounded Parallelism

Unbounded parallelism is the most common source of "Too many open files" or "Connection timeout" errors.

PatternImplementationResult
BADEffect.all(effects)Unbounded - crashes on large inputs
GOODEffect.all(effects, { concurrency: 10 })Bounded - safe and predictable

Quick Reference

ToolPurposeKey Method
FiberBackground executionEffect.fork / Fiber.join
SemaphoreBounded concurrency / Rate limitingsemaphore.withPermits(n)
DeferredOne-shot signaling / PromisesDeferred.await / Deferred.succeed
concurrencyOption for all, forEach, mapEffect`{ concurrency: number

Implementation

1. Bounded Parallelism (Critical)

Always specify concurrency when processing collections.

import { Effect } from 'effect';

// Process 1000 items, max 10 concurrent
const results = yield* Effect.all(
  items.map(processItem),
  { concurrency: 10 }
);
2. Semaphore for Rate Limiting

Use a Semaphore when multiple independent operations must share a global limit.

import { Effect } from 'effect';

const program = Effect.gen(function* () {
  const semaphore = yield* Effect.makeSemaphore(5); // Max 5 concurrent
  
  yield* Effect.all(
    requests.map((req) => 
      semaphore.withPermits(1)(handleRequest(req))
    ),
    { concurrency: 'unbounded' } // Semaphore controls actual concurrency
  );
});
3. Deferred for Signaling

Use Deferred to wait for a specific event or value from another fiber.

import { Deferred, Effect, Fiber } from 'effect';

const program = Effect.gen(function* () {
  const signal = yield* Deferred.make<void>();
  
  const worker = yield* Effect.fork(
    Effect.gen(function* () {
      yield* Deferred.await(signal); // Wait for signal
      yield* doWork();
    })
  );
  
  yield* setup();
  yield* Deferred.succeed(signal, undefined); // Trigger worker
  yield* Fiber.join(worker);
});

Common Mistakes

  • Unbounded parallelism: Forgetting { concurrency: n } in Effect.all.
  • Leaking Fibers: Forking fibers without joining or interrupting them (use Effect.scoped for safety).
  • Deadlocks: Circular dependencies between semaphores or deferreds.

Red Flags - STOP and Start Over

  • Using Effect.all on a large array without { concurrency: n }.
  • Using Promise.all inside an Effect-TS codebase.
  • Manual setTimeout for rate limiting instead of Effect.makeRateLimiter or Semaphore.

Rationalization Table

ExcuseReality
"It's only 100 items"100 items today, 10,000 tomorrow. Bound it now.
"The API is fast"Network latency and server load are unpredictable.
"I'll add concurrency later"Unbounded parallelism is a ticking time bomb.

REQUIRED BACKGROUND: See effect-ts-anti-patterns for more on unbounded parallelism.

Comments

Markdown supported