> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tensorlake.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Timeouts

> How function timeouts work and how progress updates reset them

Agents can take an unpredictable amount of time to do their work — an LLM tool-calling loop might finish in seconds or run for hours depending on the task. Tensorlake handles this by letting functions run indefinitely as long as they keep sending heartbeats in the form of progress updates. A timeout only kicks in if a function stops making progress — it doesn't finish within the allotted time *and* it doesn't send any progress updates to reset the clock.

## Setting Timeouts

Set the `timeout` attribute on the `@function()` decorator to control how long a function can run before it is terminated and marked as failed.

```python theme={null}
from tensorlake.applications import function

@function(timeout=1800)  # 30 minutes
def deep_research(prompt: str) -> str:
    ...
```

|             | Value               |
| ----------- | ------------------- |
| **Default** | `300` (5 minutes)   |
| **Minimum** | `1` second          |
| **Maximum** | `172800` (48 hours) |

When a function times out, it is terminated and marked as failed. If the function has a [retry policy](/applications/retries), it will be retried according to that policy. Already-completed nested calls are served from checkpoints on retry — see [Durable Execution](/applications/durability).

## Automatic Timeout Reset

When a function reports progress via `ctx.progress.update()`, its timeout automatically resets. This allows functions to run indefinitely as long as they continue making progress.

```python theme={null}
from tensorlake.applications import function, RequestContext

@function(timeout=300)  # 5 minute timeout
def long_running_task(items: list) -> dict:
    ctx = RequestContext.get()

    # After 3 minutes of processing...
    ctx.progress.update(50, 100, "Halfway done")

    # Timeout just reset to 5 minutes from NOW
    # Function can run another 5 minutes before next update

    # Continue processing...
```

**Timeline:**

1. Function starts with 5 minute timeout
2. At 3 minutes: `progress.update()` called
3. Timeout resets to 5 minutes from this point
4. Function can now run until minute 8 (3 + 5)
5. Next `progress.update()` resets timeout again

<Tip>Set a short timeout (e.g., 5 minutes) and rely on progress updates to extend it. This way, if a function gets stuck and stops reporting progress, it fails fast instead of running silently for hours.</Tip>

## Examples

### Agent Loops

An agent that runs hundreds of iterations can use a short timeout per iteration. Each progress update resets the clock:

```python theme={null}
@function(timeout=300)  # 5 minute timeout per iteration
def persistent_agent(task: str) -> str:
    ctx = RequestContext.get()

    for iteration in range(1000):
        ctx.progress.update(iteration, 1000)  # resets timeout
        result = agent_iteration(task)
        if is_complete(result):
            return result
```

### Batch Processing

Process an unbounded stream of items. The function runs as long as items keep arriving:

```python theme={null}
@function(timeout=600)  # 10 minute timeout
def process_stream(stream_url: str) -> dict:
    ctx = RequestContext.get()
    count = 0

    for item in stream_items(stream_url):
        ctx.progress.update(count, count + 1, f"Processed {count} items")
        process(item)
        count += 1

    return {"total": count}
```

### Video/Audio Processing

Report progress every N frames to keep the timeout from firing during long media processing:

```python theme={null}
@function(timeout=300)
def process_video(video_url: str) -> str:
    ctx = RequestContext.get()

    frames = extract_frames(video_url)
    total_frames = len(frames)

    for i, frame in enumerate(frames):
        if i % 100 == 0:
            ctx.progress.update(i, total_frames, f"Processing frame {i}/{total_frames}")
        process_frame(frame)

    return "complete"
```

## Learn More

<CardGroup cols={2}>
  <Card title="Streaming Progress" icon="signal-stream" href="/applications/guides/streaming-progress">
    The full progress API, frontend integration, and SSE streaming.
  </Card>

  <Card title="Retries & Rate Limits" icon="rotate" href="/applications/retries">
    What happens after a timeout fires — auto-retry with checkpoint reuse.
  </Card>

  <Card title="Crash Recovery" icon="shield-check" href="/applications/crash-recovery">
    Resume a request from where it timed out instead of restarting.
  </Card>

  <Card title="Durable Execution" icon="clock-rotate-left" href="/applications/durability">
    How nested completed calls are reused across timeout-triggered retries.
  </Card>

  <Card title="Error Handling" icon="triangle-exclamation" href="/applications/error-handling">
    Catch timeouts in caller code and degrade gracefully.
  </Card>

  <Card title="SDK Reference" icon="rectangle-code" href="/applications/concepts">
    Functions, retries, resource limits, and request context.
  </Card>
</CardGroup>
