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

# Production checklist

> What a robust, cost-efficient Bloklake client does. Go through it before you ship.

## Use an official client

The [client libraries](https://docs.bloklake.com/clients.md) for TypeScript, Python and Rust already do most of this
checklist: pagination, prepared queries, retries with `Retry-After`, truncation checks and
amount encoding. If you use one, the items marked *(client)* are handled for you.

## Correctness

> [accordion] Loop on next\_block; never assume one response covers your range (client)
>
> Every response may end early: at 50,000 blocks, about 8 MB, `maxObjects` objects, or the head.
> Continue from `next_block` until it passes the end you want.
> [Pagination](https://docs.bloklake.com/querying/pagination.md)

> [accordion] Read the range you got, not the range you asked for
>
> `toBlock` past the head is lowered silently. Use `from_block`, `to_block` and `next_block`
> from the response.

> [accordion] Read every Arrow stream, then check the row count (client)
>
> A response has one stream per row type. Read `bl.streams` of them, and compare the total
> rows with `bl.objects` to catch a truncated body. [Reading Arrow](https://docs.bloklake.com/responses/reading-arrow.md)

> [accordion] Treat a dropped connection as a failure (client)
>
> The server closes the connection if a query fails mid-response. Discard partial results and
> retry. [Errors and retries](https://docs.bloklake.com/production/errors-and-retries.md)

> [accordion] Handle reorgs near the head
>
> Rows above `finalized_block` can change. Either only use finalized rows, or re-read the
> unfinalized tail on every poll. [Finality and reorgs](https://docs.bloklake.com/querying/finality-and-reorgs.md)

> [accordion] Pad addresses in topic filters
>
> An address in a topic is 32 bytes: `0x` + 24 zeros + the address.

> [accordion] Parse amounts as big integers
>
> `value` and other amounts are 128-bit (16 bytes in Arrow, decimal strings in JSON). They
> overflow 64-bit integers and JavaScript numbers. [Data types](https://docs.bloklake.com/responses/data-types.md)

> [accordion] Tell unavailable fields from real nulls
>
> A field in `unavailable_fields` is null on the whole chain; other nulls are real.
> [Fields a chain doesn't have](https://docs.bloklake.com/querying/unavailable-fields.md)

## Resilience

> [accordion] Retry 429, 503, 5xx and network errors with backoff; never retry 4xx blindly (client)
>
> Honor `Retry-After`. `400`, `401`, `402` and `403` need a fix, not a retry.

> [accordion] Handle unknown\_query\_id (client) and unknown\_set
>
> Prepared queries expire after 30 minutes unused; sets after 7 days, or sooner when a new set needs the room. Resend the filter or
> re-create the set, then retry.

> [accordion] Make jobs resumable
>
> Save `next_block` after each page you've stored. On restart, continue from it.

> [accordion] Alert on 402
>
> `balance_exhausted` and `overage_limit_reached` won't fix themselves. Page a person, and
> check `GET /v1/account` (free) before large jobs.

> [accordion] Log X-Request-Id
>
> Log the request id with every error. It's how we find your request in our logs.

## Cost and speed

> [accordion] Use /query (Arrow), not /query/json (client)
>
> The same rows cost 2–2.5× less and decode faster. [Arrow vs JSON](https://docs.bloklake.com/responses/arrow-vs-json.md)

> [accordion] Select only the fields you use
>
> `input`, `data`, `logsBloom` and `accessList` are large. Use `sighash` instead of `input` if you
> only need the function. [Selecting fields](https://docs.bloklake.com/querying/fields.md)

> [accordion] Filter on indexed fields as narrowly as you can
>
> Fewer matched rows means less data. Filter the rest client-side.

> [accordion] Use blockTimestamp instead of a blocks stream
>
> If you only need each log's time.

> [accordion] Use sets and prepared queries for repeated filters (prepared queries: client)
>
> Smaller requests, cached work on the server. [Sets](https://docs.bloklake.com/querying/sets.md),
> [Prepared queries](https://docs.bloklake.com/querying/prepared-queries.md)

> [accordion] Poll at the block time
>
> Faster polling returns empty responses that still count toward the rate limit and the
> 10 KB minimum. [Following the head](https://docs.bloklake.com/guides/follow-the-head.md)

> [accordion] Store finalized data; don't re-read it
>
> Finalized history never changes. Read it once.

> [accordion] Read responses promptly
>
> A response holds a query slot until it's read; slow readers are cut off. Read first, process
> after.

## Security

> [accordion] Keep keys on servers
>
> Never in browsers, mobile apps or repositories. Use a secret store.
> [API keys](https://docs.bloklake.com/account/api-keys.md)

> [accordion] Plan key rotations
>
> Rotating revokes the old key at once, so have the new key's deployment ready (or accept a
> short interruption) before you rotate. If a key leaks, rotate right away.
> [API keys](https://docs.bloklake.com/account/api-keys.md#rotating-a-key)

> [accordion] Separate projects for separate services
>
> Each gets its own keys, limits, usage and billing.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.