Skip to main content

Back up Amazon DynamoDB

DynamoDB is a managed NoSQL service, so a "dump" means exporting table items to a local file you can upload. This guide covers the two common approaches: a quick scan for small/medium tables, and the AWS-native point-in-time export to S3 for large tables.

Prerequisitesโ€‹

  • The AWS CLI v2:
    • macOS: brew install awscli
    • Linux: AWS-provided installer
  • AWS credentials configured (aws configure) with at least dynamodb:Scan (and dynamodb:DescribeTable) on the table.

1. Sign in & create an API keyโ€‹

You need a Lighthouse account, a workspace, and an API key before you can upload a backup.

  1. Sign in to the portal and claim your free 5 GB workspace โ€” see Web Portal & Free Workspace.

  2. Create an API key scoped backup:write, backup:read, snapshots:read โ€” see API Keys.

  3. Export the credentials so the upload step can read them:

    export LH_API_KEY="lh_xxxxxxxxxxxxxxxxxxxxxxxx"
    export LH_WORKSPACE_ID="your-workspace-uuid"

Already have a key? Continue to the dump step below.

2. Create the dumpโ€‹

Create the local dump directory once:

mkdir -p ./db-dumps

Option A โ€” scan to JSON (simple, small/medium tables)โ€‹

aws dynamodb scan \
--table-name app_table \
--output json \
> ./db-dumps/app_table.json

This writes every item (in DynamoDB JSON format) to one file. For tables larger than ~1 MB the result is paginated; loop with the pagination token:

# Paginated scan into a single newline-delimited JSON file.
NEXT=""
: > ./db-dumps/app_table.json
while : ; do
if [ -z "$NEXT" ]; then
OUT=$(aws dynamodb scan --table-name app_table --output json)
else
OUT=$(aws dynamodb scan --table-name app_table --output json \
--starting-token "$NEXT")
fi
echo "$OUT" | jq -c '.Items[]' >> ./db-dumps/app_table.json
NEXT=$(echo "$OUT" | jq -r '.LastEvaluatedKey // empty')
[ -z "$NEXT" ] && break
done
Cost & throughput

A full scan reads the entire table and consumes read capacity. For large or production tables, prefer Option B (managed export), which does not consume table capacity.

Option B โ€” Point-in-time export to S3 (large tables, no capacity cost)โ€‹

Requires point-in-time recovery (PITR) enabled on the table.

aws dynamodb export-table-to-point-in-time \
--table-arn arn:aws:dynamodb:us-east-1:123456789012:table/app_table \
--s3-bucket your-export-bucket \
--export-format DYNAMODB_JSON

Then pull the export down so the BaaS job can upload it (see Amazon S3):

aws s3 sync s3://your-export-bucket/AWSDynamoDB ./db-dumps/dynamodb-export

3. Verify the dumpโ€‹

ls -lh ./db-dumps/app_table.json
jq '. | length? // 1' ./db-dumps/app_table.json | head # sanity-check it parses

4. Restore (recovery test)โ€‹

For the scan output, re-import items with batch-write-item (25 items per call). A minimal loop with jq:

jq -c '.Items // [.]' ./db-dumps/app_table.json \
| jq -c '{ "app_table_restore": [ .[] | { PutRequest: { Item: . } } ] }' \
| while read -r batch; do
aws dynamodb batch-write-item --request-items "$batch"
done

For Option B exports, use AWS's import-table from S3.

5. Upload to Lighthouseโ€‹

Your export is now in ./db-dumps. After creating an authenticated SDK client with the API key from step 1, upload the directory as a snapshot:

snapshot, err := client.Backup([]string{"./db-dumps"}, &sdktypes.BackupOptions{})
if err != nil {
log.Fatal(err)
}
log.Printf("snapshotId=%s", snapshot.SnapshotID)

To run this on a schedule, use Automated backup with scheduling.

The dump command for this table, ready to drop into the scheduled job's make_dump():

aws dynamodb scan --table-name app_table --output json > ./db-dumps/app_table.json