Skip to main content
emnode / learn
Site Reliability

Protect DynamoDB tables with AWS Backup

Point-in-time recovery lives with the table and dies with it. Layer AWS Backup on top for isolated, long-term, cross-Region copies — and verify the restore.

12 min·10 sections·AWS

Last reviewed

Unprotected DynamoDB tables: the basics

Why point-in-time recovery is not a backup strategy

DynamoDB offers Point-in-Time Recovery (PITR) — a continuous rolling window that lets you restore a table to any second in the last 35 days. People turn it on, see "continuous backups: enabled," and conclude the table is protected. PITR is genuinely excellent for operational recovery, but it has two limits that matter: the recovery data is bound to the table itself, and the window is exactly 35 days, no more.

Because PITR lives with the table, it dies with the table. The moment someone calls DeleteTable — a leaked admin key, a Terraform destroy against the wrong workspace, a ransomware operator with dynamodb:* — the PITR window goes with it. There is no separate copy in a separate place. PITR also can't copy across Regions or Accounts, and it can't retain anything beyond 35 days, so it satisfies neither cross-Region DR nor multi-year compliance retention.

Continuity check COV-009 flags DynamoDB tables that aren't assigned to any AWS Backup plan. AWS Backup gives you scheduled and on-demand full-table backups stored in a separate vault you control, with long-term retention, cross-Region and cross-Account copy, and Vault Lock immutability (WORM). PITR and AWS Backup are complementary, not redundant: PITR for fast, granular operational restore; AWS Backup for isolated, durable, compliance-grade copies that survive the table being deleted.

In this lesson you'll learn the precise difference between DynamoDB Point-in-Time Recovery and AWS Backup, why they're complementary rather than redundant, and how to bring every critical table under a centralized backup plan that survives the table being deleted. You'll see the AWS CLI to find unprotected tables, create a backup plan with tag-based selection so new tables are auto-protected, run an on-demand backup against a table ARN, and the edge cases that bite — full-table-only granularity, Vault Lock immutability, lifecycle to cold storage, and cross-Region copy for DR.

Fun fact

The Terraform destroy that took the table and the backups with it

A fintech ran a routine terraform apply against what they thought was the staging workspace. A stale TF_WORKSPACE variable pointed it at production, and the plan included a DeleteTable on the live ledger table. PITR was enabled with a full 35-day window — and it vanished in the same API call that deleted the table, because PITR is a property of the table, not a separate store. Recovery came from a single AWS Backup recovery point in a separate vault that a platform engineer had set up three weeks earlier "just in case." The restore took 40 minutes. Without that one isolated copy, 35 days of continuous backups would have been exactly as gone as the table.

Protecting a DynamoDB table in action

Priya runs the platform team at a payments company. A continuity scan returns 18 DynamoDB tables flagged as having no AWS Backup coverage — among them sevenc3-transaction-ledger, the table that records every settlement the platform processes. PITR is on with a 35-day window, so the engineers had it marked as "protected."

She pulls the table's protection posture. PITR confirms enabled, last 35 days recoverable — good for operational rollback. But list-protected-resources returns nothing for the table's ARN: no AWS Backup plan has ever run against it. If someone with dynamodb:DeleteTable got compromised tonight, the table and its entire PITR window would disappear together, with no isolated copy anywhere.

She decides on a two-layer plan: keep PITR for fast granular restore, and add AWS Backup with a tag-based selection so the ledger and every future table tagged Backup=critical is auto-protected. The plan does daily backups with 35-day warm retention, transitions to cold storage after 90 days for 7-year compliance retention, and copies each recovery point to a second Region. The vault gets Vault Lock in compliance mode so not even a rogue admin can delete the copies.

First, check what protection the table actually has — PITR status, then whether any AWS Backup plan covers it.

$ aws dynamodb describe-continuous-backups --table-name sevenc3-transaction-ledger --query 'ContinuousBackupsDescription.PointInTimeRecoveryDescription' && aws backup list-protected-resources --query "Results[?ResourceArn=='arn:aws:dynamodb:us-east-1:123456789012:table/sevenc3-transaction-ledger']" --output text
{
"PointInTimeRecoveryStatus": "ENABLED",
"EarliestRestorableDateTime": "2026-04-20T00:00:00+00:00",
"LatestRestorableDateTime": "2026-05-25T23:59:00+00:00"
}
# list-protected-resources returns nothing for this table ARN.
# PITR covers the last 35 days, but it lives with the table — DeleteTable destroys it. No isolated AWS Backup copy exists.

PITR is on, but no AWS Backup plan covers the table — the only recovery path dies with the table.

