Estuary

PostgreSQL to DynamoDB: 2 Ways to Migrate or Replicate Data

Move PostgreSQL data to DynamoDB using managed CDC or AWS DMS. Compare both approaches for one-time migration, ongoing replication, and DynamoDB key mapping.

Postgres to DynamoDB
Share this article

PostgreSQL data can be moved to Amazon DynamoDB using an AWS-native migration service such as AWS DMS or a managed CDC pipeline such as Estuary.

The right approach depends on whether you need a one-time migration or ongoing synchronization, but there is one important difference from PostgreSQL-to-PostgreSQL moves: DynamoDB uses a key-value/document model, so relational tables may need to be reshaped around DynamoDB access patterns rather than copied 1:1.

For ongoing replication, PostgreSQL changes can be captured from the write-ahead log (WAL) and applied to DynamoDB as source rows change. For one-time or AWS-native migrations, AWS DMS can load existing PostgreSQL data and continue with CDC if required.

In this guide, we’ll compare two approaches:

  • Estuary: managed PostgreSQL CDC with continuous materialization into DynamoDB
  • AWS DMS: AWS-native full-load and CDC migration into DynamoDB

PostgreSQL to DynamoDB: 2 Migration and Replication Methods

MethodMigration patternOngoing syncData-model handlingBest for
EstuaryInitial backfill followed by PostgreSQL CDCYesMaps captured collections into DynamoDB destination resourcesManaged ongoing replication
AWS DMSFull load, full load + CDC, or CDC onlyYesUses table and object mapping to control how source data is written to DynamoDBAWS-native migration workflows

The main decision is whether you want a managed continuous pipeline or an AWS-native migration task.

In both cases, plan the DynamoDB data model before migration. PostgreSQL tables do not always map cleanly to DynamoDB because DynamoDB design depends heavily on partition keys, sort keys, and application access patterns.

How PostgreSQL Data Maps to DynamoDB

PostgreSQL and DynamoDB use different data models, so migration is not always a simple table-to-table copy.

PostgreSQL stores data in normalized relational tables with primary keys, foreign keys, and joins. DynamoDB stores items in tables and is designed around partition keys, optional sort keys, and application access patterns.

Before migrating, decide how each PostgreSQL record should be represented in DynamoDB.

For example:

PostgreSQL

plaintext
customers - customer_id - name - email orders - order_id - customer_id - created_at - total

A DynamoDB design might use:

plaintext
PK = CUSTOMER#123 SK = PROFILE

for the customer, and:

plaintext
PK = CUSTOMER#123 SK = ORDER#456

for each related order.

This lets an application retrieve a customer and related orders by key without performing relational joins.

What to Decide Before Migration

Define these before moving data:

  • Partition key: how DynamoDB distributes and retrieves items
  • Sort key: how related items are grouped and queried within a partition
  • Item structure: whether PostgreSQL columns remain flat or are combined into nested DynamoDB attributes
  • Relationships: how PostgreSQL foreign-key relationships will be represented without joins
  • Access patterns: the queries your application needs DynamoDB to support

For simple tables, a PostgreSQL primary key may map directly to a DynamoDB partition key. For more relational schemas, you may need to denormalize or combine data before loading it into DynamoDB.

The key point is: design the DynamoDB access pattern first, then map PostgreSQL data into that model.

Method 1: Replicate PostgreSQL Data to DynamoDB with Estuary

Estuary can capture PostgreSQL table changes using change data capture (CDC) and continuously materialize the resulting collections into Amazon DynamoDB.

The pipeline looks like this:

PostgreSQL → WAL → Estuary capture → Estuary collections → DynamoDB

Estuary’s PostgreSQL source connector uses logical replication to read changes from PostgreSQL’s write-ahead log (WAL). By default, it first backfills the current contents of selected tables and then transitions to ongoing change capture.

Step 1: Prepare PostgreSQL for CDC

The PostgreSQL source typically requires:

  • wal_level=logical
  • a user with replication permissions
  • a replication slot
  • a publication containing the tables to capture
  • network access between Estuary and PostgreSQL

Estuary can create some of these objects automatically when the database user has sufficient permissions.

Step 2: Create the PostgreSQL Capture

Postgres to DynamoDB -  postgres capture

