[API reference](https://evolu.dev/docs/api-reference) › [@evolu/common](https://evolu.dev/docs/api-reference/common) › [Task](https://evolu.dev/docs/api-reference/common/Task) › repeat

```ts
function repeat<T, E, D, Output>(
  task: Task<T, E, D>,
  schedule: Schedule<Output, T>,
  __namedParameters?: RepeatOptions<T, Output>,
): Task<T, E, D>;
```

Defined in: [packages/common/src/Task.ts:2133](https://github.com/evoluhq/evolu/blob/e7144e2bbe9069362b62dec1b64a8aa922b8f1b0/packages/common/src/Task.ts#L2133)

Repeats a [Task](https://evolu.dev/docs/api-reference/common/Task/type-aliases/Task) according to a [Schedule](https://evolu.dev/docs/api-reference/common/Schedule/type-aliases/Schedule).

Runs the Task, then checks the schedule to determine if it should repeat. The
schedule controls how many repetitions occur and the delay between them.
Continues until the schedule returns `Err(Done<void>)` or the Task fails.

With `take(n)`, the task runs n+1 times (initial run plus n repetitions).

Also works with [NextTask](https://evolu.dev/docs/api-reference/common/Task/type-aliases/NextTask) — when the Task returns `Err(Done<D>)`,
repeat stops and propagates the done signal.

### Example

```ts

// Heartbeat every 30 seconds (runs forever until aborted)
const heartbeat = repeat(sendHeartbeat, fixed("30s"));

// Poll 4 times total (initial + 3 repetitions), 1 second apart
const poll = repeat(checkStatus, take(3)(fixed("1s")));

// Process queue items until empty (NextTask pattern)
const processQueue: NextTask<Item, ProcessError, void> = async (run) => {
  const item = queue.dequeue();
  if (!item) return err(done()); // Queue empty, stop
  await process(item);
  return ok(item);
};

const result = await run(repeat(processQueue, fixed("100ms")));
if (!result.ok && result.error.type === "Done") {
  console.log("Queue exhausted");
}
```