or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

common-patterns.mdcore-sdk.mddynamodb-service.mdindex.mds3-service.md

dynamodb-service.mddocs/

0

# Amazon DynamoDB Service APIs

1

2

Amazon DynamoDB is a fully managed NoSQL database service that provides fast and predictable performance. The AWS SDK for Java provides three levels of abstraction for working with DynamoDB: low-level service client, Document API, and Object Mapper.

3

4

## Package

5

6

**Service Package**: `com.amazonaws.services.dynamodbv2`

7

**Model Package**: `com.amazonaws.services.dynamodbv2.model`

8

**Document API**: `com.amazonaws.services.dynamodbv2.document`

9

**Object Mapper**: `com.amazonaws.services.dynamodbv2.datamodeling`

10

**Maven Artifact**: `aws-java-sdk-dynamodb`

11

12

## Client Creation

13

14

```java { .api }

15

package com.amazonaws.services.dynamodbv2;

16

17

// DynamoDB client builder

18

class AmazonDynamoDBClientBuilder extends AwsSyncClientBuilder<AmazonDynamoDBClientBuilder, AmazonDynamoDB> {

19

static AmazonDynamoDBClientBuilder standard();

20

static AmazonDynamoDB defaultClient();

21

AmazonDynamoDBClientBuilder enableEndpointDiscovery();

22

AmazonDynamoDBClientBuilder disableEndpointDiscovery();

23

AmazonDynamoDB build();

24

}

25

```

26

27

### Usage

28

29

```java

30

import com.amazonaws.services.dynamodbv2.AmazonDynamoDB;

31

import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder;

32

import com.amazonaws.regions.Regions;

33

34

// Create default DynamoDB client

35

AmazonDynamoDB dynamoDB = AmazonDynamoDBClientBuilder.defaultClient();

36

37

// Create DynamoDB client with specific region

38

AmazonDynamoDB dynamoDB = AmazonDynamoDBClientBuilder.standard()

39

.withRegion(Regions.US_EAST_1)

40

.build();

41

```

42

43

## Low-Level API

44

45

### Main Service Interface

46

47

```java { .api }

48

package com.amazonaws.services.dynamodbv2;

49

50

// Main DynamoDB interface (thread-safe)

51

interface AmazonDynamoDB {

52

// Table operations

53

CreateTableResult createTable(CreateTableRequest createTableRequest);

54

CreateTableResult createTable(List<AttributeDefinition> attributeDefinitions,

55

String tableName,

56

List<KeySchemaElement> keySchema,

57

ProvisionedThroughput provisionedThroughput);

58

DescribeTableResult describeTable(String tableName);

59

DescribeTableResult describeTable(DescribeTableRequest describeTableRequest);

60

UpdateTableResult updateTable(UpdateTableRequest updateTableRequest);

61

DeleteTableResult deleteTable(String tableName);

62

DeleteTableResult deleteTable(DeleteTableRequest deleteTableRequest);

63

ListTablesResult listTables();

64

ListTablesResult listTables(String exclusiveStartTableName, Integer limit);

65

66

// Item operations

67

PutItemResult putItem(String tableName, Map<String, AttributeValue> item);

68

PutItemResult putItem(String tableName, Map<String, AttributeValue> item,

69

String returnValues);

70

PutItemResult putItem(PutItemRequest putItemRequest);

71

GetItemResult getItem(String tableName, Map<String, AttributeValue> key);

72

GetItemResult getItem(String tableName, Map<String, AttributeValue> key,

73

Boolean consistentRead);

74

GetItemResult getItem(GetItemRequest getItemRequest);

75

UpdateItemResult updateItem(String tableName, Map<String, AttributeValue> key,

76

Map<String, AttributeValueUpdate> attributeUpdates);

77

UpdateItemResult updateItem(UpdateItemRequest updateItemRequest);

78

DeleteItemResult deleteItem(String tableName, Map<String, AttributeValue> key);

79

DeleteItemResult deleteItem(String tableName, Map<String, AttributeValue> key,

80

String returnValues);

81

DeleteItemResult deleteItem(DeleteItemRequest deleteItemRequest);

82

83

// Query and scan

84

QueryResult query(QueryRequest queryRequest);

85

ScanResult scan(String tableName, List<String> attributesToGet);

86

ScanResult scan(String tableName, Map<String, Condition> scanFilter);

87

ScanResult scan(ScanRequest scanRequest);

88

89

// Batch operations

90

BatchGetItemResult batchGetItem(Map<String, KeysAndAttributes> requestItems);

91

BatchGetItemResult batchGetItem(BatchGetItemRequest batchGetItemRequest);

92

BatchWriteItemResult batchWriteItem(Map<String, List<WriteRequest>> requestItems);

93

BatchWriteItemResult batchWriteItem(BatchWriteItemRequest batchWriteItemRequest);

94

95

// Transactions

96

TransactGetItemsResult transactGetItems(TransactGetItemsRequest transactGetItemsRequest);

97

TransactWriteItemsResult transactWriteItems(TransactWriteItemsRequest transactWriteItemsRequest);

98

99

// PartiQL

100

ExecuteStatementResult executeStatement(ExecuteStatementRequest executeStatementRequest);

101

BatchExecuteStatementResult batchExecuteStatement(BatchExecuteStatementRequest batchExecuteStatementRequest);

102

103

// Waiters

104

AmazonDynamoDBWaiters waiters();

105

}

106

```