In Estuary:

  1. Create a PostgreSQL capture.
  2. Enter the source database connection details.
  3. Discover the available schemas and tables.
  4. Select the tables you want to replicate.
  5. Publish the capture.

Unless backfilling is disabled, Estuary first captures the current table state and then continues processing PostgreSQL change events.

Step 3: Configure DynamoDB as the Destination

Use Estuary’s Amazon DynamoDB destination connector to materialize the captured collections into DynamoDB tables.

You need:

  • an AWS region
  • AWS credentials or an IAM role
  • DynamoDB permissions including BatchGetItem, BatchWriteItem, CreateTable, and DescribeTable
  • at least one Estuary collection

The connector creates DynamoDB tables from the selected collections. By default, Estuary collection keys are used as the DynamoDB partition key and, when a second collection key exists, the sort key.

Step 4: Check the DynamoDB Key and Item Structure

Before publishing, verify that the Estuary collection structure fits DynamoDB’s requirements.

The DynamoDB materialization connector supports collections with up to two collection keys. By default:

  • the first collection key becomes the DynamoDB partition key
  • the second collection key, if present, becomes the sort key
  • the root document is stored as a DynamoDB Map under flow_document, unless you configure different field projections

DynamoDB also has a 400 KB item-size limit. If a source collection has more than two keys, oversized documents, or incompatible field names, Estuary recommends deriving a new collection before materializing it.

Step 5: Publish the Materialization

Select the PostgreSQL-derived collections you want to send to DynamoDB, map each collection to a DynamoDB table, and publish the materialization.

Estuary materializations continuously push changes from bound collections into destination resources, so PostgreSQL changes captured into those collections continue flowing to DynamoDB.

When Is Estuary a Good Fit?

Use Estuary when:

  • PostgreSQL data needs to keep flowing into DynamoDB after the initial backfill
  • you want WAL-based PostgreSQL CDC without operating the capture infrastructure yourself
  • the source data can be mapped into a DynamoDB-compatible key structure
  • you need to reshape source records before materialization
  • you want a managed pipeline rather than an AWS DMS migration task

Things to Consider

  • DynamoDB data modeling should be planned before replication.
  • Estuary collections materialized to DynamoDB can have at most two collection keys.
  • DynamoDB items cannot exceed 400 KB.
  • Complex relational schemas may require an Estuary derivation or other transformation before they fit the intended DynamoDB access pattern.
  • This approach replicates data; it does not automatically redesign a normalized PostgreSQL schema into an optimized DynamoDB application model.

Postgres to DynamoDB

Method 2: Migrate PostgreSQL to DynamoDB with AWS DMS

Postgres to DynamoDB - DMS
Image Source

AWS Database Migration Service (AWS DMS) can migrate PostgreSQL data into Amazon DynamoDB using a full load, ongoing change data capture (CDC), or both.

The architecture is:

PostgreSQL → AWS DMS → DynamoDB

For PostgreSQL sources, AWS DMS can read ongoing changes through logical replication after the initial load. For DynamoDB targets, DMS uses table mapping and object mapping rules to control how relational source data is written as DynamoDB items.

See the AWS DMS PostgreSQL source documentation and DynamoDB target documentation for current requirements and limitations.

Step 1: Prepare PostgreSQL

For ongoing CDC, PostgreSQL must support logical replication.

Typical requirements include:

  • wal_level=logical
  • sufficient replication slots
  • sufficient WAL senders
  • a replication user with the required permissions
  • network access from AWS DMS to PostgreSQL

If you only need a full-load migration, CDC-specific settings may not be required.

Step 2: Configure PostgreSQL as the Source

Create a PostgreSQL source endpoint in AWS DMS and provide:

  • hostname
  • port
  • database name
  • username and password
  • network configuration

Test the endpoint before creating the migration task.

Step 3: Configure DynamoDB as the Target

Create a DynamoDB target endpoint and make sure the AWS DMS replication resources have permission to create or write to the required DynamoDB tables.

DynamoDB target configuration is different from a relational destination because you also need to define how source rows become DynamoDB items.

Step 4: Define Table and Object Mapping

AWS DMS uses table mapping to choose which PostgreSQL schemas and tables to migrate.

For DynamoDB, object mapping determines how source columns are represented in the target item and which source field becomes the DynamoDB partition key.

