---
title: "Consistency models"
description: "Compare Aerospike's AP and SC consistency models, including use cases, trade-offs, and SDK implementation guides."
---

# Consistency models

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

Aerospike supports two consistency models: **AP (Available, Partition-tolerant)** and **SC (Strong Consistency)**. Understanding when to use each is critical for your application.

## AP mode (default)

**Available, Partition-tolerant** — Prioritizes availability over consistency.

-   Reads always succeed if any replica is reachable
-   The default `WritePolicy.commitLevel` is `COMMIT_ALL`. At this commit level, write calls require all replicas to acknowledge; a replica write failure causes the call to fail even if the master was updated
-   During network partitions, both sides remain writable
-   Conflicts resolved by “last write wins” (LWW)

**Best for**: Session stores, caches, real-time analytics, high-availability requirements.

## SC mode (strong consistency)

**Strong Consistency** — Prioritizes consistency over availability.

-   Reads return the most recent committed write (depending on ReadModeSC value)
-   Writes require acknowledgement by all replicas
-   During partitions, if the minority partition has all roster replicas in it, it serves the data and the majority partition is not available
-   No conflict resolution needed (linearizable)

**Best for**: Financial transactions, inventory systems, any “single source of truth” requirement.

## Choosing a consistency model

| Factor | AP Mode | SC Mode |
| --- | --- | --- |
| Availability | Higher | Lower during partitions |
| Read latency | Lower | Slightly higher |
| Write durability | Eventually consistent | Immediately consistent |
| Conflict handling | Automatic (LWW) | Not needed |
| Use case | Caching, sessions | Transactions, inventory |

## How the SDK applies consistency

The Developer SDK does not treat AP and SC as a single global switch. Each namespace on the cluster is either AP or SC, and the SDK picks the matching policy bundle for every operation on that namespace.