107

108

### AttributeValue

109

110

```java { .api }

111

package com.amazonaws.services.dynamodbv2.model;

112

113

// Represents a DynamoDB attribute value

114

class AttributeValue {

115

AttributeValue();

116

AttributeValue(String s);

117

118

// String

119

AttributeValue withS(String s);

120

String getS();

121

122

// Number (stored as string)

123

AttributeValue withN(String n);

124

String getN();

125

126

// Binary

127

AttributeValue withB(ByteBuffer b);

128

ByteBuffer getB();

129

130

// String Set

131

AttributeValue withSS(Collection<String> ss);

132

List<String> getSS();

133

134

// Number Set

135

AttributeValue withNS(Collection<String> ns);

136

List<String> getNS();

137

138

// Binary Set

139

AttributeValue withBS(Collection<ByteBuffer> bs);

140

List<ByteBuffer> getBS();

141

142

// Map

143

AttributeValue withM(Map<String, AttributeValue> m);

144

Map<String, AttributeValue> getM();

145

146

// List

147

AttributeValue withL(Collection<AttributeValue> l);

148

List<AttributeValue> getL();

149

150

// Null

151

AttributeValue withNULL(Boolean nul);

152

Boolean isNULL();

153

154

// Boolean

155

AttributeValue withBOOL(Boolean bool);

156

Boolean getBOOL();

157

}

158

```

159

160

### Low-Level Usage

161

162

```java

163

import com.amazonaws.services.dynamodbv2.model.*;

164

import java.util.HashMap;

165

import java.util.Map;

166

167

// Put item

168

Map<String, AttributeValue> item = new HashMap<>();

169

item.put("id", new AttributeValue().withS("123"));

170

item.put("name", new AttributeValue().withS("John Doe"));

171

item.put("age", new AttributeValue().withN("30"));

172

item.put("active", new AttributeValue().withBOOL(true));

173

174

PutItemRequest putRequest = new PutItemRequest()

175

.withTableName("Users")

176

.withItem(item);

177

dynamoDB.putItem(putRequest);

178

179

// Get item

180

Map<String, AttributeValue> key = new HashMap<>();

181

key.put("id", new AttributeValue().withS("123"));

182

183

GetItemRequest getRequest = new GetItemRequest()

184

.withTableName("Users")

185

.withKey(key)

186

.withConsistentRead(true);

187

188

GetItemResult result = dynamoDB.getItem(getRequest);

189

Map<String, AttributeValue> retrievedItem = result.getItem();

190

191

// Query with expression

192

QueryRequest queryRequest = new QueryRequest()

193

.withTableName("Users")

194

.withKeyConditionExpression("id = :v_id")

195

.withExpressionAttributeValues(

196

Map.of(":v_id", new AttributeValue().withS("123")));

197

198

QueryResult queryResult = dynamoDB.query(queryRequest);

199

for (Map<String, AttributeValue> item : queryResult.getItems()) {

200

// Process item

201

}

202

203

// Update item

204

UpdateItemRequest updateRequest = new UpdateItemRequest()

205

.withTableName("Users")

206

.withKey(key)

207

.withUpdateExpression("SET age = :val")

208

.withExpressionAttributeValues(

209

Map.of(":val", new AttributeValue().withN("31")))

210

.withReturnValues(ReturnValue.ALL_NEW);

211

212

UpdateItemResult updateResult = dynamoDB.updateItem(updateRequest);

213

214

// Delete item

215

DeleteItemRequest deleteRequest = new DeleteItemRequest()

216

.withTableName("Users")

217

.withKey(key);

218

dynamoDB.deleteItem(deleteRequest);

219

```

