# Telego API Callers: FastHTTPCaller, HTTPCaller, and RetryCaller Explained

> Explore Telego API callers like FastHTTPCaller, HTTPCaller, and RetryCaller. Customize your Telegram Bot API requests for optimal performance and reliability.

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

---

**Telego provides three pluggable HTTP client implementations—FastHTTPCaller, HTTPCaller, and RetryCaller—that allow developers to customize how requests are sent to the Telegram Bot API.**

The `mymmrac/telego` library abstracts all network communication through a `Caller` interface, making it possible to swap between high-performance clients, standard library implementations, or retry-wrapped transports without modifying your bot logic. This article examines the three built-in callers and how to configure them for your specific latency, reliability, and testing requirements.

## Understanding the Caller Interface in Telego

At the heart of Telego’s networking layer is the `Caller` interface defined in [`telegoapi/api.go`](https://github.com/mymmrac/telego/blob/main/telegoapi/api.go) at line 73. This minimal contract ensures that any HTTP client can be plugged into the `Bot` struct.

```go
type Caller interface {
    Call(ctx context.Context, url string, data *RequestData) (*Response, error)
}

```

The `Call` method accepts a `context.Context` for cancellation, the target Telegram API URL, and a `RequestData` payload containing the method parameters. It returns a `Response` struct containing the `Ok` boolean, raw `Result` JSON, and error details. This abstraction allows `FastHTTPCaller`, `HTTPCaller`, and `RetryCaller` to be used interchangeably.

## Built-in Telego API Callers

Telego ships with three concrete implementations of the `Caller` interface, each optimized for different operational requirements.

### FastHTTPCaller for High-Performance Bots

`FastHTTPCaller` is the default transport in Telego, implemented in [`telegoapi/caller.go`](https://github.com/mymmrac/telego/blob/main/telegoapi/caller.go) at line 20. It leverages the `valyala/fasthttp` library, which provides significantly lower memory allocation and faster request processing compared to the standard library.

This caller is ideal for high-throughput bots handling hundreds of concurrent updates. It constructs `fasthttp.Request` objects, respects context cancellation via timeout settings, handles both raw and streamed request bodies, and unmarshals JSON responses using Telego’s internal JSON helper.

### HTTPCaller for Standard Library Compatibility

`HTTPCaller` provides a thin wrapper around Go’s standard `net/http` client, located in [`telegoapi/caller.go`](https://github.com/mymmrac/telego/blob/main/telegoapi/caller.go) at line 82. Use this implementation when your project already relies on the standard library’s HTTP transport, requires specific `http.Client` configurations (such as custom TLS settings or proxies), or when minimizing external dependencies is a priority.

The implementation creates standard `http.Request` objects, executes them via `http.Client.Do`, checks for server-level errors, and decodes the JSON response into the `Response` struct.

### RetryCaller for Automatic Retry Logic

`RetryCaller` is a decorator that adds configurable retry behavior to any underlying `Caller`, defined in [`telegoapi/caller.go`](https://github.com/mymmrac/telego/blob/main/telegoapi/caller.go) starting at line 34. The `Call` method implementation begins at line 74.

This caller supports exponential backoff with configurable `ExponentBase`, `StartDelay`, and `MaxDelay`. It handles three distinct rate-limiting strategies via the `RateLimit` field: `RetryRateLimitSkip` (continue without waiting), `RetryRateLimitAbort` (fail immediately), and `RetryRateLimitWait` (pause until the retry-after window expires).

When `BufferRequestData` is set to `true`, the caller buffers request bodies to allow safe retries of streaming data. This is essential when retrying multipart file uploads or large payloads.

## How to Configure Telego API Callers

You can inject these callers into your `Bot` instance using functional options defined in [`bot_options.go`](https://github.com/mymmrac/telego/blob/main/bot_options.go).

### Using the Default FastHTTPCaller

By default, Telego uses `FastHTTPCaller` automatically. No explicit configuration is required:

```go
bot, err := telego.NewBot(os.Getenv("TELEGRAM_TOKEN"))
if err != nil {
    log.Fatal(err)
}

// Uses DefaultFastHTTPCaller internally
_, err = bot.SendMessage(&telego.SendMessageParams{
    ChatID: telego.ChatID{ID: 123456789},
    Text:   "Hello from FastHTTPCaller!",
})

```

### Switching to the Standard HTTPCaller

To use the standard library client instead, pass the `WithHTTPCaller` option:

```go
bot, err := telego.NewBot(
    os.Getenv("TELEGRAM_TOKEN"),
    telego.WithHTTPCaller(),
)

```

### Adding Retry Logic with RetryCaller

Wrap any caller with `RetryCaller` to handle transient failures and rate limits:

```go
retryCaller := &telegoapi.RetryCaller{
    Caller:            telegoapi.DefaultFastHTTPCaller,
    MaxAttempts:       5,
    ExponentBase:      2.0,
    StartDelay:        200 * time.Millisecond,
    MaxDelay:          5 * time.Second,
    RateLimit:         telegoapi.RetryRateLimitWait,
    BufferRequestData: true,
}

bot, err := telego.NewBot(
    os.Getenv("TELEGRAM_TOKEN"),
    telego.WithCaller(retryCaller),
)

```

### Implementing a Custom Caller

For testing or alternative transports, implement the `Caller` interface. The [`telegoapi/mock/caller.go`](https://github.com/mymmrac/telego/blob/main/telegoapi/mock/caller.go) file demonstrates this pattern:

```go
type mockCaller struct{}

func (c *mockCaller) Call(ctx context.Context, url string, data *telegoapi.RequestData) (*telegoapi.Response, error) {
    return &telegoapi.Response{
        Ok:     true,
        Result: json.RawMessage(`{"message_id":42}`),
    }, nil
}

bot, err := telego.NewBot(
    os.Getenv("TELEGRAM_TOKEN"),
    telego.WithCaller(&mockCaller{}),
)

```

## Summary

- **FastHTTPCaller** (`telegoapi/caller.go#L20`) provides high-performance HTTP requests using the `fasthttp` library, making it the default choice for production bots with high request volumes.
- **HTTPCaller** (`telegoapi/caller.go#L82`) wraps the standard `net/http` client for compatibility with existing HTTP configurations and minimal external dependencies.
- **RetryCaller** (`telegoapi/caller.go#L34`) decorates any underlying caller with exponential backoff, configurable rate-limit strategies (`RetryRateLimitWait`, `RetryRateLimitAbort`, `RetryRateLimitSkip`), and request body buffering for resilient API communication.
- All callers implement the `Caller` interface defined in `telegoapi/api.go#L73`, allowing seamless substitution via `BotOptions` in [`bot_options.go`](https://github.com/mymmrac/telego/blob/main/bot_options.go) and [`bot.go`](https://github.com/mymmrac/telego/blob/main/bot.go).

## Frequently Asked Questions

### What is the default caller in Telego?

Telego uses `FastHTTPCaller` by default when you create a new bot instance without specifying caller options. This implementation leverages the `valyala/fasthttp` library for optimized memory usage and reduced latency. You can verify this in [`bot.go`](https://github.com/mymmrac/telego/blob/main/bot.go) where the default `BotOptions` initialize the `FastHTTPCaller` internally.

### When should I use FastHTTPCaller over HTTPCaller?

Choose `FastHTTPCaller` when your bot handles high concurrency or requires minimal memory allocation per request, as it outperforms the standard library in throughput benchmarks. Use `HTTPCaller` when you need specific `http.Client` configurations that are difficult to replicate with `fasthttp`, such as custom `Transport` layers, corporate proxy settings, or when you want to minimize external dependencies for security-audited environments.

### How does RetryCaller handle Telegram rate limits?

`RetryCaller` supports three rate-limit handling strategies via the `RateLimit` field: `RetryRateLimitWait` pauses execution until the retry-after window expires, `RetryRateLimitAbort` immediately returns the rate limit error without retrying, and `RetryRateLimitSkip` continues to the next retry attempt without waiting. For streaming requests like file uploads, you must set `BufferRequestData: true` to allow the body to be re-read during retries.

### Can I implement a custom caller for testing?

Yes, you can implement the `Caller` interface defined in [`telegoapi/api.go`](https://github.com/mymmrac/telego/blob/main/telegoapi/api.go) to create mock clients for unit testing. The [`telegoapi/mock/caller.go`](https://github.com/mymmrac/telego/blob/main/telegoapi/mock/caller.go) file provides a reference implementation showing how to return fabricated `Response` objects. Pass your custom caller using `telego.WithCaller()` when constructing the bot to isolate your tests from network dependencies and simulate specific API responses or error conditions.