DynamoDB PutItem vs UpdateItem: Understanding Write Operations
One of the most common questions DynamoDB developers face is when to use PutItem
versus UpdateItem
. Though these operations might seem similar at first glance, understanding their subtle differences is crucial for designing efficient and reliable applications.
This guide provides a clear explanation of both operations, their key differences, and practical guidance on when to use each one.
What is PutItem?
PutItem
is a DynamoDB operation that creates a new item or completely replaces an existing item with the same primary key.
Key Characteristics of PutItem
- Creates a new item if the specified primary key doesn’t exist
- Completely replaces all attributes of an existing item
- Any attributes not specified in the operation are removed
- Simple “all or nothing” approach to writing data
Think of PutItem
as saying: “Replace whatever is at this key with exactly this new item.”
What is UpdateItem?
UpdateItem
is a DynamoDB operation that modifies specific attributes of an existing item, or creates a new item if it doesn’t exist.
Key Characteristics of UpdateItem
- Updates only the specified attributes of an existing item
- Preserves any attributes not mentioned in the update
- Creates a new item if the specified primary key doesn’t exist
- Supports complex update expressions for atomic counters, list operations, etc.
Think of UpdateItem
as saying: “Modify these specific attributes at this key, but leave everything else as is.”
Side-by-Side Comparison
To clearly illustrate the differences, let’s compare these operations across several important dimensions:
Aspect | PutItem | UpdateItem |
---|---|---|
When Item Exists | Completely replaces the item | Modifies only specified attributes |
When Item Doesn’t Exist | Creates a new item | Creates a new item (unless you add a condition) |
Unspecified Attributes | Removes them | Preserves them |
Atomic Operations | No built-in support | Supports increment/decrement, list operations |
Conditional Writes | Supported | Supported |
Throughput Consumption | Based on item size | Based on the larger of old and new item sizes |
Use Case | Complete overwrites or new items | Partial updates or atomic operations |
Operation Outcomes: Seeing the Difference
Let’s see a concrete example of how these operations affect data differently:
Starting Item:
{
"id": "123",
"name": "Original Name",
"age": 30,
"address": {
"city": "Seattle",
"zip": "98101"
},
"interests": ["reading", "hiking"]
}
Using PutItem:
// PutItem operation with partial attributes
PutItem({
"id": "123",
"name": "New Name",
"address": {
"city": "Portland"
}
})
Result after PutItem:
{
"id": "123",
"name": "New Name",
"address": {
"city": "Portland"
}
// age, zip, and interests are GONE
}
Using UpdateItem:
// UpdateItem operation with the same partial attributes
UpdateItem({
"id": "123",
SET: "name = :name, address.city = :city",
ExpressionAttributeValues: {
":name": "New Name",
":city": "Portland"
}
})
Result after UpdateItem:
{
"id": "123",
"name": "New Name",
"age": 30,
"address": {
"city": "Portland",
"zip": "98101"
},
"interests": ["reading", "hiking"]
// All unspecified attributes are PRESERVED
}
This example clearly demonstrates that PutItem
completely replaces the item, while UpdateItem
only modifies the specified attributes.
Dynomate: Modern DynamoDB GUI Client
Built for real developer workflows with AWS profile integration, multi-session support, and team collaboration.
No account needed. Install and start using immediately.
- Table browsing across regions
- Flexible query & scan interface
- AWS API logging & debugging
Conditional Write Operations
Both PutItem
and UpdateItem
support conditional writes, allowing you to specify conditions that must be true for the operation to succeed. This is crucial for maintaining data integrity.
PutItem with Condition (Insert Only)
To ensure PutItem
only creates new items and never overwrites existing ones:
// AWS SDK v3 example
const params = {
TableName: "Users",
Item: {
id: "123",
name: "New User",
createDate: new Date().toISOString()
},
ConditionExpression: "attribute_not_exists(id)"
// Will fail if an item with this id already exists
};
UpdateItem with Condition (Update Only)
To ensure UpdateItem
only updates existing items and never creates new ones:
// AWS SDK v3 example
const params = {
TableName: "Users",
Key: {
id: "123"
},
UpdateExpression: "SET lastLogin = :date",
ExpressionAttributeValues: {
":date": new Date().toISOString()
},
ConditionExpression: "attribute_exists(id)"
// Will fail if an item with this id doesn't exist
};
Performance and Throughput Considerations
A common misconception is that UpdateItem
might be more efficient because it only modifies specific attributes. However, the throughput consumption calculation is more nuanced:
How DynamoDB Calculates Write Consumption
For both operations, DynamoDB calculates consumed write capacity based on:
- The size of the item being written
- For
UpdateItem
, the larger of the item’s size before and after the update
This means:
- If you’re completely replacing a large item with a small one using
PutItem
, you only pay for the small item size - If you’re making a small change to a large item using
UpdateItem
, you pay for the entire large item size
As AWS states in their documentation: “Even if UpdateItem changes just a subset of the item’s attributes, UpdateItem will still consume the full amount of provisioned throughput (the larger of the ‘before’ and ‘after’ item sizes).”
In practical terms, there’s usually no throughput advantage to using UpdateItem
instead of PutItem
based solely on the size of the changes.
When to Use PutItem
PutItem
is typically the better choice when:
- Creating new items where you’re certain the key doesn’t exist
- Completely replacing items with entirely new values
- Simplified code paths where you want predictable “replace everything” behavior
- Cleaning up data by ensuring no unexpected attributes persist
PutItem Use Case Examples:
- Importing data from an external system
- Regenerating denormalized or calculated data
- Implementing a snapshot-based approach where you always write complete objects
When to Use UpdateItem
UpdateItem
is typically the better choice when:
- Modifying specific attributes without affecting others
- Incrementing counters or updating timestamps atomically
- Appending to lists or modifying nested attributes
- Conditional updates based on existing attribute values
- Concurrent updates where multiple processes might be writing different attributes
UpdateItem Use Case Examples:
- Incrementing view counters or scores
- Updating user profile fields individually
- Adding items to a shopping cart
- Implementing optimistic locking with version numbers
Familiar with these Dynamodb Challenges ?
- Writing one‑off scripts for simple DynamoDB operations
- Constantly switching between AWS profiles and regions
- Sharing and managing database operations with your team
You should try Dynomate GUI Client for DynamoDB
- Create collections of operations that work together like scripts
- Seamless integration with AWS SSO and profile switching
- Local‑first design with Git‑friendly sharing for team collaboration
Code Examples Across Different Languages
AWS CLI Examples
PutItem
aws dynamodb put-item \
--table-name Users \
--item '{"id": {"S": "123"}, "name": {"S": "John Doe"}, "age": {"N": "30"}}' \
--return-consumed-capacity TOTAL
UpdateItem
aws dynamodb update-item \
--table-name Users \
--key '{"id": {"S": "123"}}' \
--update-expression "SET #n = :name, age = :age" \
--expression-attribute-names '{"#n": "name"}' \
--expression-attribute-values '{":name": {"S": "John Doe"}, ":age": {"N": "31"}}' \
--return-consumed-capacity TOTAL
Python (Boto3) Examples
PutItem
import boto3
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('Users')
response = table.put_item(
Item={
'id': '123',
'name': 'John Doe',
'age': 30
},
ReturnConsumedCapacity='TOTAL'
)
UpdateItem
import boto3
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('Users')
response = table.update_item(
Key={
'id': '123'
},
UpdateExpression='SET #n = :name, age = :age',
ExpressionAttributeNames={
'#n': 'name'
},
ExpressionAttributeValues={
':name': 'John Doe',
':age': 31
},
ReturnConsumedCapacity='TOTAL'
)
Node.js Examples
PutItem
const AWS = require('aws-sdk');
const docClient = new AWS.DynamoDB.DocumentClient();
const params = {
TableName: 'Users',
Item: {
id: '123',
name: 'John Doe',
age: 30
},
ReturnConsumedCapacity: 'TOTAL'
};
docClient.put(params, (err, data) => {
if (err) console.error(err);
else console.log(data);
});
UpdateItem
const AWS = require('aws-sdk');
const docClient = new AWS.DynamoDB.DocumentClient();
const params = {
TableName: 'Users',
Key: {
id: '123'
},
UpdateExpression: 'SET #n = :name, age = :age',
ExpressionAttributeNames: {
'#n': 'name'
},
ExpressionAttributeValues: {
':name': 'John Doe',
':age': 31
},
ReturnConsumedCapacity: 'TOTAL'
};
docClient.update(params, (err, data) => {
if (err) console.error(err);
else console.log(data);
});
Update Item If Exists (Common Pattern)
A frequently requested pattern is to update an item only if it already exists. Here’s how to implement it:
const params = {
TableName: 'Users',
Key: {
id: '123'
},
UpdateExpression: 'SET lastLogin = :now',
ExpressionAttributeValues: {
':now': new Date().toISOString()
},
ConditionExpression: 'attribute_exists(id)'
};
// This will fail with ConditionalCheckFailedException if the item doesn't exist
docClient.update(params, (err, data) => {
if (err && err.code === 'ConditionalCheckFailedException') {
console.log('Item does not exist');
} else if (err) {
console.error('Error:', err);
} else {
console.log('Update successful:', data);
}
});
Idempotency Considerations
When building resilient systems, idempotency (the ability to perform an operation multiple times without changing the result) is important:
PutItem
is naturally idempotent if you always specify the complete itemUpdateItem
with expressions likeSET attribute = :value
is also idempotentUpdateItem
with expressions likeADD counter :increment
is NOT idempotent
If your system might retry operations (e.g., in case of network failures), consider how this affects your choice between the two operations.
Best Practices Summary
Based on all the information above, here are some best practices:
-
Use PutItem when:
- Creating completely new items
- Replacing items entirely
- You want to ensure no old attributes remain
-
Use UpdateItem when:
- Modifying specific attributes
- Performing atomic operations (increments, adds to lists)
- Building optimistic locking patterns
- Updating nested attributes
-
Add conditions to prevent unintended consequences:
- Use
attribute_not_exists()
with PutItem to avoid overwriting - Use
attribute_exists()
with UpdateItem to avoid creating
- Use
-
Monitor consumed capacity:
- Both operations might use similar capacity despite different semantics
- Remember, UpdateItem consumes based on the larger of before/after sizes
Common Questions Answered
Does UpdateItem use less throughput than PutItem?
No, not necessarily. DynamoDB charges based on the item size, not the number of attributes changed. For UpdateItem, you pay for the larger of the before and after sizes of the entire item, not just the changed attributes.
Can both operations create new items?
Yes, both PutItem and UpdateItem can create new items if the specified key doesn’t exist. Use conditional expressions if you want to prevent either operation from creating or updating.
Which one is faster?
In terms of latency, there’s typically no significant difference. Both operations require the same network round trip and similar processing within DynamoDB.
When should I use TransactWriteItems instead?
Use TransactWriteItems when you need to perform multiple operations (Put, Update, Delete) as an all-or-nothing transaction across multiple items or tables.
Switching from Dynobase? Try Dynomate
Developers are switching to Dynomate for these key advantages:
Better Multi-Profile Support
- Native AWS SSO integration
- Seamless profile switching
- Multiple accounts in a single view
Developer-Focused Workflow
- Script-like operation collections
- Chain data between operations
- Full AWS API logging for debugging
Team Collaboration
- Git-friendly collection sharing
- No account required for installation
- Local-first data storage for privacy
Privacy & Security
- No account creation required
- 100% local data storage
- No telemetry or usage tracking
Conclusion
Understanding the differences between PutItem
and UpdateItem
is essential for effective DynamoDB application design. While they might seem similar, their behavior with existing attributes and their support for different types of updates makes each more suitable for specific scenarios.
Remember:
PutItem
replaces entire items, removing any attributes not specifiedUpdateItem
modifies only the specified attributes, preserving everything else- Both operations consume write capacity based on item size, not the number of attributes changed
- Conditional expressions can enhance both operations to handle existence checks
For more advanced DynamoDB operations, consider using Dynomate to visualize your data and simplify the process of creating, updating, and querying your tables. Dynomate makes it easier to understand the impact of different write operations on your data without writing code.
To learn more about other DynamoDB topics, check out our related guides: