# Telego Long Polling Retry Timeout: Configuration and Best Practices

> Configure Telego long polling retry timeout to optimize GetUpdates request retries. Learn best practices for managing timeouts and ensuring reliable Telegram bot communication.

- Repository: [Artem Yadelskyi/telego](https://github.com/mymmrac/telego)
- Tags: how-to-guide
- Published: 2026-03-07

---

**The `WithLongPollingRetryTimeout` option in Telego controls how long the library waits before retrying failed `GetUpdates` requests during long polling, defaulting to 8 seconds and disabling automatic retries when explicitly set to zero.**

Telego, the popular Go library for the Telegram Bot API available at `mymmrac/telego`, provides resilient long polling capabilities through granular configuration options. Understanding the **Telego long polling retry timeout** mechanism is essential for building bots that gracefully handle network interruptions without overwhelming Telegram's servers or your own infrastructure.

## What Is the Long Polling Retry Timeout?

The `WithLongPollingRetryTimeout` configuration option defines the **delay between retry attempts** when the `GetUpdates` method fails during long polling operations. This mechanism prevents aggressive retry storms while ensuring your bot recovers automatically from transient network failures.

According to the source code in [`long_polling.go`](https://github.com/mymmrac/telego/blob/main/long_polling.go), this value is stored in the `retryTimeout` field of the internal `longPolling` struct and is evaluated within the `doLongPolling` loop after each failed request.

## Default Behavior and Configuration

### Default Value (8 Seconds)

By default, Telego applies an **8-second retry timeout** defined by the constant `defaultLongPollingRetryTimeout`. This conservative delay balances quick recovery from transient errors with respectful API usage.

```go
lp := &longPolling{
    updateChanBuffer: defaultLongPollingUpdateChanBuffer,
    updateInterval:   defaultLongPollingUpdateInterval,
    retryTimeout:     defaultLongPollingRetryTimeout, // 8 seconds
}

```

*Source: [`long_polling.go`](https://github.com/mymmrac/telego/blob/main/long_polling.go) lines 58-62*

### Zero Value Behavior (Disables Retries)

Setting the retry timeout to `0` **completely disables automatic retries**. When `GetUpdates` encounters its first error, the update channel closes immediately and your bot stops polling.

```go
updates, err := bot.UpdatesViaLongPolling(
    ctx,
    nil,
    telego.WithLongPollingRetryTimeout(0), // disable retries
)

```

This mode is useful when you prefer to handle errors explicitly through external monitoring rather than automatic recovery.

### Negative Values (Validation Errors)

Telego validates the retry timeout during option processing. Passing a **negative duration** results in an immediate error: `"retry timeout is negative"`.

```go
func WithLongPollingRetryTimeout(retryTimeout time.Duration) LongPollingOption {
    return func(lp *longPolling) error {
        if retryTimeout < 0 {
            return fmt.Errorf("retry timeout is negative: %s", retryTimeout)
        }
        lp.retryTimeout = retryTimeout
        return nil
    }
}

```

*Source: [`long_polling.go`](https://github.com/mymmrac/telego/blob/main/long_polling.go) lines 45-55*

## How the Retry Timeout Works Internally

The retry mechanism operates within the `doLongPolling` function in [`long_polling.go`](https://github.com/mymmrac/telego/blob/main/long_polling.go). When a `GetUpdates` request fails, the logic evaluates the configured `retryTimeout`:

```go
if lp.retryTimeout == 0 || errors.Is(err, context.Canceled) {
    return
}
b.log.Errorf("Retrying getting updates in %s...", lp.retryTimeout.String())
time.Sleep(lp.retryTimeout)
continue

```

*Source: [`long_polling.go`](https://github.com/mymmrac/telego/blob/main/long_polling.go) lines 27-33*

This implementation ensures that:
- **Context cancellation** always exits immediately regardless of timeout settings
- **Zero timeout** prevents any retry attempts
- **Positive timeouts** trigger a sleep delay before the next request

## Practical Code Examples

### Using the Default 8-Second Timeout

The simplest implementation relies on Telego's built-in resilience:

```go
bot, _ := telego.NewBot("YOUR_TOKEN")
ctx := context.Background()

updates, _ := bot.UpdatesViaLongPolling(ctx, nil) // default 8s retry timeout
for update := range updates {
    // Process update
}

```

### Customizing the Retry Duration

For production environments with specific SLA requirements, specify a custom duration:

```go
updates, err := bot.UpdatesViaLongPolling(
    ctx,
    nil,
    telego.WithLongPollingRetryTimeout(5*time.Second), // 5 second retry
)
if err != nil {
    log.Fatal(err)
}

```

### Disabling Retries Entirely

For debugging or when implementing custom error handling at the application level:

```go
updates, err := bot.UpdatesViaLongPolling(
    ctx,
    nil,
    telego.WithLongPollingRetryTimeout(0), // disable automatic retries
)
if err != nil {
    log.Fatal(err)
}

// Channel closes immediately on first error
for upd := range updates {
    processUpdate(upd)
}
// Execution continues here after channel closes due to error

```

### Handling Channel Closure

Always implement proper channel handling to detect when retries are exhausted or disabled:

```go
for {
    select {
    case upd, ok := <-updates:
        if !ok {
            log.Println("Update channel closed, exiting")
            return
        }
        handleUpdate(upd)
    case <-ctx.Done():
        return
    }
}

```

## Interaction with Other Long Polling Options

The retry timeout operates independently from other configuration options:

- **`WithLongPollingUpdateInterval`**: Adds a fixed pause **between successful** polls, while `WithLongPollingRetryTimeout` controls delays **after failures**
- **`WithLongPollingBuffer`**: Defines the channel buffer size for incoming updates, unaffected by retry logic

Understanding these distinctions ensures you configure the polling loop holistically rather than treating options in isolation.

## Summary

- **`WithLongPollingRetryTimeout`** controls the delay between retry attempts when `GetUpdates` fails during Telego long polling
- The **default value is 8 seconds**, defined by `defaultLongPollingRetryTimeout` in [`long_polling.go`](https://github.com/mymmrac/telego/blob/main/long_polling.go)
- Setting the timeout to **zero disables automatic retries**, causing the update channel to close on the first error
- **Negative values** return validation errors during option processing
- The retry logic executes in the `doLongPolling` function, sleeping for the specified duration before subsequent requests
- This option works independently from `WithLongPollingUpdateInterval` (success delays) and `WithLongPollingBuffer` (channel sizing)

## Frequently Asked Questions

### What happens when Telego long polling retry timeout is set to zero?

When you pass `telego.WithLongPollingRetryTimeout(0)`, Telego **disables automatic retries entirely**. If the `GetUpdates` request fails for any reason other than context cancellation, the internal `doLongPolling` loop returns immediately, triggering deferred cleanup that closes the updates channel. Your application can detect this closure to implement custom error handling or shutdown procedures.

### How does Telego long polling retry timeout interact with update intervals?

The `WithLongPollingRetryTimeout` and `WithLongPollingUpdateInterval` options serve different phases of the polling cycle. The **update interval** adds a fixed sleep duration **between successful** `GetUpdates` requests to prevent aggressive polling. The **retry timeout** only activates **after failed** requests, controlling how long Telego waits before attempting recovery. These durations are not additive; they apply to mutually exclusive states in the polling loop.

### Can I set a negative retry timeout in Telego?

No, Telego explicitly **rejects negative durations** during option processing. The `WithLongPollingRetryTimeout` function validates the input and returns `fmt.Errorf("retry timeout is negative: %s", retryTimeout)` if you pass a value less than zero. This validation occurs before the long polling starts, ensuring that configuration errors surface immediately rather than during runtime execution.

### Where is the retry logic implemented in Telego?

The retry mechanism resides in the **`doLongPolling` function** within [`long_polling.go`](https://github.com/mymmrac/telego/blob/main/long_polling.go). After a failed `GetUpdates` call, the code checks `lp.retryTimeout` at lines 27-33. If the timeout is positive, the function logs the retry attempt, sleeps for the specified duration using `time.Sleep(lp.retryTimeout)`, and continues the loop. If the timeout is zero or the error is `context.Canceled`, the function returns and closes the updates channel.