Create a backup plan, then a tag-based selection so the ledger and every future table tagged Backup=critical is auto-protected — no per-table wiring.

$ aws backup create-backup-plan --backup-plan file://ledger-plan.json && aws backup create-backup-selection --backup-plan-id 9f8e7d6c-1234-5678-90ab-cdef01234567 --backup-selection '{"SelectionName":"critical-dynamodb","IamRoleArn":"arn:aws:iam::123456789012:role/service-role/AWSBackupDefaultServiceRole","ListOfTags":[{"ConditionType":"STRINGEQUALS","ConditionKey":"Backup","ConditionValue":"critical"}]}'
{
"SelectionId": "a1b2c3d4-5566-7788-99aa-bbccddeeff00",
"BackupPlanId": "9f8e7d6c-1234-5678-90ab-cdef01234567",
"CreationDate": "2026-05-25T14:22:18.193000+00:00"
}
# Tag-based selection: any table tagged Backup=critical is now protected automatically, including ones created next year.

Tag-based selection means new critical tables inherit protection without anyone remembering to wire them up.

DynamoDB protection layers under the hooddeep dive

PITR works by continuously logging every write to the table and retaining the change stream plus periodic snapshots for a rolling 35-day window. A restore replays to any chosen second within that window into a brand-new table. The critical detail is ownership: PITR is a property of the table resource itself. There is no separate stored artifact you can point at — so DeleteTable removes the table and its entire continuous-backup window in one atomic operation. PITR also cannot copy across Region or Account, and 35 days is a hard ceiling, not a configurable one.

AWS Backup for DynamoDB takes a full-table backup — a complete, self-contained recovery point — and writes it to a backup vault. The vault is a separate namespace owned by the AWS Backup service, not your DynamoDB control plane, so an attacker with full dynamodb:* in your account cannot reach into the vault and delete recovery points; that requires distinct backup:* permissions against the vault. Vault Lock in compliance mode goes further: once the lock's grace period passes, no one — not the account root, not AWS Support — can delete a recovery point before its retention expires. That immutability is the actual defense against rogue admins and ransomware.

Two behaviors matter for planning. First, AWS Backup for DynamoDB is full-table granularity — there is no per-item restore; you restore the whole table to a new table name and reconcile from there (PITR is the tool when you need finer-grained, very recent recovery). Second, recovery points support a lifecycle: keep them in warm storage for fast restores, transition to cold storage after a configurable number of days for cheap multi-year retention, and copy each point to a vault in a second Region for DR. Warm backup storage runs roughly $0.10 per GB-month and cold around $0.01 per GB-month in US-East.

# Audit every DynamoDB table in a Region for AWS Backup coverage (PITR is not enough on its own).
ACCOUNT=$(aws sts get-caller-identity --query Account --output text)
REGION=us-east-1
for table in $(aws dynamodb list-tables --query 'TableNames[]' --output text); do
  ARN="arn:aws:dynamodb:$REGION:$ACCOUNT:table/$table"
  PITR=$(aws dynamodb describe-continuous-backups --table-name "$table" \
    --query 'ContinuousBackupsDescription.PointInTimeRecoveryDescription.PointInTimeRecoveryStatus' --output text)
  BACKUP=$(aws backup list-protected-resources \
    --query "Results[?ResourceArn=='$ARN'].ResourceArn" --output text)
  echo "$table  pitr=$PITR  awsbackup=${BACKUP:-NONE}"
done

What is the impact of an unprotected DynamoDB table?

The most direct impact is irrecoverable loss of core application data. A terraform destroy against the wrong workspace, a leaked IAM key in the hands of a ransomware crew, or a maintenance script that drops the wrong table all end the same way if the only protection is PITR: the table and its entire 35-day recovery window vanish together. There is no isolated copy to fall back on, and reconstructing a transactional table from upstream sources — if those even exist — is days-to-weeks of engineering under maximum pressure.

The second-order impact is regulatory and audit exposure. SOC 2, PCI DSS, HIPAA, and GDPR all require demonstrable backups that are isolated from the production system and retained for defined periods — often years. DynamoDB's in-table 35-day PITR window satisfies neither the isolation nor the retention requirement. The moment an auditor asks "show me an immutable, off-system backup of this table retained for your stated period," an unprotected table becomes a finding, and remediation under audit pressure costs far more than the protection would have.

The third-order impact is decision paralysis during an incident. The team that has AWS Backup configured with a tested restore runs one start-restore-job, recovers to a new table, and reconciles — measured in tens of minutes. The team that has only PITR and just watched the table get deleted has no command to run at all; they're escalating to AWS Support and assembling a war room while the business is down. The difference between those two outcomes is one backup plan and one practice restore.

