---
title: "C# client policies"
description: "Guide to tuning Aerospike C# client policies, including connection pools, timeouts, retries, and batch operations."
---

# C# client policies

> For the complete documentation index see: [llms.txt](https://aerospike.com/docs/llms.txt)
> 
> All documentation pages available in markdown.

## Overview

This page describes how you can customize your client policies for optimal query performance and reliability. Aerospike [client policies](https://aerospike.com/docs/database/learn/policies) control the behavior of database queries at a fine-grained level.

## Connecting to the server

The [`ClientPolicy`](https://aerospike.com/apidocs/csharp/api/Aerospike.Client.ClientPolicy.html) class includes constructors for defining the client/server connection, including authentication, consistency guarantees, and TCP keep-alive.

### Basic timeout settings

Aerospike clients offer a variety of timeout and retry settings that you can set for any operation requests. You can modify these timeout settings in the policy objects, and then they are passed as a parameter when the Aerospike operation is requested.

Timeout setting recommendations behave as you would expect - you should increase timeout lengths longer than a normal request time to avoid premature timeouts. Decrease timeout lengths if you know it is safe to do so to avoid unnecessary delays in detecting a real abnormal condition or problem with the network or server.

Increase the number of retries and the time between retries in an environment where your responses are unreliable, due to either network or server issues. Keep in mind that doing so will also cause more delays in detecting fatal error conditions such as real network or server outages.

-   Socket timeout: `Policy.socketTimeout` specifies socket idle timeout in milliseconds when processing a database command.
    
-   Total timeout: `Policy.totalTimeout` specifies total transaction timeout in milliseconds.
    
-   Max retries: `Policy.maxRetries` specifies the maximum number of retries before aborting the current transaction. The initial attempt is not counted as a retry.
    
-   Sleep between retries: `Policy.sleepBetweenRetries` specifies the milliseconds to sleep between retries. Enter zero to skip sleep. This field is ignored when `maxRetries` is zero. This field is also ignored in async mode.
    
-   Timeout delay: `Policy.timeoutDelay` creates a grace period after a client operation times out. During this period:
    
    -   The client returns a timeout error to the application immediately.
        
    -   Instead of closing the socket immediately, the client waits for the specified delay period.
        
    -   If the server response arrives during this delay window, the connection is returned to the pool for reuse.
        
    -   If no response arrives by the end of the delay, the connection is closed.
        
    
    This approach is particularly valuable for TLS connections, which are significantly more expensive to establish due to the handshake process.
    
    For more information, see the timeout policies [blog post](https://aerospike.com/blog/using-aerospike-policies-correctly/).
    

## Connection pool configuration

Whenever possible, Aerospike clients manage an internal session pool to avoid the cost of creating a session when making an operation request. A variety of client policy options are available to control the behavior of the Aerospike client’s session pool management. You can avoid fluctuation in the client pool and create a fixed resource utilization cost by setting the minimum connections per node to the same value as the maximum connections per node.

-   Increase the minimum connections per node to avoid the latency overhead for creating new connections after a period of relative inactivity. This situation can arise if your workload has spikes or waves of high volume, but comes at the cost of constant increased client-side resource utilization.

### Minimum connections per node

Increase the minimum connections per node to avoid the latency overhead for creating new connections after a period of relative inactivity. This situation can arise if your workload has spikes or waves of high volume, but comes at the cost of constant increased client-side resource utilization.

`ClientPolicy.minConnsPerNode` is the minimum number of synchronous connections allowed per server node. Setting this option preallocates the minimum connections on client node creation. The client periodically allocates new connections if the count falls below `minConnsPerNode`.

For more information, see [`minConnsPerNode`](https://aerospike.com/docs/develop/connection-tuning-guide/#minconnspernode).

You can avoid fluctuation in the client pool and create a fixed resource utilization cost by setting the minimum connections per node to the same value as the maximum connections per node.

### Maximum connections per node

Increase the maximum connections per node to avoid latency overhead and blocking or queuing during your peak workload periods. This can greatly increase your client-side resource utilization. You may want to reduce this number if you are controlling client-side scaling externally. For instance, with Kubernetes application side scaling, you may want to reduce the total number of outstanding sessions that the Aerospike server will need to support simultaneously.

`ClientPolicy.maxConnsPerNode` is the maximum number of synchronous connections allowed per server node. Requests go through retry logic and potentially fail with `ResultCode.NO_MORE_CONNECTIONS` if the maximum number of connections is exceeded.

For more information, see [`maxConnsPerNode`](https://aerospike.com/docs/develop/connection-tuning-guide/#maxconnspernode-asyncmaxconnspernode).

You can avoid fluctuation in the client pool and create a fixed resource utilization cost by setting the maximum connections per node to the same value as the minimum connections per node.

#### Backoff behavior

Aerospike clients provide [client-side backoff](https://aerospike.com/docs/develop/tutorials/circuit-breaker/) or circuit breaker functionality that you can control with the client policy. This functionality restricts an application from overwhelming the server with requests if it notices an increase in the number of errors returned by the server. We highly recommend that you use this functionality, especially in situations where you have a large or scalable application workload connected to a single Aerospike cluster.

-   Max error rate: `ClientPolicy.maxErrorRate` is the maximum number of errors allowed per node during an interval defined by [ClientPolicy.errorRateWindow](https://aerospike.com/docs/develop/connection-tuning-guide/#errorratewindow) before the backoff algorithm throws an `AerospikeException.Backoff` error on database commands to that node. If `maxErrorRate` is zero, there is no error limit and the exception is never thrown.
    
-   Error rate window: [`ClientPolicy.errorRateWindow`](https://aerospike.com/docs/develop/connection-tuning-guide/#errorratewindow) is the number of cluster tend iterations to use to evaluate the `maxErrorRate`. If the `maxErrorRate` is reached, the backoff algorithm rejects additional database commands to the node until the number of errors goes back down.
    

### Tend configuration

Every client instance runs a cluster tend thread that periodically polls server nodes for cluster status. You can control how frequently client instances check in with the server by adjusting the tend interval.

-   Tend interval: [`ClientPolicy.tendInterval`](https://aerospike.com/docs/develop/connection-tuning-guide/#tendinterval) is the interval, in milliseconds, at which the cluster tend thread checks the cluster status. It defaults to 1000ms. For more information, see the [Knowledge Base article](https://support.aerospike.com/hc/en-us/articles/49939338228379-FAQ-What-is-the-tend-interval).

### Policy defaults

Every client application database API call takes a policy parameter, and if that parameter is `null` the API call uses the default policy. You can set defaults for all the various `clientPolicy` parameters and use them throughout the application, rather than setting a policy for every API call.

The following example creates a client policy, sets defaults, and connects to a cluster:

```csharp
ClientPolicy clientPolicy = new()

{

   clientPolicy.ReadPolicyDefault.socketTimeout = 100,

   clientPolicy.ReadPolicyDefault.totalTimeout = 100,

   clientPolicy.WritePolicyDefault.socketTimeout = 100,

   clientPolicy.WritePolicyDefault.totalTimeout = 100

};

// Connect to the cluster.

bool isProxy = false;

var hosts = new Host[]

{

    new Host("localhost", "localhost", 4000)

};

AerospikeClient client = AerospikeClientFactory.CreateClient(clientPolicy, isProxy, hosts);
```

Single operation policy defaults are set in the following `Client` properties:

-   `readPolicyDefault`
-   `writePolicyDefault`
-   `scanPolicyDefault`
-   `queryPolicyDefault`

All of these policies inherit from the base `Policy` class. You can set base `Policy` default settings for each single operation type by using the associated base `Policy` inherited properties.

Batch operation defaults are set with the following `Client` properties:

-   `batchPolicyDefault`
-   `batchParentPolicyWriteDefault`
-   `batchWritePolicyDefault`
-   `batchDeletePolicyDefault`
-   `batchUDFPolicyDefault`

`batchWritePolicy`, `batchDeletePolicy`, and `BatchUDF` policies do not inherit from the base `batchPolicy` class. To properly set default batch policies for the client object, use:

-   `batchPolicyDefault` property to set defaults for reads.
-   `batchParentPolicyWriteDefault` to set base policy property defaults for writes
-   `batchWritePolicyDefault`, `batchDeletePolicyDefault`, and `batchUDFPolicyDefault` to set the detailed specific property settings for those batch operations.

### Read/Write command policies

You can use `WritePolicy` parameters such as [`CommitLevel`](https://aerospike.com/apidocs/csharp/api/Aerospike.Client.WritePolicy.html#Aerospike_Client_WritePolicy_commitLevel) and [`DurableDelete`](https://aerospike.com/apidocs/csharp/api/Aerospike.Client.WritePolicy.html#Aerospike_Client_WritePolicy_durableDelete) to control policy settings on a per-command basis.

```csharp
// Make a copy of the client's default write policy.

WritePolicy policy = new WritePolicy(client.writePolicyDefault);

// Change commit level.

policy.commitLevel = CommitLevel.COMMIT_MASTER;

// Write record with modified write policy.

client.put(policy, key, bins);
```

More information about single-record commands can be found on the [Single-Record Commands](https://aerospike.com/docs/develop/learn/bin-operations) page.

### Batched commands

Batched commands affect multiple records with a single request. Batch requests can occur serially or in parallel, depending on the [batch policy settings](https://aerospike.com/apidocs/csharp/api/Aerospike.Client.BatchPolicy.html).

[`ClientPolicy.batchPolicyDefault`](https://aerospike.com/apidocs/csharp/api/Aerospike.Client.ClientPolicy.html#Aerospike_Client_ClientPolicy_batchPolicyDefault) defines the default settings for the batch policy, which are used whenever `null` is passed to an API call as the `policy` parameter.

Batch write commands process multiple updates in a single operation using fewer connections. Batch write policy options include:

-   Commit level: [`BatchWritePolicy.commitLevel`](https://aerospike.com/apidocs/csharp/api/Aerospike.Client.BatchWritePolicy.html#Aerospike_Client_BatchWritePolicy_commitLevel) specifies a consistency guarantee when sending a request to the server.
    
-   Durable delete: [`BatchWritePolicy.durableDelete`](https://aerospike.com/apidocs/csharp/api/Aerospike.Client.BatchWritePolicy.html#Aerospike_Client_BatchWritePolicy_durableDelete) is a boolean value. If true, the server leaves a tombstone for any record deleted.
    

## Collection Data Types (CDT)

[ListPolicy](https://aerospike.com/apidocs/csharp/api/Aerospike.Client.ListPolicy.html) and [MapPolicy](https://aerospike.com/apidocs/csharp/api/Aerospike.Client.MapPolicy.html) define how list and map operations should behave.

-   Write flags: [`MapWriteFlags`](https://aerospike.com/apidocs/csharp/api/Aerospike.Client.MapWriteFlags.html) and [`ListWriteFlags`](https://aerospike.com/apidocs/csharp/api/Aerospike.Client.ListWriteFlags.html) provide options for what to do if a key specified by a write operation already exists or contains duplicate data.