Why this matters
- VaultCommerce emits Stream events when order status changes — search index, email, and analytics services react without polling the table.
- DAX helps read-heavy product-metadata paths but hides stale reads — only cache idempotent, TTL-tolerant data.
- Checkout must deduct inventory and create an order atomically — TransactWrite with condition checks prevents double-sell.
Partition key: USER#42Routes to shard
Items in partition
ORDER#2026-001Sort key
ORDER#2026-002Sort key
PROFILESort key
DynamoDB Streams
Streams append INSERT, MODIFY, REMOVE records with old/new images. Enable on the table, attach a Lambda event source mapping:
aws dynamodb update-table \
--table-name VaultCommerce \
--stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES
def handler(event, context):
for record in event["Records"]:
if record["eventName"] in ("INSERT", "MODIFY"):
new_image = record["dynamodb"]["NewImage"]
if new_image.get("SK", {}).get("S", "").startswith("ORDER#"):
sync_to_elasticsearch(unmarshall(new_image))
Stream view types
- KEYS_ONLY — partition and sort keys only.
- NEW_IMAGE — item after change.
- OLD_IMAGE — item before change.
- NEW_AND_OLD_IMAGES — both — VaultCommerce uses this for audit diffs.
Consumers must be idempotent — Lambda retries duplicate events.
DAX caching layer
import amazondax
from boto3.dynamodb.types import TypeDeserializer
client = amazondax.AmazonDaxClient(resource_id="vaultcommerce-dax.xxxxxx.dax-clusters.us-east-1.amazonaws.com:8111")
# Same API as DynamoDB — point SDK at DAX endpoint for reads/writes
DAX maintains item cache with write-through invalidation. VaultCommerce caches PRODUCT# metadata reads through DAX; never cache stock counts that change every checkout.
TransactWriteItems
client.transact_write_items(TransactItems=[
{
"Put": {
"TableName": "VaultCommerce",
"Item": {"PK": {"S": f"USER#{uid}"}, "SK": {"S": f"ORDER#{oid}"}, ...},
"ConditionExpression": "attribute_not_exists(PK)",
}
},
{
"Update": {
"TableName": "VaultCommerce",
"Key": {"PK": {"S": f"PRODUCT#{sku}"}, "SK": {"S": "INVENTORY"}},
"UpdateExpression": "SET qty = qty - :one",
"ConditionExpression": "qty >= :one",
"ExpressionAttributeValues": {":one": {"N": "1"}},
}
},
])
All items succeed or none apply — conditional failures roll back the whole transaction. Limit: 100 actions, 4 MB payload, items must fit service constraints.
Quick recall
Everything you need if you only revisit this box.
- Streams: change feed for Lambda — enable NEW_AND_OLD_IMAGES for rich consumers.
- Stream handlers must be idempotent — at-least-once delivery on retries.
- DAX: microsecond read cache — write-through; not for rapidly mutating counters.
- TransactWriteItems: up to 100 all-or-nothing ops with condition expressions.
- VaultCommerce uses transactions for checkout; Streams for search/email sync.
- Route inventory reads around DAX; cache stable product metadata through DAX.
Test yourself
Answer these before moving on — recall is what makes it stick.