220

221

## Document API (Higher-Level)

222

223

The Document API provides a simpler, more intuitive interface than the low-level API.

224

225

```java { .api }

226

package com.amazonaws.services.dynamodbv2.document;

227

228

// Entry point for Document API

229

class DynamoDB {

230

DynamoDB(AmazonDynamoDB client);

231

232

// Table operations

233

Table getTable(String tableName);

234

Table createTable(CreateTableRequest createTableRequest);

235

TableCollection<ListTablesResult> listTables();

236

237

// Batch operations

238

BatchGetItemOutcome batchGetItem(TableKeysAndAttributes... tableKeysAndAttributes);

239

BatchGetItemOutcome batchGetItem(BatchGetItemSpec batchGetItemSpec);

240

BatchWriteItemOutcome batchWriteItem(TableWriteItems... tableWriteItems);

241

BatchWriteItemOutcome batchWriteItem(BatchWriteItemSpec batchWriteItemSpec);

242

243

// Lifecycle

244

void shutdown();

245

}

246

247

// Represents a DynamoDB table

248

class Table {

249

// Metadata

250

String getTableName();

251

TableDescription describe();

252

TableDescription getDescription();

253

Index getIndex(String indexName);

254

255

// Item operations

256

PutItemOutcome putItem(Item item);

257

PutItemOutcome putItem(Item item, String conditionExpression,

258

Map<String, String> nameMap, Map<String, Object> valueMap);

259

PutItemOutcome putItem(PutItemSpec putItemSpec);

260

GetItemOutcome getItemOutcome(KeyAttribute... primaryKeyComponents);

261

GetItemOutcome getItemOutcome(PrimaryKey primaryKey);

262

GetItemOutcome getItemOutcome(GetItemSpec spec);

263

Item getItem(KeyAttribute... primaryKeyComponents);

264

Item getItem(PrimaryKey primaryKey);

265

Item getItem(GetItemSpec spec);

266

UpdateItemOutcome updateItem(PrimaryKey primaryKey, AttributeUpdate... attributeUpdates);

267

UpdateItemOutcome updateItem(UpdateItemSpec updateItemSpec);

268

DeleteItemOutcome deleteItem(KeyAttribute... primaryKeyComponents);

269

DeleteItemOutcome deleteItem(PrimaryKey primaryKey);

270

DeleteItemOutcome deleteItem(DeleteItemSpec deleteItemSpec);

271

272

// Query and scan

273

ItemCollection<QueryOutcome> query(QuerySpec spec);

274

ItemCollection<ScanOutcome> scan(ScanSpec spec);

275

276

// Table management

277

TableDescription updateTable(UpdateTableSpec updateTableSpec);

278

DeleteTableResult delete();

279

Table waitForActive();

280

Table waitForAllActiveOrDelete();

281

}

282

283

// Represents a DynamoDB item

284

class Item {

285

// Type-specific getters

286

String getString(String attrName);

287

BigDecimal getNumber(String attrName);

288

int getInt(String attrName);

289

long getLong(String attrName);

290

boolean getBoolean(String attrName);

291

byte[] getBinary(String attrName);

292

Set<String> getStringSet(String attrName);

293

Set<BigDecimal> getNumberSet(String attrName);

294

Map<String, Object> getMap(String attrName);

295

List<Object> getList(String attrName);

296

297

// Fluent setters

298

Item withString(String attrName, String value);

299

Item withNumber(String attrName, Number value);

300

Item withInt(String attrName, int value);

301

Item withLong(String attrName, long value);

302

Item withBoolean(String attrName, boolean value);

303

Item withBinary(String attrName, byte[] value);

304

Item withStringSet(String attrName, Set<String> value);

305

Item withNumberSet(String attrName, Set<Number> value);

306

Item withMap(String attrName, Map<String, Object> value);

307

Item withList(String attrName, List<Object> value);

308

Item withPrimaryKey(KeyAttribute... components);

309

Item withPrimaryKey(String hashKeyName, Object hashKeyValue);

310

Item withPrimaryKey(String hashKeyName, Object hashKeyValue,

311

String rangeKeyName, Object rangeKeyValue);

312

313

// Utility methods

314

boolean isNull(String attrName);

315

boolean isPresent(String attrName);

316

Map<String, Object> asMap();

317

String toJSON();

318

String toJSONPretty();

319

}

320

```

321

322

### Document API Usage

323

324

```java

325

import com.amazonaws.services.dynamodbv2.document.*;

326

import com.amazonaws.services.dynamodbv2.document.spec.*;

327

328

// Create DynamoDB Document API

329

DynamoDB dynamoDB = new DynamoDB(dynamoDBClient);

330

331

// Get table reference

332

Table table = dynamoDB.getTable("Users");

333

334

// Put item

335

Item item = new Item()

336

.withPrimaryKey("id", "123")

337

.withString("name", "John Doe")

338

.withNumber("age", 30)

339

.withBoolean("active", true)

340

.withStringSet("tags", Set.of("vip", "premium"));

341

342

PutItemOutcome outcome = table.putItem(item);

343

344

// Get item

345

Item retrievedItem = table.getItem("id", "123");

346

String name = retrievedItem.getString("name");

347

int age = retrievedItem.getInt("age");

348

boolean active = retrievedItem.getBoolean("active");

349

350

// Get item with projection

351

GetItemSpec spec = new GetItemSpec()

352

.withPrimaryKey("id", "123")

353

.withProjectionExpression("name, age")

354

.withConsistentRead(true);

355

Item item = table.getItem(spec);

356

357

// Update item

358

UpdateItemSpec updateSpec = new UpdateItemSpec()

359

.withPrimaryKey("id", "123")

360

.withUpdateExpression("SET age = :val")

361

.withValueMap(Map.of(":val", 31))

362

.withReturnValues(ReturnValue.ALL_NEW);

363

UpdateItemOutcome updateOutcome = table.updateItem(updateSpec);

364

365

// Query

366

QuerySpec querySpec = new QuerySpec()

367

.withKeyConditionExpression("id = :v_id")

368

.withValueMap(Map.of(":v_id", "123"));

369

370

ItemCollection<QueryOutcome> items = table.query(querySpec);

371

for (Item item : items) {

372

System.out.println(item.toJSON());

373

}

374

375

// Scan with filter

376

ScanSpec scanSpec = new ScanSpec()

377

.withFilterExpression("age > :min_age")

378

.withValueMap(Map.of(":min_age", 25));

379

380

ItemCollection<ScanOutcome> items = table.scan(scanSpec);

381

for (Item item : items) {

382

System.out.println(item.getString("name"));

383

}

384

385

// Delete item

386

DeleteItemSpec deleteSpec = new DeleteItemSpec()

387

.withPrimaryKey("id", "123")

388

.withConditionExpression("attribute_exists(id)")

389

.withReturnValues(ReturnValue.ALL_OLD);

390

DeleteItemOutcome deleteOutcome = table.deleteItem(deleteSpec);

391

```

392

393

## Object Mapper (ORM-Style)

394

395

The Object Mapper provides annotation-based mapping of Java POJOs to DynamoDB tables.

396

397

