AWS Cheatsheet

DynamoDB

Use this AWS reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

Key Concepts

ConceptDescription
TableTop-level container. No joins across tables.
Partition Key (PK)Required. Determines data distribution across partitions.
Sort Key (SK)Optional. Enables range queries within a partition. Together with PK = composite primary key.
ItemA row. Max 400 KB per item.
AttributeA field. Schema-less — different items can have different attributes.
GSIGlobal Secondary Index — alternate PK+SK; can query any attribute.
LSILocal Secondary Index — same PK, different SK; must be defined at table creation.
StreamsChange data capture — ordered log of item changes.
WCU / RCUWrite/Read Capacity Units for provisioned mode.

Create & Describe Tables

# Simple table (PK only)
aws dynamodb create-table \
  --table-name Users \
  --attribute-definitions AttributeName=userId,AttributeType=S \
  --key-schema AttributeName=userId,KeyType=HASH \
  --billing-mode PAY_PER_REQUEST

# Table with composite key (PK + SK)
aws dynamodb create-table \
  --table-name Orders \
  --attribute-definitions \
    AttributeName=customerId,AttributeType=S \
    AttributeName=orderId,AttributeType=S \
  --key-schema \
    AttributeName=customerId,KeyType=HASH \
    AttributeName=orderId,KeyType=RANGE \
  --billing-mode PAY_PER_REQUEST

# With a GSI
aws dynamodb create-table \
  --table-name Posts \
  --attribute-definitions \
    AttributeName=pk,AttributeType=S \
    AttributeName=sk,AttributeType=S \
    AttributeName=gsi1pk,AttributeType=S \
  --key-schema \
    AttributeName=pk,KeyType=HASH \
    AttributeName=sk,KeyType=RANGE \
  --global-secondary-indexes '[{
    "IndexName": "GSI1",
    "KeySchema": [{"AttributeName":"gsi1pk","KeyType":"HASH"},
                  {"AttributeName":"sk","KeyType":"RANGE"}],
    "Projection": {"ProjectionType":"ALL"}
  }]' \
  --billing-mode PAY_PER_REQUEST

aws dynamodb describe-table --table-name Users
aws dynamodb list-tables
aws dynamodb wait table-exists --table-name Users

CRUD Operations

PutItem (create or replace)

aws dynamodb put-item \
  --table-name Users \
  --item '{
    "userId": {"S": "user-123"},
    "email":  {"S": "alice@example.com"},
    "age":    {"N": "30"},
    "active": {"BOOL": true},
    "tags":   {"SS": ["admin","beta"]}
  }'

# Conditional put (only if not exists)
aws dynamodb put-item \
  --table-name Users \
  --item '{"userId": {"S": "user-123"}, "email": {"S": "alice@example.com"}}' \
  --condition-expression "attribute_not_exists(userId)"

GetItem

aws dynamodb get-item \
  --table-name Users \
  --key '{"userId": {"S": "user-123"}}'

# Project specific attributes
aws dynamodb get-item \
  --table-name Users \
  --key '{"userId": {"S": "user-123"}}' \
  --projection-expression "email, age"

# Strongly consistent read
aws dynamodb get-item \
  --table-name Users \
  --key '{"userId": {"S": "user-123"}}' \
  --consistent-read

UpdateItem

aws dynamodb update-item \
  --table-name Users \
  --key '{"userId": {"S": "user-123"}}' \
  --update-expression "SET age = :a, #n = :name" \
  --expression-attribute-names '{"#n": "name"}' \
  --expression-attribute-values '{":a": {"N": "31"}, ":name": {"S": "Alice"}}' \
  --return-values ALL_NEW

# Increment a counter atomically
aws dynamodb update-item \
  --table-name Users \
  --key '{"userId": {"S": "user-123"}}' \
  --update-expression "ADD loginCount :one" \
  --expression-attribute-values '{":one": {"N": "1"}}'

# Remove an attribute
aws dynamodb update-item \
  --table-name Users \
  --key '{"userId": {"S": "user-123"}}' \
  --update-expression "REMOVE tempFlag"

DeleteItem

aws dynamodb delete-item \
  --table-name Users \
  --key '{"userId": {"S": "user-123"}}'

# Conditional delete
aws dynamodb delete-item \
  --table-name Users \
  --key '{"userId": {"S": "user-123"}}' \
  --condition-expression "active = :false" \
  --expression-attribute-values '{":false": {"BOOL": false}}'

Query & Scan

Query (efficient — uses index)

# All orders for a customer
aws dynamodb query \
  --table-name Orders \
  --key-condition-expression "customerId = :cid" \
  --expression-attribute-values '{":cid": {"S": "cust-456"}}'

# Orders with SK prefix
aws dynamodb query \
  --table-name Orders \
  --key-condition-expression "customerId = :cid AND begins_with(orderId, :prefix)" \
  --expression-attribute-values '{":cid":{"S":"cust-456"}, ":prefix":{"S":"2024-"}}'

