# Production readiness

Source: https://docs.graphops.xyz/production-readiness

Launch with credentials you can replace, data you can trust, and failures you can diagnose and
recover from. Work through this checklist with your team after your first successful request, then
follow your service's usage and troubleshooting pages for protocol-specific decisions.

_Six areas to check before production traffic, in the order of this page. Each section below lists the full checklist for its area._

- Credentials and access: A separate key per workload and environment.
- Billing, credits, and limits: Monthly credits sized and automatic top-ups on.
- Data correctness: Block references, _meta and committed cursors.
- Timeouts and retries: Bounded backoff with a retry budget.
- Observability: Enough context to diagnose, never secrets.
- Recovery: Tested reconnects, rotation and support path.

## Credentials and access

* Create a separate API key for each environment and workload, with a label that names it.
* Store keys in a secret manager or server-side runtime configuration.
* Keep keys out of logs, analytics events, support messages, and source control.
* Ship a key to the browser only as a [browser key](/platform/api-keys#use-a-key-in-a-browser):
every service on it limited to your production site's origins and to what it queries, separate
from the keys your servers use.
* Confirm each production key belongs to the intended organization and includes only the services
its workload uses, [limited](/platform/api-keys#limit-a-key) to the networks or Subgraphs it
queries.
* Decide who can rotate and revoke production keys, and test a rotation before launch.

See [API keys](/platform/api-keys) and the authentication page for your service.

## Billing, credits, and limits

* Size your [monthly credits](/platform/billing-and-credits#choose-your-monthly-credits) to cover
launch traffic.
* Turn on [automatic top-ups](/platform/billing-and-credits#automatic-top-ups) with a spending limit
you are comfortable with, so a traffic spike adds credits instead of pausing your services. At zero
or below, requests pause and return `403` with the code `credits_exhausted`.
* Set [low-credit alerts](/platform/billing-and-credits#get-notified-before-credits-run-low)
so the right people hear before the balance runs out.
* Check your [organization limits](/platform/billing-and-credits#organization-limits) for API keys
and Managed Subgraphs, and ask support for an increase before you need it.
* Read your service's usage page before choosing concurrency, batch size, or backfill strategy.
* Treat access (`403`) and limit responses as configuration or billing problems; do not retry them
indefinitely.

[Open billing](https://platform.graphops.xyz/organizations/current/billing)

## Data correctness

Decide how fresh and how stable each result must be, then use the service's tool for it.

| Service    | Correctness decision                                                                                |
| ---------- | --------------------------------------------------------------------------------------------------- |
| RPC        | Anchor multi-request workflows to an explicit block number, hash, `safe`, or `finalized` reference. |
| Subgraphs  | Inspect `_meta` when indexing freshness or indexing errors affect the result.                       |
| Substreams | Persist cursors only after committing output, and handle undo signals for reversible data.          |

## Timeouts and retries

_Retry only failures that can succeed unchanged, with bounded backoff, jitter and a retry budget. Authentication, access and validation failures need a configuration, billing or request fix first. A Substreams consumer resumes from its last committed cursor instead._

Retry with backoff and jitter:

- Timeouts and dropped connections
- 429 Too Many Requests
- 502, 503 and 504

Fix before sending again:

- 401: missing or invalid API key
- 403: organization access paused, such as when credits run out
- Malformed or invalid requests

* Set explicit connection and request timeouts.
* Retry transient failures with bounded exponential backoff and jitter.
* Respect server retry guidance when a response supplies it.
* Give each workflow a retry budget so a downstream failure cannot create unbounded traffic.
Successful retries can count as additional usage.

## Observability

Record enough context to diagnose a failed request without recording secrets. One structured entry
per failed attempt is enough to answer most support questions:

A reference template for a structured log entry for a failed RPC request. It identifies the organization, key, network and attempt without recording the key itself. Use the same fields for any service.

```json
{
  "time": "2026-10-21T14:03:12Z",
  "service": "rpc",
  "organization": "acme-production",
  "apiKeyLabel": "production-indexer",
  "endpoint": "/v1/evm/1",
  "status": 429,
  "error": "Too Many Requests",
  "requestId": "<REQUEST_ID>",
  "attempt": 2
}
```

- UTC timestamp
- GraphOps service
- Organization name or ID
- Key label, never the key
- Network or endpoint path
- HTTP or gRPC status
- Safe error detail
- When the response supplies one
- Retries used from the budget

For Subgraphs, record the Endpoint Alias or Deployment CID and
`_meta.block.number`. For Substreams, record the package, module, and last committed cursor or
block when it is safe to share.

## Recovery

* Define what each client does after a disconnect or partial workflow failure.
* Make writes and materialization steps idempotent wherever a retry can repeat work.
* Test the troubleshooting path for each service you use.
* Decide who contacts [GraphOps support](https://platform.graphops.xyz/organizations/current/overview?support=open)
and which sanitized details they provide.

## Next steps

* [RPC usage and limits](/rpc/usage-and-limits): Plan requests, batches, WebSockets, and retries.
* [Subgraphs usage and limits](/subgraphs/usage-and-limits): Plan query complexity, indexing checks, and retries.
* [Substreams usage and limits](/substreams/usage-and-limits): Plan streams, backfills, cursors, and output volume.
* [Support and status](/platform/support-and-status): Know what to include when you need help.