Files
lukaszraczylo bfb7e9875e feat(client): opt-in fasthttp transport (NewFastHTTPDoer)
Adds an alternative HTTPDoer backed by valyala/fasthttp for high-throughput
bots. Cuts per-call allocs from 102 to 56 in the cross-library bench
(within 8 of telego, which uses fasthttp by default), and per-call bytes
from 11.1 KiB to 6.6 KiB.

  bot := client.New(token,
      client.WithHTTPClient(client.NewFastHTTPDoer()),
  )

Implementation notes:
  - Wraps *fasthttp.Client behind the existing HTTPDoer (Do *http.Request)
    interface, so RetryDoer, custom transports, observability middleware,
    and the 1428 generated tests all keep working as-is.
  - Translates *http.Request -> fasthttp.Request once per call and
    returns a *http.Response whose Body releases the pooled fasthttp
    response on Close (net/http contract).
  - Recognises the bufferReadCloser / readerReadCloser shapes produced
    by buildRequest and passes their underlying bytes straight to
    SetBodyRaw -- no io.ReadAll, no copy.
  - Honours ctx.Deadline via DoDeadline, falls back to WithFastHTTPReadTimeout
    when no deadline is set. fasthttp.ErrTimeout maps to
    context.DeadlineExceeded for errors.Is compatibility.

Default stays net/http: fasthttp is HTTP/1.1 only, doesn't compose with
the http.RoundTripper middleware ecosystem, and most users don't have
the throughput to notice. Bots making thousands of API calls/sec should
opt in.

Multipart/file-upload path remains on net/http per the agreed scope --
the perf bottleneck was JSON-method round-trip, not file uploads.

Time numbers in the report deferred until a quiet-system bench run;
allocs/bytes numbers (which are deterministic per code path) are
already updated.
2026-05-10 23:07:04 +01:00
..

Cross-library benchmarks

Apples-to-apples micro-benchmarks comparing lukaszraczylo/go-telegram against the five most-starred Go Telegram libraries:

  • github.com/go-telegram-bot-api/telegram-bot-api/v5
  • gopkg.in/telebot.v3 (tucnak)
  • github.com/go-telegram/bot
  • github.com/mymmrac/telego
  • github.com/NicoNex/echotron/v3

Lives in its own Go module so competitor dependencies don't leak into the main repo's go.mod.

Run

go test -count=10 -bench=. -benchmem | tee results/raw.txt
go install golang.org/x/perf/cmd/benchstat@latest    # one-time
benchstat results/raw.txt > results/benchstat.txt

Hot paths covered

File Path
webhook_bench_test.go Decode small text-message Update from JSON
unmarshal_bench_test.go Decode large Update (entities + reply markup + photo array)
call_bench_test.go sendMessage round-trip against httptest.Server
dispatch_bench_test.go Route an Update through 20 registered handlers (worst-case match)

Fixtures

shared/fixtures.go defines the JSON payloads and the mock HTTP server. Every library decodes the same bytes; every round-trip hits the same canned response.

Latest results

See ../../docs/benchmarks/2026-05-10-comparison.md for the rendered comparison.