Beginner6 min read

How to Copy a DynamoDB Table to Another Account or Region

DynamoDB has no one-click "copy table" command — not in the AWS CLI, not in the console. Copying or migrating a table across accounts or regions means picking one of four approaches, each with different cost, downtime, and fidelity tradeoffs. This guide covers all four, plus the operational gotchas that bite in production.

How do I copy a DynamoDB table to another account or region?

There's no native copy-table command. Pick one of four approaches: a Scan + BatchWriteItem script for small one-off copies, an S3 export-then-import for large tables, AWS Backup copy + restore for cross-account moves with full fidelity, or global tables for ongoing live replication. Each restore or import creates a new table.

SituationBest approach
Small table, one-off, full controlScan + BatchWriteItem script
Large table, can tolerate a snapshotS3 export → import (creates new table)
Cross-account / cross-region with restoreAWS Backup copy + restore
Ongoing live replication (not a one-time copy)Global tables

No approach is universally "right" — it depends on table size, whether you need a point-in-time snapshot or live data, and whether the destination is a new or existing table.

Approach 1: Scan + BatchWriteItem (the script)

The lowest-tech option: read every item from the source with Scan, write it to the destination with BatchWriteItem. Works cross-account and cross-region as long as your script holds credentials for both sides (or assumes a role in the target account).

# Sketch — read source, write target (pseudo; use the SDK in real life)
aws dynamodb scan --table-name SourceTable --region us-east-1 \
  > items.json
# transform Items[] into BatchWriteItem RequestItems, then:
aws dynamodb batch-write-item --request-items file://batch.json \
  --region eu-west-1

The gotchas are real and easy to miss:

  • BatchWriteItem caps at 25 items or 16MB per call — you must chunk, and a single call can return unprocessed items you have to retry with exponential backoff (API reference).
  • Writes consume write capacity. On a target you'll hit ProvisionedThroughputExceededException fast; absorbs more but still has per-partition soft limits. Size the write load against the destination's capacity before you start.
  • Scan reads the whole table and meters every item — the classic Query-vs-Scan cost. A big table also means paginating through LastEvaluatedKey; see pagination.
  • It's not atomic. Items written while the scan is in flight can be missed — you only get a consistent snapshot if the source is quiescent.

Best for small tables or when you need to transform/filter during the copy.

Approach 2: Export to S3, then import to a new table

For large tables, DynamoDB's managed export to S3 plus import from S3 avoids hammering your capacity at all.

Export snapshots the table to an S3 bucket (how it works):

  • Requires point-in-time recovery (PITR) enabled on the source table.
  • Does not consume read capacity and has no impact on table performance — it reads from continuous backups, not the live table.
  • Outputs DynamoDB JSON or Amazon Ion format. (The DynamoDB-JSON wire format is what lands in S3, type tags and all.)
  • Can write to an S3 bucket owned by another account and in a different region.
  • Supports full and incremental exports (incremental export GA, Sept 2023).

Import then builds a fresh table from that S3 data (how it works):

  • Imports into a brand-new table only — you cannot import into an existing table.
  • Does not consume write capacity on the new table.
  • Accepts CSV, DynamoDB JSON, or Amazon Ion (optionally GZIP/ZSTD compressed).
  • The source S3 bucket may be in another account or another region.
  • You can define secondary indexes at import time, queryable as soon as the import completes.

This is the cleanest path for a large cross-account/cross-region migration where a point-in-time snapshot (not live data) is acceptable.

Approach 3: AWS Backup copy + restore

If you already use AWS Backup, it copies recovery points across accounts and regions (cross-account migration guide):

  1. Back up the source table into a backup vault.
  2. Copy the backup to a vault in the target account/region.
  3. Restore it to a new table in the target.

Key constraints:

  • Cross-account copy requires both accounts to be in the same AWS Organization.
  • Restore always creates a new table — you can't restore over an existing one.
  • are preserved by default (exclude some or all to save on restore time/cost); you can't add new indexes at restore.
  • Encryption gotcha: to keep the same KMS key on a cross-region restore you need a multi-region key; for cross-account you must share the key with the target account. AWS-owned and AWS-managed keys can't be shared or made multi-region (restore encryption notes).

Approach 4: Global tables (live replication, not a one-time copy)

Global tables replicate a table across regions — and now optionally across accounts (multi-account GA, Feb 2026) — continuously. Any replica serves reads and writes (multi-active), with asynchronous, last-writer-wins replication (global tables docs).

This is not a "copy and walk away" tool — it's ongoing replication. Use it when you want the destination region to stay in sync indefinitely (DR, low-latency local reads), not for a clean one-time migration. Add a region to an existing table and DynamoDB backfills the existing data into the new replica.

Operational gotchas (all approaches)

  • GSIs aren't free to recreate. A scan+write copy doesn't carry indexes — you define them on the target and they backfill (and cost) separately. Plan your GSI vs LSI layout on the destination up front; LSIs can only be created at table-creation time (LSI docs).
  • Capacity mode doesn't transfer. The new table starts with whatever mode you set, not the source's. Estimate the write load before a scan+write copy — size a representative item with the item-size calculator and multiply by item count to ballpark WCUs.
  • , , auto-scaling, and tags are table settings, not data — none of the copy methods carry all of them. Re-apply them on the target.
  • DynamoDB JSON ≠ plain JSON. Exports and scans emit type-tagged DynamoDB-JSON; if you're transforming en route, the DynamoDB JSON converter handles the marshalling.

FAQ

Is there an AWS CLI command to copy a DynamoDB table? No. There's no native copy-table command. You combine scan + batch-write-item, or use the managed export/import or AWS Backup features.

How do I copy a DynamoDB table to another account? Three options: a scan+write script with credentials for both accounts, an S3 export/import (the bucket can be cross-account), or AWS Backup copy+restore (both accounts must be in the same AWS Organization).

How do I copy a DynamoDB table to another region? S3 export/import and AWS Backup both support cross-region. For ongoing cross-region sync rather than a one-time copy, add a global-table replica in the target region.

Does copying a table copy its indexes? S3 import and AWS Backup restore let you keep/define secondary indexes; a scan+write script does not — you create indexes on the target yourself, and they backfill separately.

Can I import into an existing DynamoDB table? No. DynamoDB's S3 import and AWS Backup restore both create a new table. To merge into an existing table, use a scan+write script.


A GUI makes the cutover sane: browse both source and target side by side, verify item counts and a few sample records after the copy, and run ad-hoc checks without writing a scan script. Download DynoTable to inspect tables across accounts and regions during a migration.

Updated