# Manage sets

This page describes how to manage [sets](https://aerospike.com/docs/database/learn/architecture/data-storage/data-model) and [set indexes](https://aerospike.com/docs/database/learn/architecture/data-storage/set-index/) in an Aerospike namespace.

An Aerospike set is similar to a table in a relational database, except you do not define a schema for it. Sets are created dynamically and implicitly by the first record inserted into the set, a behavior which can be restricted through the use of [role-based access control](https://aerospike.com/docs/database/manage/security/rbac/). While records can be created without a set name, you can configure the namespace to [`disallow-null-setname`](https://aerospike.com/docs/database/reference/config#namespace__disallow-null-setname).

::: caution
Truncation, expiration, and eviction are discouraged for strong consistency (CP mode) namespaces.
:::

## Managing set indexes

A set index can be dynamically enabled in the set context by configuring [`enable-index`](https://aerospike.com/docs/database/reference/config#namespace__enable-index) to `true`.

### Adding a set index

Using asadm’s [`manage config`](https://aerospike.com/docs/database/tools/asadm/live-mode/#config):

Terminal window

```bash
asadm -e "enable; manage config namespace test set demo param enable-index to true"
```

Or using the `set-config` info command:

Terminal window

```bash
asadm -e "enable; asinfo -v 'set-config:context=namespace;id=test;set=demo;enable-index=true' "
```

### Removing a set index

Using asadm to revert the `enable-index` set configuration:

Terminal window

```bash
Admin> enable

Admin+> manage config namespace test set demo param enable-index to false
```

Or using the raw info command:

Terminal window

```bash
Admin> enable

Admin+> asinfo -v 'set-config:context=namespace;id=test;set=demo;enable-index=false'
```

### Monitoring set indexes

The memory cost of enabling a set index is described in the [capacity planning](https://aerospike.com/docs/database/manage/planning/capacity#calculating-storage-for-the-set-index) guide. The [`indexes-memory-budget`](https://aerospike.com/docs/database/reference/config#namespace__indexes-memory-budget) configuration parameter can be used to limit the combined memory usage by all indexes (primary, set, secondary) at the namespace level. Setting limits on the number of objects and storage used by a set is described further below in this page.

The memory used by all set indexes in a namespace is provided by the [`memory_used_set_index_bytes`](https://aerospike.com/docs/database/reference/metrics#namespace__memory_used_set_index_bytes) metric and also using the [“memory-usage”](https://aerospike.com/docs/database/reference/logs/#info__1909672775) server log ticker line.

## Managing expiration and eviction

You can modify namespace [data retention](https://aerospike.com/docs/database/manage/namespace/retention/) aspects like expiration, eviction and TTL at the set level.

::: note
Configuration parameters are applied per-node. `asadm` sends the same info command to all the nodes in the cluster.
:::

### Defining set-level record TTL

As of Database 7.0.0, you can specify a default time-to-live ([`default-ttl`](https://aerospike.com/docs/database/reference/config#namespace__default-ttl)) configuration option at the set level, which overrides any `default-ttl` option specified at the namespace level.

Terminal window

```bash
asadm -e "enable; manage config namespace test set demo param default-ttl 60D"
```

See how to [specify a set-level default TTL](https://aerospike.com/docs/database/manage/namespace/retention/#specify-a-set-level-default-ttl) through static configuration.

### Protecting a set from evictions

To protect a set from evictions you can statically or dynamically [`disable-eviction`](https://aerospike.com/docs/database/reference/config#namespace__disable-eviction). When evictions are in effect for a namespace, sets with evictions disabled will be skipped, regardless of the void-time of the records.

Terminal window

```bash
asadm -e "enable; manage config namespace test set demo param disable-eviction to true"
```

See how to [disable eviction on sets](https://aerospike.com/docs/database/manage/namespace/retention/#disable-eviction-on-sets) through static configuration.

## Capping a set

You can cap the growth of a set through configuration.

::: note
Configuration parameters are applied per-node, and thresholds are checked separately on each cluster node. Stop-writes behavior occurs independently on each node past the defined threshold.
:::

When using `asadm`, the same dynamic configuration is sent to all the nodes in the Aerospike Database cluster.

### Capping the size of a set

Starting with Aerospike 6.3.0, you can cap the amount of storage used by a set with [`stop-writes-size`](https://aerospike.com/docs/database/reference/config#namespace__stop-writes-size). If this threshold is breached on a cluster node, client writes to the set (on this node) are refused. Deletions, replica writes, and migration writes are still allowed when the set is in stop-writes mode.

Once the limit is reached, the server does not allow any additional writes, even those that would decrease the size of a record. There are two ways to get under the `stop-writes-size` limit: increase or remove the limit, or delete records. However, record deletions using UDF, delete-all-bins ops, or background ops queries will also be rejected – only regular record deletes (including batch deletes) and namespace supervisor (NSUP) deletes will be allowed.

The `asadm` command to dynamically cap the size of a set is:

Terminal window

```bash
asadm -e "enable; manage config namespace test set demo param stop-writes-size to 250M"
```

Or using a raw `set-config` info command:

Terminal window

```bash
asadm -e "enable; asinfo -v 'set-config:context=namespace;id=test;set=demo;stop-writes-size=250M' "
```

Use asadm’s [`show stop-writes`](https://aerospike.com/docs/database/tools/asadm/live-mode#stop-writes) to view the configured cap and to see how close you are to crossing the threshold.

Terminal window

```bash
Admin> show stop-writes for test employees

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Stop Writes (2025-05-19 04:16:15 UTC)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

                         Show all stop writes - add 'for <namespace> [<set>]' for a shorter list.

           Config|Namespace|      Set|           Node|Stop-Writes|         Metric|  Usage%|   Usage|Threshold

stop-writes-count|test     |employees|10.0.1.127:3100|False      |objects        |      --|10.000 K|       --

stop-writes-size |test     |employees|10.0.1.127:3100|True       |data_used_bytes|117.84 %|1.178 MB| 1.000 MB

Number of rows: 2
```

See how to [define a data size maximum on a set](https://aerospike.com/docs/database/manage/namespace/retention/#define-a-data-size-maximum-on-a-set) through static configuration.

### Capping the number of records in a set

You can cap the number of records in the set with [`stop-writes-count`](https://aerospike.com/docs/database/reference/config#namespace__stop-writes-count). If this threshold is breached on a cluster node, client writes to the set (on this node) are refused. Deletions, replica writes, and migration writes are still allowed when the set is in stop-writes mode.

The `asadm` command to dynamically cap the number of records in a set is:

Terminal window

```bash
asadm -e "enable; manage config namespace test set demo param stop-writes-count to 1000000"
```

Or using the older info command:

Terminal window

```bash
asadm -e "enable; asinfo -v 'set-config:context=namespace;id=test;set=demo;stop-writes-count=1000000' "
```

Use [`show stop-writes`](https://aerospike.com/docs/database/tools/asadm/live-mode#stop-writes) to view the configured cap and to see how close you are to crossing the limit.

See how to [define an object count limit on a set](https://aerospike.com/docs/database/manage/namespace/retention/#define-an-object-count-limit-on-a-set) through static configuration.

## Truncating a set in a namespace

Use the [`asadm`](https://aerospike.com/docs/database/tools/asadm) or [`asinfo`](https://aerospike.com/docs/database/tools/asinfo) tools to issue a `truncate` command to one Aerospike cluster node at a time.

::: caution
To use the `truncate` command in a namespace that is also enabled with transactions, you must first verify that all transactions are paused as described in [Pause and drain transactions before truncating](#pause-and-drain-transactions-before-truncating).
:::

### Truncate with `asadm`

Using the `asadm` command-line interface:

Terminal window

```bash
asadm

Seed:        [('127.0.0.1', 3000, None)]

Aerospike Interactive Shell, version 2.11.0

Found 1 nodes

Online:  127.0.0.1:3000

Admin> info set

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Set Information (2023-03-26 22:59:40 UTC)~~~~~~~~~~~~~~~~~~~~~~~~~~~

Namespace| Set|           Node|  Memory|    Disk|~~~~~Quota~~~~~~| Objects|   Stop| Disable|  Set

         |    |               |    Used|    Used|     Total|Used%|        | Writes|Eviction|Index

         |    |               |        |        |          |     |        |  Count|        |

test     |demo|127.0.0.1:3000 |1.236 MB|0.000 B |250.000 MB|0.0 %|99.711 K|1000000|True    |No

test     |demo|               |1.236 MB|0.000 B |250.000 MB|0.0 %|99.711 K|       |        |

Number of rows: 1

Admin> enable

Admin+> manage truncate ns test set demo

You're about to truncate up to 0 records from set demo for namespace test

Confirm that you want to proceed by typing 6cdc8c, or cancel by typing anything else.

6cdc8c

Successfully started truncation for set demo of namespace test

Admin+> info set

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Set Information (2023-03-26 23:04:08 UTC)~~~~~~~~~~~~~~~~~~~~~~~~~~

Namespace| Set|           Node|  Memory|    Disk|~~~~~Quota~~~~~~|Objects|   Stop| Disable|  Set

         |    |               |    Used|    Used|     Total|Used%|       | Writes|Eviction|Index

         |    |               |        |        |          |     |       |  Count|        |

test     |demo|127.0.0.1:3000 |0.000 B |0.000 B |250.000 MB|0.0 %|0.000  |1000000|True    |No

test     |demo|               |0.000 B |0.000 B |250.000 MB|0.0 %|0.000  |       |        |

Number of rows: 1
```

#### In non-interactive mode

Terminal window

```bash
asadm --enable -e "manage truncate ns test set demo --no-warn"
```

### Truncate with `asinfo`

The following command truncates a single node, and is then communicated to the other nodes as shared metadata (SMD):

Terminal window

```bash
asinfo -h 127.0.0.1 -v "truncate:namespace=test;set=demo"
```

### Pause and drain transactions before truncating

Use the following steps to truncate sets in a namespace with transactions enabled.

1.  Pause the transactions using one of the following commands.

```java
asadm -e "enable; manage config namespace <NAMESPACE_NAME> param disable-mrt-writes to true"
```

or

```java
asadm -e "enable; asinfo -v 'set-config:context=namespace;id=<NAMESPACE_NAME>;disable-mrt-writes=true'"
```

2.  Run the following command to examine the special monitor set.

```java
asadm -e "show statistics sets for <NAMESPACE_NAME> <ERO~MRT like objects -t"
```

or

```java
asadm -e "enable; asinfo -v 'sets/<NAMESPACE_NAME>/<ERO~MRT'" and in response objects=? shows the count
```

3.  When the number of records given by the “objects” value is zero, transactions are stopped. The character between the O and the M in the set name is a tilde not a dash.

### Mechanism

The mechanism involved in truncating a namespace, or a set within a namespace, is distinct from NSUP.

::: note
Prior to Database 6.3.0, the `truncate` info command started a single background thread on each of the nodes in the cluster. Starting with Database 6.3.0, the `truncate` info command starts a number of threads for each truncation job equal to the value of the [`truncate-threads`](https://aerospike.com/docs/database/reference/config#namespace__truncate-threads) configuration parameter. The truncate threads then traverse the primary index of the namespace and remove the necessary records.
:::

In Database 6.3.0 and later:

-   Set truncation is optimized to use set indexes to rapidly find all the records belonging to the set being truncated. This optimization significantly increases the speed of set truncation, with the caveat that it is skipped if the set has tombstones.
    
-   The truncate command takes an optional last update time (LUT) threshold parameter, `lut` which limits the truncation to records with an LUT earlier than the specified timestamp . If no timestamp is specified, the “now” timestamp of the receiving node is used.
    
-   Set truncation can be issued repeatedly. It updates the effective last update time of an affected set, and is reflected in the `lut` field of the set information.
    
-   For truncation on sets with secondary indexes, each record data is actively read, and any secondary index entries associated with the record are also removed. See [Manage sindexes](#manage-sindexes).
    
-   In the Enterprise Edition, truncation is durable and preserves record deletions through a cold-restart. In the Community Edition, similar to record deletes, records in previously truncated sets are not durable and deletes can return through a cold start.
    

### Truncate undo

Use the [`truncate-undo`](https://aerospike.com/docs/database/reference/info#truncate-undo) and [`truncate-namespace-undo`](https://aerospike.com/docs/database/reference/info#truncate-namespace-undo) commands to remove the truncate related entry(ies) in SMD to allow for potential recovery of inadvertently truncated records upon a subsequent [cold restart](https://aerospike.com/docs/database/manage/database/cold-start). Truncated records that have been overwritten on persistent storage are not recoverable.

### During cluster change

If nodes return to the cluster during or after a `truncate` or `truncate-namespace` command has run, the SMD subsystem provides information on what has been truncated. The nodes will match the truncation level of the rest of the cluster by truncating data based on the LUT received through the SMD subsystem.

During migrations, records are checked against the truncation criteria based on the timestamp saved in the SMD truncate file for the specific set and/or namespace as partitions migrate across nodes. If they meet the truncation criteria, the records are discarded. In this way, `truncate` and `truncate-namespace` are completely robust during cluster memberships changes.

When nodes are executing `truncate` or `truncate-namespace`, incoming transactions are only executed if the LUT of the accessed record is older than the execution time of any truncation command (pending or completed). From an application’s perspective, as soon as a truncation command starts, whether directly, through an SMD update, or when a node joins a cluster, the would-be truncated record cannot be differentiated from an already truncated record, and the command works as if it were instantaneous. This is possible as records accessed through any transactions are checked against the LUTs stored in the SMD subsystem.

### Manage sindexes

The presence of sindexes can slow down truncation. Delete any sindexes before running `truncate` or `truncate-namespace`, as described in the following table.

| Storage Engine | Versions | Description |
| --- | --- | --- |
| All Flash | Prior to Database 5.7.0.20 | Before you truncate, delete the secondary index (sindex) associated with the set to avoid performance impact. |
| Database 6.0.0 prior to 6.0.0.4 | Before you truncate, delete the sindex associated with the set to avoid performance impact. |
| Database 5.7.0.20 and later and Database 6.0.0.4 and later | Do not delete sindex before truncating. Truncation updates the secondary index on the fly. |
| Other storage engines (including persistent memory, data-in-memory, data-in-index, memory-only, and shadow device) | Database prior to 5.7.0 | Before you truncate, delete the sindex associated with the set to avoid performance impact. |
| Database 5.7.0 and later | Do not delete any sindex prior to truncating a set. Deleting a secondary index while a truncation is in progress could impact performance. |

::: note
If using the client APIs to perform the truncation, the LUT (last update time) is accurate to 1 millisecond (ms) resolution.
:::

## Reclaiming unused sets

The total number of sets in a namespace is limited to 1023 in Database 6.0.0 and earlier, and 4095 in Database 7. Deleting a set metadata to reclaim space from this limit requires durably deleting all the data in the set and cold restarting the node. See [How to clear up set names when they exceed the limit](https://support.aerospike.com/s/article/How-to-clear-up-set-names-when-they-exceed-the-limit) for details.