```java { .api }

398

package com.amazonaws.services.dynamodbv2.datamodeling;

399

400

// DynamoDB Mapper (thread-safe)

401

class DynamoDBMapper {

402

DynamoDBMapper(AmazonDynamoDB dynamoDB);

403

DynamoDBMapper(AmazonDynamoDB dynamoDB, DynamoDBMapperConfig config);

404

405

// CRUD operations

406

<T> T load(Class<T> clazz, Object hashKey);

407

<T> T load(Class<T> clazz, Object hashKey, Object rangeKey);

408

<T> T load(T keyObject);

409

<T> T load(T keyObject, DynamoDBMapperConfig config);

410

<T> void save(T object);

411

<T> void save(T object, DynamoDBSaveExpression saveExpression, DynamoDBMapperConfig config);

412

<T> void delete(T object);

413

<T> void delete(T object, DynamoDBDeleteExpression deleteExpression, DynamoDBMapperConfig config);

414

415

// Batch operations

416

Map<String, List<Object>> batchLoad(Iterable<?> itemsToGet);

417

Map<String, List<Object>> batchLoad(Iterable<?> itemsToGet, DynamoDBMapperConfig config);

418

List<FailedBatch> batchWrite(Iterable<?> objectsToWrite, Iterable<?> objectsToDelete);

419

List<FailedBatch> batchWrite(Iterable<?> objectsToWrite, Iterable<?> objectsToDelete,

420

DynamoDBMapperConfig config);

421

422

// Query operations

423

<T> PaginatedQueryList<T> query(Class<T> clazz, DynamoDBQueryExpression<T> queryExpression);

424

<T> PaginatedQueryList<T> query(Class<T> clazz, DynamoDBQueryExpression<T> queryExpression,

425

DynamoDBMapperConfig config);

426

<T> QueryResultPage<T> queryPage(Class<T> clazz, DynamoDBQueryExpression<T> queryExpression);

427

428

// Scan operations

429

<T> PaginatedScanList<T> scan(Class<T> clazz, DynamoDBScanExpression scanExpression);

430

<T> PaginatedScanList<T> scan(Class<T> clazz, DynamoDBScanExpression scanExpression,

431

DynamoDBMapperConfig config);

432

<T> PaginatedParallelScanList<T> parallelScan(Class<T> clazz,

433

DynamoDBScanExpression scanExpression,

434

int totalSegments);

435

<T> ScanResultPage<T> scanPage(Class<T> clazz, DynamoDBScanExpression scanExpression);

436

437

// Count operations

438

int count(Class<?> clazz, DynamoDBScanExpression scanExpression);

439

<T> int count(Class<T> clazz, DynamoDBQueryExpression<T> queryExpression);

440

441

// Transaction operations

442

void transactionWrite(TransactionWriteRequest transactionWriteRequest,

443

DynamoDBMapperConfig config);

444

List<Object> transactionLoad(TransactionLoadRequest transactionLoadRequest,

445

DynamoDBMapperConfig config);

446

447

// Table generation

448

<T> CreateTableRequest generateCreateTableRequest(Class<T> clazz);

449

<T> DeleteTableRequest generateDeleteTableRequest(Class<T> clazz);

450

}

451

```

452

453

### Annotations

454

455

```java { .api }

456

package com.amazonaws.services.dynamodbv2.datamodeling;

457

458

// Mark class as DynamoDB table

459

@interface DynamoDBTable {

460

String tableName();

461

}

462

463

// Mark property as hash key (partition key)

464

@interface DynamoDBHashKey {

465

String attributeName() default "";

466

}

467

468

// Mark property as range key (sort key)

469

@interface DynamoDBRangeKey {

470

String attributeName() default "";

471

}

472

473

// Mark property as attribute

474

@interface DynamoDBAttribute {

475

String attributeName() default "";

476

}

477

478

// Mark property for optimistic locking (version check)

479

@interface DynamoDBVersionAttribute {

480

String attributeName() default "";

481

}

482

483

// Ignore property

484

@interface DynamoDBIgnore {

485

}

486

487

// Auto-generate UUID for key

488

@interface DynamoDBAutoGeneratedKey {

489

}

490

491

// Auto-generate timestamp

492

@interface DynamoDBAutoGeneratedTimestamp {

493

String strategy() default "CREATE";

494

}

495

496

// Mark properties for secondary indexes

497

@interface DynamoDBIndexHashKey {

498

String globalSecondaryIndexName() default "";

499

String[] globalSecondaryIndexNames() default {};

500

}

501

502

@interface DynamoDBIndexRangeKey {

503

String globalSecondaryIndexName() default "";

504

String[] globalSecondaryIndexNames() default {};

505

String localSecondaryIndexName() default "";

506

}

507

508

// Custom type conversion

509

@interface DynamoDBTypeConverted {

510

Class<? extends DynamoDBTypeConverter<?, ?>> converter();

511

}

512

513

// Mark class as document (nested object)

514

@interface DynamoDBDocument {

515

}

516

```

517

518

### Object Mapper Usage

519

520