On the cost side, AWS Backup for DynamoDB is cheap relative to the exposure: roughly $0.10 per GB-month of warm backup storage, dropping to about $0.01 per GB-month in cold storage, plus modest cross-Region copy transfer. A 50 GB ledger table with daily backups and 7-year cold retention is single-digit dollars a month. Compared to the cost of the incident it prevents — data loss, regulatory penalties, customer churn — it's a rounding error. The reason coverage isn't blanket-on for every table is that ephemeral and cache tables genuinely don't warrant it; coverage should be data-class-driven, not indiscriminate.

How do you protect DynamoDB tables properly?

Protection is a four-step loop. Keep PITR for fast operational restore, but layer AWS Backup on top for isolation, long-term retention, and DR — then prove the restore works before you need it.

1. Classify tables and keep PITR as the operational layer

Tag every table with a data class — regulated, business-critical, operational, ephemeral. Keep PITR enabled on everything that holds real state: it's the right tool for fast, granular, recent recovery (fat-fingered writes, bad deploys). But understand its limits — it lives with the table and caps at 35 days. PITR is the operational layer, not the protection-of-last-resort. Ephemeral and cache tables can rely on PITR or nothing; the top two tiers need a second, isolated layer.

2. Bring critical tables under AWS Backup with tag-based selection

Create a backup plan and attach a tag-based selection (Backup=critical) rather than naming tables individually. Tag-based selection means every future table tagged critical is auto-protected the moment it's created — no one has to remember to wire it up. Set the schedule (daily is typical for transactional data), warm retention (35 days for fast restores), and a lifecycle transition to cold storage for long-term compliance retention. Remember AWS Backup for DynamoDB is full-table granularity — there's no per-item restore, so PITR remains the tool for surgical recovery.

3. Add Vault Lock and cross-Region copy for the threats PITR can't cover

Put recovery points in a vault with Vault Lock in compliance mode so neither a compromised admin nor ransomware can delete them before retention expires — this is the defense against DeleteTable and rogue-credential attacks that PITR fundamentally cannot provide. Add a cross-Region (and ideally cross-Account) copy action to the plan so a Region-level failure or an account compromise doesn't take the backups with it. Default Vault Lock to a sensible grace period before it becomes irrevocable, and reserve compliance mode for data that genuinely requires WORM.

4. Verify the restore, not just the backup

A backup you've never restored from is a hypothesis. At least quarterly, run start-restore-job against one recovery point per critical plan, restore to a scratch table name, and reconcile a sample of items against the source. Restoration is where things surprise you — the restored table is a new table (you reconcile or swap names), IAM and KMS permissions on the target must be right, and capacity settings reset to defaults. Practice this when nothing is on fire so the real incident is one known command.

# Run an on-demand AWS Backup job for a DynamoDB table to validate the vault, plan, and IAM role end-to-end.
aws backup start-backup-job \
  --backup-vault-name ledger-vault \
  --resource-arn arn:aws:dynamodb:us-east-1:123456789012:table/sevenc3-transaction-ledger \
  --iam-role-arn arn:aws:iam::123456789012:role/service-role/AWSBackupDefaultServiceRole \
  --lifecycle MoveToColdStorageAfterDays=90,DeleteAfterDays=2555

# Once the first recovery point exists, restore it to a new table to prove the path works.
aws backup start-restore-job \
  --recovery-point-arn arn:aws:backup:us-east-1:123456789012:recovery-point:01234567-89ab-cdef-0123-456789abcdef \
  --iam-role-arn arn:aws:iam::123456789012:role/service-role/AWSBackupDefaultServiceRole \
  --metadata '{"targetTableName":"sevenc3-transaction-ledger-restore-test"}' \
  --resource-type DynamoDB

Quick quiz

Question 1 of 5

Your DynamoDB table has Point-in-Time Recovery enabled with the full 35-day window. A compromised IAM key with dynamodb:* runs DeleteTable on it at 3am. What actually lets you recover?

You've completed Protect DynamoDB tables with AWS Backup. You now know why Point-in-Time Recovery dies with the table and AWS Backup survives it, how the two are complementary rather than redundant, and the four-step loop — classify, cover with tag-based selection, lock and copy cross-Region, verify the restore — that protects critical data without over-protecting ephemeral tables. The next time a continuity scan flags an uncovered DynamoDB table, you'll have a defensible path from "flagged" to "protected and proven."

Back to the library