# Custom Timeouts (/sdks/csharp/how-to/connection/custom-timeouts)



## Overview [#overview]

Every client operation has an implicit deadline — how long to wait for the initial connection, how long before a dead socket is detected, how long a single RPC blocks before giving up, how long reconnection retries keep running. The defaults are reasonable for a healthy local network, but they're wrong for high-latency links, connections that pass through load balancers or NAT gateways, or servers that occasionally run slow under load. Tuning timeouts explicitly is how you trade fast-fail behavior against tolerance for transient slowness.

Each timeout targets a different phase of the client lifecycle. `ConnectionTimeout` bounds the initial connect, while `DefaultTimeout` bounds individual operations; `RetryPolicy` wraps transient failures with exponential backoff (`BackoffMultiplier`, `JitterMode`); `KeepaliveOptions.PingInterval` / `PingTimeout` configure gRPC HTTP/2 PING frames that detect a stale connection before you try to use it; and `ReconnectOptions` governs the delay and attempt budget for automatic reconnection. &#x2A;*Gotchas:** a `DefaultTimeout` shorter than the server's real processing time causes spurious failures, not faster detection of a genuinely broken operation; an aggressive `PingInterval` can flag a slow-but-healthy link as dead; and `ReconnectOptions.MaxAttempts = 0` means unlimited retries — fine for a client that should wait out any outage, but it will silently mask a server that's down for good unless you set a finite budget.

## Prerequisites [#prerequisites]

* KubeMQ server running on `localhost:50000`
* C# SDK installed (`dotnet add package KubeMQ.SDK.CSharp`)

## Code [#code]

```csharp title="Program.cs"
// KubeMQ .NET SDK — Config: Custom Timeouts and Retry Policy
//
// This example demonstrates configuring operation timeouts, retry policy,
// keepalive, and reconnection behavior.
//
// Prerequisites:
//   - KubeMQ server running on localhost:50000
//   - dotnet run

using KubeMQ.Sdk.Client;
using KubeMQ.Sdk.Config;

var options = new KubeMQClientOptions
{
    Address = "localhost:50000",
    ClientId = "csharp-config-custom-timeouts-client",

    // Operation timeouts
    DefaultTimeout = TimeSpan.FromSeconds(30),
    ConnectionTimeout = TimeSpan.FromSeconds(15),

    // Retry policy for transient failures
    Retry = new RetryPolicy
    {
        Enabled = true,
        MaxRetries = 5,
        InitialBackoff = TimeSpan.FromMilliseconds(500),
        MaxBackoff = TimeSpan.FromSeconds(30),
        BackoffMultiplier = 2.0,
        JitterMode = JitterMode.Full
    },

    // gRPC keepalive pings
    Keepalive = new KeepaliveOptions
    {
        PingInterval = TimeSpan.FromSeconds(15),
        PingTimeout = TimeSpan.FromSeconds(5),
        PermitWithoutStream = true
    },

    // Auto-reconnection
    Reconnect = new ReconnectOptions
    {
        Enabled = true,
        MaxAttempts = 0,   // 0 = unlimited
        InitialDelay = TimeSpan.FromSeconds(1),
        MaxDelay = TimeSpan.FromSeconds(30),
        BackoffMultiplier = 2.0
    }
};

await using var client = new KubeMQClient(options);

try
{
    await client.ConnectAsync();
    Console.WriteLine("Connected with custom configuration");
    Console.WriteLine($"  DefaultTimeout: {options.DefaultTimeout}");

    var info = await client.PingAsync();
    Console.WriteLine($"  Server info: {info}");
}
catch (Exception ex)
{
    Console.WriteLine($"Connection failed: {ex.Message}");
}

Console.WriteLine("Done.");

```

## How It Works [#how-it-works]

* `DefaultTimeout` and `ConnectionTimeout` set the per-operation and initial-connect deadlines; both accept any `TimeSpan`.
* `RetryPolicy` wraps transient failures with exponential backoff — `BackoffMultiplier = 2.0` with `JitterMode.Full` avoids thundering-herd storms at scale.
* `KeepaliveOptions.PingInterval` tells the gRPC channel to send HTTP/2 PING frames every 15 seconds so load balancers and firewalls don't drop idle connections.
* `ReconnectOptions.MaxAttempts = 0` means unlimited retries; set a positive value for finite retry budgets (e.g. during short maintenance windows).

## Related [#related]

* Getting started
* [C# SDK Reference](/sdks/csharp/reference)
* [Connect](/sdks/csharp/tutorials/connect)
* [Close](/sdks/csharp/how-to/connection/close)
