# Decoupled configuration

The Developer SDK separates **connection configuration** from **operational behavior**, giving operators and developers independent control.

## Why decoupled configuration?

Traditional clients mix connection settings with operation policies, making it hard to:

-   Change timeouts without code changes
-   Use different configurations per environment
-   Let operators tune behavior without developer involvement

The Developer SDK solves this with three layers:

```plaintext
┌─────────────────────────────────────────┐

│           Application Code              │

│  (uses Session, calls operations)       │

├─────────────────────────────────────────┤

│            Behaviors                    │

│  (operational policies, developer-set)  │

├─────────────────────────────────────────┤

│         Cluster Configuration           │

│  (connection details, operator-set)     │

└─────────────────────────────────────────┘
```

## Cluster configuration (operators)

Connection details that operators control:

-   [Java](#tab-panel-2942)
-   [Python](#tab-panel-2943)

```java
import com.aerospike.client.sdk.Cluster;

import com.aerospike.client.sdk.ClusterDefinition;

// From environment variables

Cluster cluster = new ClusterDefinition(

        System.getenv("AEROSPIKE_HOST"),

        3000)

    .withNativeCredentials(

        System.getenv("AEROSPIKE_USER"),

        System.getenv("AEROSPIKE_PASSWORD"))

    .connect();
```

```python
import os

from aerospike_sdk import ClusterDefinition

# From environment variables

cluster = await ClusterDefinition(

    os.environ["AEROSPIKE_HOST"],

    3000,

).with_native_credentials(

    os.environ.get("AEROSPIKE_USER"),

    os.environ.get("AEROSPIKE_PASSWORD"),

).connect()
```

## Behaviors (developers)

Operational policies that developers control:

-   [Java](#tab-panel-2944)
-   [Python](#tab-panel-2945)

```java
// Developer chooses behavior for their use case

Behavior readHeavyBehavior = Behavior.DEFAULT.deriveWithChanges("READ_HEAVY", b -> {});

Behavior writeHeavyBehavior = Behavior.DEFAULT.deriveWithChanges("WRITE_HEAVY", b -> {});

Session readHeavy = cluster.createSession(readHeavyBehavior);

Session writeHeavy = cluster.createSession(writeHeavyBehavior);

Session balanced = cluster.createSession(Behavior.DEFAULT);
```

```python
# Developer chooses behavior for their use case

read_heavy = cluster.create_session(Behavior.READ_FAST)

write_heavy = cluster.create_session(Behavior.DEFAULT)

balanced = cluster.create_session(Behavior.DEFAULT)
```

## External configuration files

Load configuration from YAML or properties files:

aerospike-config.yaml

```yaml
cluster:

  hosts:

    - host: prod-aerospike-1.example.com

      port: 3000

    - host: prod-aerospike-2.example.com

      port: 3000

  tls:

    enabled: true

    cert_file: /etc/ssl/aerospike.crt
```

## Configuration precedence

1.  **Code** (highest) — Explicit settings in code
2.  **Environment Variables** — `AEROSPIKE_*` variables
3.  **Config Files** — YAML/properties files
4.  **Defaults** (lowest) — Built-in sensible defaults

## Next steps

-   [Behaviors](https://aerospike.com/docs/develop/client/sdk/concepts/behaviors)
-   [Connect to Aerospike](https://aerospike.com/docs/develop/client/sdk/connect)
-   [Connect with TLS](https://aerospike.com/docs/develop/client/sdk/connect#connect-with-tls)