You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Use Effect.retry with a Schedule to automatically retry failed operations with customizable delays and limits.
tags
getting-started
retry
schedule
error-recovery
beginner
rule
description
Retry failed operations with Effect.retry.
related
getting-started-handle-errors
control-repetition-with-schedule
scheduling-pattern-exponential-backoff
author
Paul Philp
Retry a Failed Operation with Effect.retry
Guideline
Use Effect.retry to automatically retry an Effect that fails. Combine it
with a Schedule to control how many times to retry and how long to wait
between attempts.
Rationale
Network requests fail. Databases time out. Services go down temporarily.
Instead of failing immediately, you often want to retry a few times.
Effect makes this a one-liner.
Simple Retry
import{Effect,Schedule}from"effect";// An operation that might failconstfetchData=Effect.tryPromise({try: ()=>fetch("https://api.example.com/data"),catch: ()=>newError("Network error"),});// Retry up to 3 timesconstwithRetry=Effect.retry(fetchData,Schedule.recurs(3));
Retry with Delay
import{Effect,Schedule}from"effect";constunreliableOperation=Effect.gen(function*(){constrandom=Math.random();if(random<0.7){returnyield*Effect.fail("Random failure");}return"Success!";});// Retry up to 3 times, waiting 1 second between attemptsconstwithDelay=Effect.retry(unreliableOperation,Schedule.recurs(3).pipe(Schedule.addDelay(()=>"1 second")));
Common Retry Patterns
import{Effect,Schedule}from"effect";constoperation=Effect.fail("temporary error");// Retry 5 times immediatelyconstquick=Effect.retry(operation,Schedule.recurs(5));// Retry 3 times with 1 second betweenconstspaced=Effect.retry(operation,Schedule.spaced("1 second").pipe(Schedule.intersect(Schedule.recurs(3))));// Retry with exponential backoff (1s, 2s, 4s, 8s...)constexponential=Effect.retry(operation,Schedule.exponential("1 second").pipe(Schedule.intersect(Schedule.recurs(5))));
Good Example: Retrying an API Call
import{Effect,Schedule,pipe}from"effect";classApiError{readonly_tag="ApiError";constructor(readonlystatus: number){}}constfetchUserData=(userId: string)=>Effect.tryPromise({try: async()=>{constresponse=awaitfetch(`/api/users/${userId}`);if(!response.ok)thrownewApiError(response.status);returnresponse.json();},catch: (error)=>errorasApiError,});// Retry up to 3 times with 500ms between attemptsconstfetchWithRetry=(userId: string)=>pipe(fetchUserData(userId),Effect.retry(Schedule.recurs(3).pipe(Schedule.addDelay(()=>"500 millis"))),Effect.catchAll((error)=>Effect.succeed({error: `Failed after retries: ${error._tag}`})));
Quick Reference
Schedule
Behavior
Schedule.recurs(3)
Retry 3 times immediately
Schedule.spaced("1 second")
Retry forever with 1s delay
Schedule.exponential("100 millis")
Exponential backoff
Schedule.forever
Retry indefinitely
Key Points
Effect.retry takes an Effect and a Schedule
Schedule controls the retry timing and count
Combine schedules with .pipe() for complex behavior
Still need error handling - retries might all fail
What's Next?
Learn exponential backoff for production systems
Learn Schedule combinators for complex retry logic