This is one of the most important parts of the migration.

For example, a PostgreSQL table such as:

plaintext
customers - customer_id - name - email

might be mapped so that:

plaintext
customer_id → DynamoDB partition key name → attribute email → attribute

For more complex relational schemas, you may need to redesign or denormalize the source data before or during migration.

Step 5: Choose the Migration Type

AWS DMS supports:

  • Full load: migrate existing PostgreSQL data once
  • Full load + CDC: migrate existing data and continue replicating changes
  • CDC only: replicate changes from a defined starting point

Use full load + CDC when DynamoDB needs to stay updated while PostgreSQL remains active.

Step 6: Run and Monitor the Migration

During the task, monitor:

  • full-load progress
  • CDC latency
  • task errors
  • rejected records
  • source WAL retention
  • DynamoDB throttling or write capacity issues

Also validate that the resulting DynamoDB keys and item structure match the access patterns your application actually needs.

When AWS DMS Is a Good Fit

Use AWS DMS when:

  • you want an AWS-native migration workflow
  • PostgreSQL and DynamoDB are already part of your AWS architecture
  • you need a full load with optional ongoing CDC
  • you are comfortable configuring table and object mappings
  • your DynamoDB key design is already understood

Things to Consider

  • AWS DMS does not automatically design the ideal DynamoDB schema for your application.
  • Relational joins and foreign-key relationships do not directly translate into DynamoDB.
  • Partition-key design should be decided before migration.
  • Complex relational models may require preprocessing or denormalization.
  • DynamoDB item-size and throughput limits still apply.
  • Application behavior should be validated against the migrated DynamoDB model, not just row counts.

How Are PostgreSQL Inserts, Updates, and Deletes Handled in DynamoDB?

Both Estuary and AWS DMS can keep DynamoDB updated after the initial load, but the result depends on how PostgreSQL rows are mapped to DynamoDB keys.

ChangeEstuaryAWS DMS
InsertCaptured from PostgreSQL WAL and materialized as a DynamoDB itemApplied during full load or CDC
UpdateCaptured as a change event and applied to the matching DynamoDB itemApplied during CDC when the source row maps to a stable DynamoDB key
DeleteCaptured from PostgreSQL and propagated through the materializationCan be propagated during CDC when the source row can be identified reliably
Existing rowsBackfilled before ongoing CDCLoaded with full-load or full-load + CDC

The key requirement is stable identity. A PostgreSQL row must map consistently to the same DynamoDB partition key, and sort key if one is used. Otherwise, later updates or deletes may not target the intended item.

For complex relational schemas, this is another reason to design the DynamoDB key structure before starting replication.

Which PostgreSQL to DynamoDB Method Should You Use?

Choose the method based on whether you want a managed ongoing pipeline or an AWS-native migration workflow.

MethodBest forOngoing syncMain consideration
EstuaryManaged PostgreSQL CDC into DynamoDBYesBest when you want initial backfill plus ongoing replication without operating the capture infrastructure
AWS DMSAWS-native migration and replicationYesBest when you want to stay within AWS and are comfortable configuring table/object mappings and replication tasks

Use Estuary when PostgreSQL data needs to keep flowing into DynamoDB after the initial backfill, and you want a managed CDC pipeline.

Use AWS DMS when you prefer AWS-native migration tooling and already have a DynamoDB key and object-mapping strategy in place.

In either case, the migration should start with the DynamoDB data model. The hardest part is usually not moving the rows—it is deciding how PostgreSQL records should map to DynamoDB partition keys, sort keys, and item structures.


Need to keep PostgreSQL data continuously synchronized with DynamoDB?

Start building with Estuary or review the PostgreSQL source connector and Amazon DynamoDB destination connector documentation.

Start streaming your data for free

Build a Pipeline

About the author

Picture of Jeffrey Richman
Jeffrey RichmanData Engineering & Growth Specialist

Jeffrey is a data engineering professional with over 15 years of experience, helping early-stage data companies scale by combining technical expertise with growth-focused strategies. His writing shares practical insights on data systems and efficient scaling.

Streaming Pipelines.
Simple to Deploy.
Simply Priced.
$0.50/GB of data moved + $.14/connector/hour;
50% less than competing ETL/ELT solutions;
<100ms latency on streaming sinks/sources.