Create records
For the complete documentation index see: llms.txt
All documentation pages available in markdown.
Applies to
- Aerospike Developer SDK (Java 21+ and Python 3.11+)
- Aerospike Database 8.2.0 or later, unless a section states otherwise
Learn how to create records in Aerospike using the Developer SDK. This guide covers inserting new records, upserting, setting TTL, and working with collection data types (CDTs).
Except where noted, snippets on this page use the imports below. A snippet lists additional import lines only when it needs a type not shown here. When this page includes a Complete example section, that block is fully self-contained with every import required to run it.
import com.aerospike.client.sdk.AerospikeException;import com.aerospike.client.sdk.DataSet;import com.aerospike.client.sdk.RecordResult;import com.aerospike.client.sdk.RecordStream;import com.aerospike.client.sdk.Session;import com.aerospike.client.sdk.policy.Behavior.Selectors;import com.aerospike.client.sdk.policy.Behavior;
import java.time.Duration;import java.time.LocalDateTime;import java.util.List;import java.util.Map;from datetime import datetime, timedelta
from aerospike_sdk import Behavior, DataSetfrom aerospike_sdk.exceptions import AerospikeError, ResultCodefrom aerospike_sdk.policy import SettingsInsert a single record
Use insert() to create a new record. This fails if the record already exists.
DataSet users = DataSet.of("test", "users");
session.insert(users) .bins("name", "email", "age") .id("user-1").values("Alice Smith", "alice@example.com", 28) .execute();📖 API reference:
DataSet.of(...)|Session.insert(DataSet)|OperationObjectBuilder.bins(...)|IdValuesBuilder.id(...)|IdValuesRowBuilder.values(...)|ChainableQueryBuilder.execute()
users = DataSet.of("test", "users")
await session.insert(users.id("user-1")).put( {"name": "Alice Smith", "email": "alice@example.com", "age": 28}).execute()📖 API reference:
DataSet.of()|DataSet.id()|Session.insert()|WriteSegmentBuilder.put()|WriteSegmentBuilder.execute()
Upsert (insert or update)
Use upsert() when you want to create a record if it doesn’t exist, or update it if it does.
DataSet users = DataSet.of("test", "users");
// Creates or updates the recordsession.upsert(users) .bins("name", "email", "age") .id("user-1").values("Alice Smith", "alice.smith@example.com", 29) .execute();📖 API reference:
Session.upsert(DataSet)|OperationObjectBuilder.bins(...)|IdValuesBuilder.id(...)|IdValuesRowBuilder.values(...)|ChainableQueryBuilder.execute()
users = DataSet.of("test", "users")
# Creates or updates the recordawait session.upsert(users.id("user-1")).put( {"name": "Alice Smith", "email": "alice.smith@example.com", "age": 29}).execute()📖 API reference:
DataSet.of()|DataSet.id()|Session.upsert()|WriteSegmentBuilder.put()|WriteSegmentBuilder.execute()
Insert vs upsert vs other operations
| Method | Record Exists | Record Doesn’t Exist | Merges with Existing Data |
|---|---|---|---|
insert() | ❌ Fails with error | ✅ Creates record | Not Applicable |
upsert() | ✅ Updates record | ✅ Creates record | ✅ Yes |
update() | ✅ Updates record | ❌ Fails with error | ✅ Yes |
replace() | ✅ Updates record | ✅ Creates record | ❌ No |
replaceIfExists() / replace_if_exists() | ✅ Updates record | ❌ Fails with error | ❌ No |
The table above describes single-key behavior. Batch verbs carry the same per-verb existence semantics on the wire. insert requires the record to be absent, update requires it to exist, and so on, so per-key failures surface as non-OK rows in the returned stream.
Rule of thumb: Use insert() when you expect the record to be new and want to catch duplicates. Use upsert() when you don’t care whether it exists.
Set time-to-live (TTL)
Records can automatically expire after a specified duration, or at a specified time:
DataSet users = DataSet.of("test", "users");
// Record expires in 1 hourtry { session.upsert(users) .bins("token", "user_id") .id("session-token").values("abc123", "user-1") .expireRecordAfter(Duration.ofHours(1)) .execute();} catch (AerospikeException e) { // Can fail with "Operation not allowed at this time" when TTL prerequisites are not met. System.err.println("TTL write failed: " + e.getMessage());}
// Record expires on 1st January, 2030 (local time)session.upsert(users) .bins("name") .id("user-1").values("Alice") .expireRecordAt(LocalDateTime.of(2030,1,1,0,0,0)) .execute();
// Record never expires (override namespace default)session.upsert(users.id("permanent-user")) .bin("name").setTo("System Admin") .neverExpire() .execute();📖 API reference:
DataSet.id(...)|Session.upsert(DataSet)|OperationObjectBuilder.bins(...)|IdValuesBuilder.id(...)|IdValuesRowBuilder.values(...)|ChainableQueryBuilder.bin(...)|ChainableQueryBuilder.execute()|AerospikeException
users = DataSet.of("test", "users")
# Record expires in 1 hourtry: await session.upsert(users.id("session-token")).put( {"token": "abc123", "user_id": "user-1"} ).expire_record_after(timedelta(hours=1)).execute()except AerospikeError as e: # Can fail with "Operation not allowed at this time" when TTL prerequisites are not met. print(f"TTL write failed: {e}")
# Record expires on 1st January, 2030 (local time)await session.upsert(users.id("user-1")).put( {"name": "Alice"}).expire_record_at(datetime(2030, 1, 1)).execute()
# Record never expires (override namespace default)await session.upsert(users.id("permanent-user")).put( {"name": "System Admin"}).never_expire().execute()📖 API reference:
DataSet.of()|DataSet.id()|Session.upsert()|WriteSegmentBuilder.put()|WriteSegmentBuilder.expire_record_after()|WriteSegmentBuilder.expire_record_at()|WriteSegmentBuilder.never_expire()|WriteSegmentBuilder.execute()|AerospikeError
Store the user key
By default, Aerospike only stores a digest (hash) of the key. To retrieve
the original key later, enable send-key on the behavior used by the session:
sendKey(true) in Java, Settings(send_key=True) in Python.
DataSet users = DataSet.of("test", "users");
Behavior sendKeyBehavior = Behavior.DEFAULT.deriveWithChanges("sendKey", builder -> builder.on(Selectors.all(), op -> op.sendKey(true)));
Session keySession = cluster.createSession(sendKeyBehavior);
keySession.upsert(users) .bins("name") .id("user-12345").values("Alice") .execute();
// Later, when scanning the set:keySession.query(users) .execute() .forEach(result -> System.out.printf("key: %s\n", result.getKey().userKey) // user-12345 );📖 API reference:
Cluster.createSession(Behavior)|DataSet.of(...)|Session.upsert(DataSet)|Session.query(DataSet)|OperationObjectBuilder.bins(...)|IdValuesBuilder.id(...)|IdValuesRowBuilder.values(...)|ChainableQueryBuilder.execute()|RecordStream.forEach(...)|RecordResult.getKey()
users = DataSet.of("test", "users")
send_key_behavior = Behavior.DEFAULT.derive_with_changes( "send_key", all=Settings(send_key=True))key_session = cluster.create_session(send_key_behavior)
await key_session.upsert(users.id("user-12345")).put({"name": "Alice"}).execute()
# Later, when scanning the set:stream = await key_session.query(users).execute()async for row in stream: print(row.key.value) # "user-12345"stream.close()📖 API reference:
Cluster.create_session()|Behavior.derive_with_changes()|DataSet.of()|DataSet.id()|Behavior.DEFAULT|Session.query()|Session.upsert()|WriteSegmentBuilder.put()|RecordResult.key|RecordStream.close()|QueryBuilder.execute()|WriteSegmentBuilder.execute()
Create with CDTs
Aerospike supports lists and maps as bin values:
DataSet users = DataSet.of("test", "users");
// List valuessession.upsert(users) .bins("name", "tags", "scores") .id("user-1").values( "Alice", List.of("premium", "verified", "active"), List.of(95, 87, 92, 88) ) .execute();
// Map valuessession.upsert(users.id("user-2")) .bin("name").setTo("Alice") .bin("preferences").setTo( Map.of("theme", "dark", "language", "en", "notifications", true)) .execute();
// Nested structuressession.upsert(users) .bins("name", "address") .id("user-3").values( "Alice", Map.of( "street", "123 Main St", "city", "San Francisco", "coordinates", List.of(37.7749, -122.4194) ) ) .execute();📖 API reference:
DataSet.id(...)|Session.upsert(DataSet)|OperationObjectBuilder.bins(...)|IdValuesBuilder.id(...)|IdValuesRowBuilder.values(...)|ChainableQueryBuilder.bin(...)|BinBuilder.setTo(Map)|ChainableQueryBuilder.execute()
users = DataSet.of("test", "users")
# List valuesawait session.upsert(users.id("user-1")).put( { "name": "Alice", "tags": ["premium", "verified", "active"], "scores": [95, 87, 92, 88], }).execute()
# Map/dict valuesawait session.upsert(users.id("user-2")).put( { "name": "Alice", "preferences": { "theme": "dark", "language": "en", "notifications": True, }, }).execute()
# Nested structuresawait session.upsert(users.id("user-3")).put( { "name": "Alice", "address": { "street": "123 Main St", "city": "San Francisco", "coordinates": [37.7749, -122.4194], }, }).execute()📖 API reference:
DataSet.of()|DataSet.id()|Session.upsert()|WriteSegmentBuilder.put()|WriteSegmentBuilder.execute()
📖 Learn more: Data Model explains Aerospike’s data types in detail.
Create only if not exists
Use insert() with error handling to implement “create only if not exists” logic:
DataSet users = DataSet.of("test", "users");
try { session.insert(users) .bins("name") .id("user-1").values("Alice") .execute(); System.out.println("User created successfully");} catch (AerospikeException.RecordExistsException e) { System.out.println("User already exists, skipping creation");}📖 API reference:
Session.insert(DataSet)|OperationObjectBuilder.bins(...)|IdValuesBuilder.id(...)|IdValuesRowBuilder.values(...)|ChainableQueryBuilder.execute()|AerospikeException
users = DataSet.of("test", "users")
try: await session.insert(users.id("user-1")).put({"name": "Alice"}).execute() print("User created successfully")except AerospikeError as e: if e.result_code != ResultCode.KEY_EXISTS_ERROR: raise print("User already exists, skipping creation")📖 API reference:
DataSet.of()|DataSet.id()|Session.insert()|WriteSegmentBuilder.put()|WriteSegmentBuilder.execute()
📖 Learn more: Error Handling covers all exception types.
Batch create
For creating multiple records efficiently, see Batch Operations.
DataSet users = DataSet.of("test", "users");
// Quick preview - see Batch Operations for full detailssession.insert(users) .bins("name") .id("user-1").values("Alice") .id("user-2").values("Bob") .id("user-3").values("Carol") .execute();📖 API reference:
Session.insert(DataSet)|OperationObjectBuilder.bins(...)|IdValuesBuilder.id(...)|IdValuesRowBuilder.values(...)|ChainableQueryBuilder.execute()
users = DataSet.of("test", "users")
# Quick preview - see Batch Operations for full detailsawait ( session.insert(users) .bins("name") .row("user-1", "Alice") .row("user-2", "Bob") .row("user-3", "Carol") .execute())📖 API reference:
DataSet.of()|Session.insert()
Complete example
This example is self-contained—it lists every import needed to run standalone.
import com.aerospike.client.sdk.Cluster;import com.aerospike.client.sdk.ClusterDefinition;import com.aerospike.client.sdk.DataSet;import com.aerospike.client.sdk.Session;import com.aerospike.client.sdk.policy.Behavior;import java.util.List;import java.util.Map;
public class CreateRecordsExample { public static void main(String[] args) { try (Cluster cluster = new ClusterDefinition("localhost", 3000).connect()) { Session session = cluster.createSession(Behavior.DEFAULT); DataSet users = DataSet.of("test", "users"); String key = "create-example-user";
// Cleanup so the example is repeatable. session.delete(users.id(key)).execute();
// Simple insert session.insert(users) .bins("name", "email", "age") .id(key).values("Alice Smith", "alice@example.com", 28) .execute();
// Upsert with complex data session.upsert(users) .bins("name", "tags", "preferences") .id(key).values( "Alice Smith", List.of("premium", "verified"), Map.of("theme", "dark") ) .execute();
System.out.println("Records created successfully!"); } }}📖 API reference:
ClusterDefinition(String,int)|ClusterDefinition.connect()|Cluster.createSession(Behavior)|Cluster.close()|DataSet.of(...)|Session.insert(DataSet)|Session.upsert(DataSet)|Session.delete(Key)|OperationObjectBuilder.bins(...)|IdValuesBuilder.id(...)|IdValuesRowBuilder.values(...)|ChainableQueryBuilder.execute()
import asyncio
from aerospike_sdk import Behavior, ClusterDefinition, DataSet
async def main(): async with ClusterDefinition("localhost", 3000).connect() as cluster: session = cluster.create_session(Behavior.DEFAULT) users = DataSet.of("test", "users") key = users.id("create-example-user")
# Cleanup so the example is repeatable. await session.delete(key).execute()
# Simple insert await session.insert(key).put( {"name": "Alice Smith", "email": "alice@example.com", "age": 28} ).execute()
# Upsert with complex data await session.upsert(key).put( { "name": "Alice Smith", "tags": ["premium", "verified"], "preferences": {"theme": "dark"}, } ).execute()
print("Records created successfully!")
if __name__ == "__main__": asyncio.run(main())📖 API reference:
ClusterDefinition|ClusterDefinition.connect()|Cluster.create_session()|DataSet.of()|DataSet.id()|Behavior.DEFAULT|Session.upsert()|Session.insert()|Session.delete()|WriteSegmentBuilder.put()|WriteSegmentBuilder.execute()
API reference summary
| Method | Description |
|---|---|
insert() | Create a new record (fails if exists) |
upsert() | Create or update a record |
.bins(name1, name2, ...).id(...).values(...) (Java) · .put({...}) or .bins(...).row(id, ...) (Python) | Set bin values |
.expireRecordAfter(duration) (Java) · .expire_record_after(timedelta) or .expire_record_after_seconds(seconds) (Python) | Set time-to-live |
.expireRecordAt(localDateTime) (Java) · .expire_record_at(datetime) (Python) | Expire records at a wall-clock time |
.neverExpire() (Java) · .never_expire() (Python) | Pin record TTL to never expire |
Next steps
Read Records
Retrieve the records you’ve created.
Update Records
Modify existing records and bins.
Batch Operations
Create multiple records efficiently.
Data Model
Understand namespaces, sets, and bins.