> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.astropods.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.astropods.com/_mcp/server.

# Reconnection

#### Node

The Node SDK has a built-in reconnect loop on both `connectWithRetry()` and `createConversationStream()`. It retries with full-jitter exponential backoff and buffers writes until the stream is back.

```typescript
const conversation = client.createConversationStream({
  maxRetries: 20,
  initialDelayMs: 500,
  maxDelayMs: 30_000,
  jitter: true,
  maxBufferSize: 1000,
});

conversation.on('reconnecting', ({ attempt, delayMs }) => { /* … */ });
conversation.on('reconnected',  ({ attempt }) => { /* … */ });
```

**`ReconnectOptions`** (used by `connectWithRetry()` and `createConversationStream()`)

| Field                  | Type      | Default          | Notes                                                           |
| ---------------------- | --------- | ---------------- | --------------------------------------------------------------- |
| `maxRetries`           | number    | `Infinity`       | Cap on retry attempts.                                          |
| `initialDelayMs`       | number    | `500`            | Initial backoff delay.                                          |
| `maxDelayMs`           | number    | `30_000`         | Cap on backoff delay.                                           |
| `jitter`               | boolean   | `true`           | Full-jitter on the backoff delay.                               |
| `maxBufferSize`        | number    | `1000`           | Writes buffered while reconnecting.                             |
| `retryableStatusCodes` | number\[] | `[4, 8, 13, 14]` | DEADLINE\_EXCEEDED, RESOURCE\_EXHAUSTED, INTERNAL, UNAVAILABLE. |

#### Python

The Python SDK is the raw generated stub, with no built-in retry. Implement reconnect with your usual gRPC retry policy. Two common shapes:

1. **Channel-level retry** via the `grpc.service_config` JSON on the channel, applied to all RPCs.
2. **Wrapper loop** that re-establishes the stream on `grpc.RpcError` with `StatusCode.UNAVAILABLE` / `DEADLINE_EXCEEDED` / `INTERNAL` / `RESOURCE_EXHAUSTED`, with exponential backoff.

```python
import time, random, grpc

def stream_with_retry(stub, requests_factory, max_attempts=20):
    delay = 0.5
    attempt = 0
    while True:
        try:
            for resp in stub.ProcessConversation(requests_factory()):
                yield resp
            return  # clean end
        except grpc.RpcError as e:
            attempt += 1
            if attempt >= max_attempts:
                raise
            code = e.code()
            if code not in (
                grpc.StatusCode.UNAVAILABLE,
                grpc.StatusCode.DEADLINE_EXCEEDED,
                grpc.StatusCode.INTERNAL,
                grpc.StatusCode.RESOURCE_EXHAUSTED,
            ):
                raise
            time.sleep(min(delay, 30) * (0.5 + random.random() * 0.5))
            delay = min(delay * 2, 30)
```

## Next steps

* [The conversation stream](/messaging-sdk/conversation-stream): the stream this reconnects
* [Worked examples](/messaging-sdk/examples): `connectWithRetry` in a full agent