# DBX Connection Retry and Auto-Reconnect Mechanism: How It Handles Lost Database Connections

> DBX automatically retries database operations twice on connection loss. Learn how its retry and auto-reconnect mechanism ensures seamless query execution without intervention.

- Repository: [skyler/dbx](https://github.com/t8y2/dbx)
- Tags: internals
- Published: 2026-07-04

---

**TLDR:** DBX automatically retries database operations up to two times when it detects transient connection failures, using `retry_metadata_connection` in [`crates/dbx-core/src/schema.rs`](https://github.com/t8y2/dbx/blob/main/crates/dbx-core/src/schema.rs) to recreate connection pools and re-execute queries without user intervention.

The t8y2/dbx repository implements a resilient **connection retry and auto-reconnect mechanism** designed to mask transient network failures from end users. When a database connection drops due to temporary network glitches or brief server unavailability, DBX identifies retryable errors, tears down stale connection pools, and re-establishes connectivity before propagating only fatal errors to the application layer.

## How DBX Detects and Retries Transient Connection Failures

### The Core Retry Loop in `retry_metadata_connection`

The central retry logic resides in [[`crates/dbx-core/src/schema.rs`](https://github.com/t8y2/dbx/blob/main/crates/dbx-core/src/schema.rs)](https://github.com/t8y2/dbx/blob/main/crates/dbx-core/src/schema.rs), specifically within the `retry_metadata_connection` function. This wrapper executes metadata operations with a strict **two-attempt limit**—the initial call plus one automatic retry.

When a query fails, the function evaluates the error through `is_retryable_metadata_error`. If the error qualifies as transient, DBX immediately drops the existing driver pool, recreates it using identical connection parameters, and re-executes the original async closure. Non-retryable errors such as authentication failures or syntax errors propagate instantly without attempting a second connection.

### Identifying Retryable Errors with `is_retryable_metadata_error`

DBX distinguishes between recoverable network issues and permanent failures using the `is_retryable_metadata_error` helper. This function pattern-matches error strings against a whitelist of known transient indicators:

```rust
fn is_retryable_metadata_error(error: &str) -> bool {
    error.contains("Pool not found")
        || error.contains("connection reset by peer")
        || error.contains("ERROR: server closed the connection unexpectedly")
        // ... driver-specific patterns
}

```

Only errors matching these patterns trigger the recreation of the connection pool and the second execution attempt.

## Database-Specific Retry Strategies

DBX extends its core retry logic with database-specific adapters located in [[`crates/dbx-core/src/connection.rs`](https://github.com/t8y2/dbx/blob/main/crates/dbx-core/src/connection.rs)](https://github.com/t8y2/dbx/blob/main/crates/dbx-core/src/connection.rs).

### MongoDB Legacy Driver Fallback

For MongoDB deployments, the `should_retry_mongo_with_legacy_driver` helper detects when the modern driver fails to establish a connection. Before applying the standard retry logic, DBX automatically attempts to fall back to the legacy driver implementation, ensuring compatibility across different MongoDB server versions.

### Oracle Alternate Descriptor Configuration

When Oracle encounters listener failures, the `oracle_alternate_connect_config` function generates alternative connection descriptors with different host or port configurations. This allows DBX to retry connections against backup listeners without requiring manual intervention or configuration changes.

## Auto-Reconnect for Long-Running Queries and UI Integration

Beyond metadata queries, DBX maintains persistent connection state in [[`crates/dbx-web/src/state.rs`](https://github.com/t8y2/dbx/blob/main/crates/dbx-web/src/state.rs)](https://github.com/t8y2/dbx/blob/main/crates/dbx-web/src/state.rs). When a pool detects a disconnection, the WebSocket layer pushes real-time updates via [[`crates/dbx-web/src/sse.rs`](https://github.com/t8y2/dbx/blob/main/crates/dbx-web/src/sse.rs)](https://github.com/t8y2/dbx/blob/main/crates/dbx-web/src/sse.rs), notifying the frontend to re-issue queries automatically.

This architecture ensures that long-running queries in the web interface survive temporary network partitions without requiring users to manually refresh their browsers.

## Practical Usage Examples

DBX makes retry logic transparent to end users, but you can observe and configure this behavior through both CLI and programmatic interfaces.

### Command Line Interface

Run queries normally; DBX handles retries automatically:

```bash
dbx query "SELECT * FROM production_metrics" --connection postgres_prod

```

Enable debug logging to observe retry attempts:

```bash
DBX_LOG=debug dbx query "SELECT * FROM production_metrics"

```

Expected output shows the retry path:

```

[debug] Detected retryable error: "connection reset by peer"
[debug] Recreating connection pool for connection-id=42
[debug] Retry succeeded on second attempt

```

### Node.js SDK Implementation

When using the JavaScript SDK, retries happen internally:

```javascript
import { DBX } from '@dbx/client';

const dbx = new DBX({ connection: 'mysql_cluster' });

async function fetchData() {
  // Automatically retries on transient connection failures
  return await dbx.metadata.listSchemas();
}

```

### Rust Implementation

When working directly with the core library, you can leverage the retry wrapper:

```rust
use dbx_core::schema::retry_metadata_connection;

let result = retry_metadata_connection(pool, |conn| async {
    conn.query("SELECT * FROM users").await
}).await?;

```

## Summary

- **Two-attempt limit**: DBX retries failed operations once after the initial failure, preventing infinite loops while resolving transient network glitches.
- **Intelligent error detection**: `is_retryable_metadata_error` filters transient patterns like "connection reset by peer" from fatal authentication or syntax errors.
- **Pool recreation**: On retryable failures, DBX drops stale connections and rebuilds the connection pool automatically.
- **Driver-specific handling**: MongoDB and Oracle use specialized helpers (`should_retry_mongo_with_legacy_driver`, `oracle_alternate_connect_config`) for database-specific recovery.
- **UI synchronization**: The web layer ([`state.rs`](https://github.com/t8y2/dbx/blob/main/state.rs), [`sse.rs`](https://github.com/t8y2/dbx/blob/main/sse.rs)) propagates reconnection events to frontend clients via server-sent events.

## Frequently Asked Questions

### How many times does DBX retry a failed connection?

DBX implements a **two-attempt strategy**: one initial attempt plus one retry. This limit prevents excessive resource consumption while resolving the majority of transient network failures.

### Does DBX retry all database errors?

No. DBX only retries errors classified as transient by `is_retryable_metadata_error`. Permanent failures like authentication errors, permission denials, or SQL syntax errors propagate immediately without retry attempts.

### Can I disable automatic retries in DBX?

Currently, the retry mechanism is built into the core metadata and query execution layers without a configuration toggle. To effectively disable retries, you would need to modify the source code in [`crates/dbx-core/src/schema.rs`](https://github.com/t8y2/dbx/blob/main/crates/dbx-core/src/schema.rs) to bypass the `retry_metadata_connection` wrapper.

### How does DBX handle reconnection in the web interface?

When connections drop, the web backend ([`crates/dbx-web/src/state.rs`](https://github.com/t8y2/dbx/blob/main/crates/dbx-web/src/state.rs)) detects the failure and pushes reconnection events through server-sent events ([`crates/dbx-web/src/sse.rs`](https://github.com/t8y2/dbx/blob/main/crates/dbx-web/src/sse.rs)). The frontend receives these notifications and automatically re-establishes queries without requiring manual page refreshes.