# `Nous.HTTP.StreamBackend.Hackney`
[🔗](https://github.com/nyo16/nous/blob/v0.17.1/lib/nous/http/stream_backend/hackney.ex#L1)

`Nous.HTTP.StreamBackend` implementation backed by `:hackney` in
`[{:async, :once}]` mode for strict pull-based backpressure.

The consumer calls `:hackney.stream_next/1` to ask for one more chunk;
hackney reads it off the socket and delivers it as a single message
`{:hackney_response, conn, chunk_or_done}`. Because the network read
only happens when the consumer asks for it, the producer literally
cannot outrun the consumer — the mailbox stays bounded at one message
no matter how slow the consumer is.

Pick this backend when downstream consumers can block per chunk
(LiveView fan-out under load, persistence-on-every-chunk, slow IO).
For typical LLM workloads where token-generation rate is the
bottleneck, `Nous.HTTP.StreamBackend.Req` is simpler and equally fast.

## Hackney 4 option shape

Hackney 4 documents the pull-based form as `[{async, once}]` — a
**tuple**. The legacy `[:async, :once]` two-atom form silently puts
hackney into push mode (`proplists` resolves bare `:async` as
`{:async, true}`), which forfeits the backpressure guarantee. This
module uses the tuple form. See `deps/hackney/NEWS.md:255-275`.

## TLS verification

Passes `verify: :verify_peer` with system CAs from
`:public_key.cacerts_get/0` explicitly. Hackney's default is
`:verify_none`, which would silently accept MITM'd connections — do
not regress this.

## Pool

Uses hackney's `:default` pool (50 conns, 2s idle keepalive) unless
the caller passes `:pool`. Apps that want isolation can pass
`pool: :my_pool` per call after starting the pool with
`:hackney_pool.start_pool/2`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