-   [Java](#tab-panel-5031)
-   [Python](#tab-panel-5032)

When you call `session.update(...)`, `session.query(...)`, or other builders, the SDK reads the namespace mode from the cluster partition map and resolves settings with `behavior.getSettings(..., scMode)`. AP namespaces use AP-scoped selectors (for example `.reads().ap()`); SC namespaces use SC-scoped selectors (for example `.reads().cp()`).

You can inspect a namespace with [`Session.isNamespaceSC(String)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#isNamespaceSC%28java.lang.String%29).

A session caches both AP and SC read/write policies when it is created. For each operation, the SDK resolves the target namespace’s mode (cached on the client after the first lookup) and passes the matching policy to the client layer. Fast paths such as `session.get()` and `session.put()` supply both `policy` and `policy_sc` so SC namespaces receive SC semantics automatically.

You do not need separate sessions for AP and SC namespaces on the same cluster unless you want different timeout or retry profiles per workload.

## Configuring consistency

For most applications, one session with `Behavior.DEFAULT` is enough. The SDK routes AP settings to AP namespaces and SC settings to SC namespaces.

Use `Behavior.STRICTLY_CONSISTENT` (Python built-in) or a derived behavior with SC read selectors (Java) when you need linearizable reads on SC namespaces. See [Behaviors](https://aerospike.com/docs/develop/client/sdk/concepts/behaviors) for full profiles and derivation patterns.

-   [Java](#tab-panel-5033)
-   [Python](#tab-panel-5034)

```java
import com.aerospike.client.sdk.policy.Behavior.Selectors;

import com.aerospike.client.sdk.policy.ReadModeSC;

// Mixed cluster: DEFAULT picks AP vs SC settings per namespace

Session session = cluster.createSession(Behavior.DEFAULT);

// Stricter SC reads (linearizable) on SC namespaces

Behavior scBehavior = Behavior.DEFAULT.deriveWithChanges("STRICTLY_CONSISTENT", builder -> builder

    .on(Selectors.reads().get().cp(), ops -> ops.consistency(ReadModeSC.LINEARIZE)));

Session scSession = cluster.createSession(scBehavior);

if (session.isNamespaceSC("inventory")) {

    // Namespace is SC — transactions and linearizable reads are available

}
```

> 📖 **API reference**: [`Cluster.createSession(Behavior)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Cluster.html#createSession%28com.aerospike.client.sdk.policy.Behavior%29) | [`Session.isNamespaceSC(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#isNamespaceSC%28java.lang.String%29)

```python
from aerospike_sdk import Behavior

from aerospike_sdk.policy import Settings

from aerospike_async import ReadModeSC

# Mixed cluster: DEFAULT routes AP vs SC settings per namespace

session = cluster.create_session(Behavior.DEFAULT)

# Stricter SC reads (linearizable) on SC namespaces

sc_session = cluster.create_session(Behavior.STRICTLY_CONSISTENT)

# Custom SC-only tuning without a separate session profile name

strict_inventory = Behavior.DEFAULT.derive_with_changes(

    "STRICT_INVENTORY",

    reads_sc=Settings(read_mode_sc=ReadModeSC.LINEARIZE),

    writes_sc=Settings(durable_delete=True),

)
```

`Behavior.DEFAULT` already sets `writes_sc` with `durable_delete=True` for SC namespaces. Override `writes_sc` when you need different delete or commit semantics on SC workloads.

> 📖 **API reference**: [`Behavior.DEFAULT`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/behavior.html#aerospike_sdk.policy.behavior.Behavior.DEFAULT) | [`Behavior.STRICTLY_CONSISTENT`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/behavior.html#aerospike_sdk.policy.behavior.Behavior.STRICTLY_CONSISTENT) | [`Behavior.derive_with_changes()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/behavior.html#aerospike_sdk.policy.behavior.Behavior.derive_with_changes)

## Verify namespace mode

If the code is generic across namespaces and does not know ahead of time if a namespace is AP or SC mode, confirm the target namespace is SC-enabled on the server.

-   [Java](#tab-panel-5035)
-   [Python](#tab-panel-5036)

```java
if (session.isNamespaceSC("inventory")) {

    System.out.println("inventory is an SC namespace");

} else {

    System.out.println("inventory is AP (or unknown)");

}
```

> 📖 **API reference**: [`Session.isNamespaceSC(...)`](https://javadoc.io/doc/com.aerospike/aerospike-client-sdk/latest/com/aerospike/client/sdk/Session.html#isNamespaceSC%28java.lang.String%29)

```python
# Boolean check

if await session.is_namespace_sc("inventory"):

    print("inventory is an SC namespace")

# Detailed status (preferred when you need a log message or test skip reason)

status = await session.namespace_sc_status("inventory")

if status.is_sc:

    print("inventory is SC")

else:

    print(f"Not SC: {status.detail}")
```

[`namespace_sc_status()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/session.html) queries the `namespace/<name>` info command and returns a [`NamespaceScStatus`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/session.html) with `is_sc` and `detail`. Use it in integration tests or startup checks when a feature requires SC.

The sync client exposes the same methods on [`SyncSession`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/sync/session.html) without `await`.

> 📖 **API reference**: [`Session.is_namespace_sc()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/session.html) | [`Session.namespace_sc_status()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/session.html)

## SC-scoped behavior settings (Python)

Python behaviors support separate patches for AP and SC namespaces through `reads_ap`, `reads_sc`, `writes_ap`, and `writes_sc` on [`derive_with_changes()`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/behavior.html). Resolution order is documented on [`Scope`](https://aerospike-python-sdk.readthedocs.io/en/latest/api/behavior.html); SC namespaces merge `reads` → `reads_sc` → shape-specific scopes (for example `reads_point`).

| Scope | Applies when |
| --- | --- |
| `reads_ap` / `writes_ap` | Namespace is AP |
| `reads_sc` / `writes_sc` | Namespace is SC |

Predefined `Behavior.STRICTLY_CONSISTENT` sets `reads_sc=Settings(read_mode_sc=ReadModeSC.LINEARIZE)`. `Behavior.FAST_RACK_AWARE` sets `reads_sc=Settings(read_mode_sc=ReadModeSC.SESSION)` for lower-latency SC reads when session consistency is enough.

See [Behaviors and selectors](https://aerospike.com/docs/develop/client/sdk/concepts/behaviors-and-selectors) for the Java selector model and [Behaviors](https://aerospike.com/docs/develop/client/sdk/concepts/behaviors) for read-mode tables.

## Server configuration

SC mode requires namespace configuration on the server:

```plaintext
namespace myns {

    strong-consistency true

    ...

}
```

Multi-record transactions additionally require Aerospike Server 8.0+ on an SC namespace. See [Transactions](https://aerospike.com/docs/develop/client/sdk/usage/transactions).

## Next steps

-   [Behaviors](https://aerospike.com/docs/develop/client/sdk/concepts/behaviors)
-   [Behaviors and selectors](https://aerospike.com/docs/develop/client/sdk/concepts/behaviors-and-selectors)
-   [Transactions](https://aerospike.com/docs/develop/client/sdk/usage/transactions)
-   [Data Model](https://aerospike.com/docs/develop/client/sdk/concepts/data-model)
-   [Error Handling](https://aerospike.com/docs/develop/client/sdk/concepts/errors)