```java

521

import com.amazonaws.services.dynamodbv2.datamodeling.*;

522

523

// Define POJO with annotations

524

@DynamoDBTable(tableName = "Users")

525

public class User {

526

private String id;

527

private String name;

528

private int age;

529

private boolean active;

530

private Long version;

531

532

@DynamoDBHashKey(attributeName = "id")

533

public String getId() { return id; }

534

public void setId(String id) { this.id = id; }

535

536

@DynamoDBAttribute(attributeName = "name")

537

public String getName() { return name; }

538

public void setName(String name) { this.name = name; }

539

540

@DynamoDBAttribute(attributeName = "age")

541

public int getAge() { return age; }

542

public void setAge(int age) { this.age = age; }

543

544

@DynamoDBAttribute(attributeName = "active")

545

public boolean isActive() { return active; }

546

public void setActive(boolean active) { this.active = active; }

547

548

@DynamoDBVersionAttribute

549

public Long getVersion() { return version; }

550

public void setVersion(Long version) { this.version = version; }

551

}

552

553

// Create mapper

554

DynamoDBMapper mapper = new DynamoDBMapper(dynamoDBClient);

555

556

// Save object

557

User user = new User();

558

user.setId("123");

559

user.setName("John Doe");

560

user.setAge(30);

561

user.setActive(true);

562

mapper.save(user);

563

564

// Load object

565

User loadedUser = mapper.load(User.class, "123");

566

System.out.println(loadedUser.getName());

567

568

// Update object

569

loadedUser.setAge(31);

570

mapper.save(loadedUser);

571

572

// Delete object

573

mapper.delete(loadedUser);

574

575

// Query with expression

576

User hashKeyValues = new User();

577

hashKeyValues.setId("123");

578

579

DynamoDBQueryExpression<User> queryExpression = new DynamoDBQueryExpression<User>()

580

.withHashKeyValues(hashKeyValues);

581

582

PaginatedQueryList<User> queryResult = mapper.query(User.class, queryExpression);

583

for (User u : queryResult) {

584

System.out.println(u.getName());

585

}

586

587

// Scan with filter

588

DynamoDBScanExpression scanExpression = new DynamoDBScanExpression()

589

.withFilterExpression("age > :min_age")

590

.withExpressionAttributeValues(Map.of(":min_age", new AttributeValue().withN("25")));

591

592

PaginatedScanList<User> scanResult = mapper.scan(User.class, scanExpression);

593

for (User u : scanResult) {

594

System.out.println(u.getName());

595

}

596

597

// Batch save

598

List<User> users = Arrays.asList(user1, user2, user3);

599

List<FailedBatch> failures = mapper.batchWrite(users, Collections.emptyList());

600

601

// Batch load

602

List<User> keysToLoad = Arrays.asList(keyUser1, keyUser2);

603

Map<String, List<Object>> results = mapper.batchLoad(keysToLoad);

604

605

// Create table from annotated class

606

CreateTableRequest tableRequest = mapper.generateCreateTableRequest(User.class);

607

tableRequest.setProvisionedThroughput(new ProvisionedThroughput(5L, 5L));

608

dynamoDBClient.createTable(tableRequest);

609

```

610

611

## Best Practices

612

613

### Data Modeling

614

- **Choose appropriate primary key**: Hash key for uniform distribution, range key for sorting

615

- **Use sparse indexes**: Save storage by only indexing items with specific attributes

616

- **Denormalize data**: Optimize for read patterns, duplicate data where necessary

617

- **Use composite keys**: Combine multiple attributes in sort keys for flexible queries

618

619

### Performance

620

- **Use batch operations**: batchGetItem and batchWriteItem reduce API calls

621

- **Enable auto-scaling**: Automatically adjust throughput based on demand

622

- **Use DynamoDB Streams**: Track changes without polling

623

- **Query over scan**: Queries are more efficient, use indexes when possible

624

625

### Consistency

626

- **Choose read consistency**: Eventually consistent reads (default) vs strongly consistent reads

627

- **Use conditional writes**: Prevent race conditions with condition expressions

628

- **Implement optimistic locking**: Use @DynamoDBVersionAttribute to detect concurrent modifications

629

630

### Cost Optimization

631

- **Use on-demand pricing**: For unpredictable workloads

632

- **Archive old data**: Use TTL or move to S3

633

- **Use projections**: Retrieve only needed attributes

634

- **Monitor capacity**: Avoid throttling by staying within limits

635