# Filter results (applied after key condition — still reads all matching items)
aws dynamodb query \
  --table-name Orders \
  --key-condition-expression "customerId = :cid" \
  --filter-expression "#s = :status" \
  --expression-attribute-names '{"#s":"status"}' \
  --expression-attribute-values '{":cid":{"S":"cust-456"}, ":status":{"S":"shipped"}}'

# Query a GSI
aws dynamodb query \
  --table-name Posts \
  --index-name GSI1 \
  --key-condition-expression "gsi1pk = :v" \
  --expression-attribute-values '{":v": {"S": "category#tech"}}'

# Paginate (use --starting-token with LastEvaluatedKey)
aws dynamodb query \
  --table-name Orders \
  --key-condition-expression "customerId = :cid" \
  --expression-attribute-values '{":cid":{"S":"cust-456"}}' \
  --limit 20

Scan (reads entire table — expensive)

aws dynamodb scan --table-name Users

# Parallel scan (split into N segments)
aws dynamodb scan \
  --table-name Users \
  --segment 0 --total-segments 4

aws dynamodb scan \
  --table-name Users \
  --filter-expression "age > :a" \
  --expression-attribute-values '{":a": {"N": "25"}}'

Batch Operations

# BatchGetItem (up to 100 items)
aws dynamodb batch-get-item \
  --request-items '{
    "Users": {
      "Keys": [
        {"userId": {"S": "user-123"}},
        {"userId": {"S": "user-456"}}
      ]
    }
  }'

# BatchWriteItem (up to 25 put/delete)
aws dynamodb batch-write-item \
  --request-items '{
    "Users": [
      {"PutRequest": {"Item": {"userId":{"S":"u1"},"email":{"S":"a@b.com"}}}},
      {"DeleteRequest": {"Key": {"userId":{"S":"u-old"}}}}
    ]
  }'

Transactions

# TransactWriteItems (all-or-nothing, up to 100 items across tables)
aws dynamodb transact-write-items \
  --transact-items '[
    {
      "Put": {
        "TableName": "Orders",
        "Item": {"customerId":{"S":"c1"},"orderId":{"S":"o1"},"total":{"N":"99"}},
        "ConditionExpression": "attribute_not_exists(orderId)"
      }
    },
    {
      "Update": {
        "TableName": "Inventory",
        "Key": {"productId":{"S":"p1"}},
        "UpdateExpression": "SET stock = stock - :one",
        "ConditionExpression": "stock > :zero",
        "ExpressionAttributeValues": {":one":{"N":"1"},":zero":{"N":"0"}}
      }
    }
  ]'

Capacity & Billing Modes

# Switch to provisioned (set read/write capacity)
aws dynamodb update-table \
  --table-name Users \
  --billing-mode PROVISIONED \
  --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5

# Switch back to on-demand
aws dynamodb update-table \
  --table-name Users \
  --billing-mode PAY_PER_REQUEST

# Enable auto-scaling on provisioned table
aws application-autoscaling register-scalable-target \
  --service-namespace dynamodb \
  --resource-id "table/Users" \
  --scalable-dimension dynamodb:table:ReadCapacityUnits \
  --min-capacity 5 --max-capacity 100

TTL (Time-to-Live)

# Enable TTL on an attribute (must be a Unix epoch number)
aws dynamodb update-time-to-live \
  --table-name Sessions \
  --time-to-live-specification Enabled=true,AttributeName=expiresAt

aws dynamodb describe-time-to-live --table-name Sessions

Streams & DynamoDB Global Tables

# Enable streams
aws dynamodb update-table \
  --table-name Users \
  --stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES

# List streams
aws dynamodbstreams list-streams --table-name Users

# Global tables (multi-region replication, 2019 version)
# Requires streams enabled with NEW_AND_OLD_IMAGES; run in the source region
aws dynamodb update-table \
  --table-name Users \
  --replica-updates '[{"Create": {"RegionName": "eu-west-1"}}]'

# Check replica status
aws dynamodb describe-table --table-name Users \
  --query 'Table.Replicas'

The legacy 2017 API (aws dynamodb create-global-table) is deprecated — new tables must use the 2019 --replica-updates path above.

Backup & Export

# On-demand backup
aws dynamodb create-backup \
  --table-name Users \
  --backup-name users-backup-2024-01

aws dynamodb list-backups --table-name Users
aws dynamodb restore-table-from-backup \
  --target-table-name Users-restored \
  --backup-arn arn:aws:dynamodb:us-east-1:123:table/Users/backup/...

# Export to S3 (point-in-time, no table interruption)
aws dynamodb export-table-to-point-in-time \
  --table-arn arn:aws:dynamodb:us-east-1:123:table/Users \
  --s3-bucket my-bucket \
  --s3-prefix exports/ \
  --export-format DYNAMODB_JSON

Delete Table

aws dynamodb delete-table --table-name Users
aws dynamodb wait table-not-exists --table-name Users