# Sleep & Delays

Sleep pauses a task for a specified duration while freeing the worker slot. No resources are consumed during the wait, whether the pause lasts seconds or weeks.


Both durable tasks and DAGs support sleeping, but the API differs: durable tasks call `SleepFor` dynamically at runtime, while DAGs declare a sleep condition upfront on the task definition.

#### Durable Tasks

## Durable Sleep

Durable sleep pauses execution for a specified amount of time and frees the worker slot until the sleep expires.

> **Info:** Sleeping puts the task into an [evictable state](/v1/task-eviction), the
>   worker slot is freed and the task is re-queued when the sleep expires.

Unlike a language-level sleep (e.g. `time.sleep` in Python or `setTimeout` in Node), durable sleep is guaranteed to respect the original duration across interruptions. A language-level sleep ties the wait to the local process, so if the process restarts, the sleep starts over from zero.

For example, say you'd like to send a notification to a user after 24 hours. With `time.sleep`, if the task is interrupted after 23 hours, it will restart and sleep for 24 hours again (47 hours total). With durable sleep, Hatchet tracks the original deadline server-side, so the task will only sleep for 1 more hour on restart.

### Using durable sleep

Durable sleep can be used by calling the `SleepFor` method on the `DurableContext` object. This method takes a duration as an argument and will sleep for that duration.

#### Python

```python
@hatchet.durable_task(name="DurableSleepTask")
async def durable_sleep_task(input: EmptyModel, ctx: DurableContext) -> None:
    res = await ctx.aio_sleep_for(timedelta(seconds=5))

    print("got result", res)
```

#### Typescript

```typescript
durableSleep.durableTask({
  name: 'durable-sleep',
  executionTimeout: '10m',
  fn: async (_, ctx) => {
    console.log('sleeping for 5s');
    const sleepRes = await ctx.sleepFor('5s');
    console.log('done sleeping for 5s', sleepRes);

    return {
      Value: 'done',
    };
  },
});
```

#### Go

```go
task := client.NewStandaloneDurableTask("long-running-task", func(ctx hatchet.DurableContext, input DurableInput) (DurableOutput, error) {
	log.Printf("Starting task, will sleep for %d seconds", input.Delay)

	if _, err := ctx.SleepFor(time.Duration(input.Delay) * time.Second); err != nil {
		return DurableOutput{}, err
	}

	log.Printf("Finished sleeping, processing message: %s", input.Message)

	return DurableOutput{
		ProcessedAt: time.Now().Format(time.RFC3339),
		Message:     "Processed: " + input.Message,
	}, nil
})
```

#### Ruby

```ruby
DURABLE_SLEEP_TASK = HATCHET.durable_task(name: "DurableSleepTask") do |input, ctx|
  res = ctx.sleep_for(duration: 5)

  puts "got result #{res}"
end
```

#### DAGs

## Sleep Conditions

Sleep conditions pause a DAG task for a specified duration before it runs. Use them when a task should wait for a fixed amount of time after its parent tasks complete.

Unlike durable sleep (which is called dynamically at runtime), DAG sleep conditions are declared upfront on the task definition. Both free the worker slot during the wait.

### Using sleep conditions

Declare a task with a `wait_for` sleep condition. The task will wait for its parent tasks to complete, then sleep for the specified duration before executing.

#### Python

```python
@task_condition_workflow.task(
    parents=[start], wait_for=[SleepCondition(timedelta(seconds=10))]
)
def wait_for_sleep(input: EmptyModel, ctx: Context) -> StepOutput:
    return StepOutput(random_number=random.randint(1, 100))
```

#### Typescript

```typescript
const waitForSleep = taskConditionWorkflow.task({
  name: 'waitForSleep',
  parents: [start],
  waitFor: [new SleepCondition('10s')],
  fn: () => {
    return {
      randomNumber: Math.floor(Math.random() * 100) + 1,
    };
  },
});
```

#### Go

```go
waitForSleep := workflow.NewTask("wait-for-sleep", func(ctx hatchet.Context, _ any) (StepOutput, error) {
	return StepOutput{RandomNumber: rand.Intn(100) + 1}, nil //nolint:gosec
},
	hatchet.WithParents(start),
	hatchet.WithWaitFor(hatchet.SleepCondition(10*time.Second)),
)
```

#### Ruby

```ruby
WAIT_FOR_SLEEP = TASK_CONDITION_WORKFLOW.task(
  :wait_for_sleep,
  parents: [COND_START],
  wait_for: [Hatchet::SleepCondition.new(10)]
) do |input, ctx|
  { "random_number" => rand(1..100) }
end
```

This task will first wait for its parent to complete, then sleep for the specified duration before executing.

### Combining with other conditions

Sleep conditions can be combined with other conditions using or groups. For example, you can wait for _either_ a sleep duration or an event (whichever comes first). See [Combining Conditions](/v1/conditions#or-groups) for details.
