DynamoDB to MySQL: How to Move Your Data
Move DynamoDB into MySQL with Airbyte. Why schema inference matters more without a raw layer, cursor field rules, and modelling nested attributes in views.

Moving DynamoDB into MySQL is usually about giving an application or an internal tool a queryable copy of data it can otherwise only fetch by key. Reporting features, admin panels and anything needing a join are far easier against a relational database than against a key-value store.
This guide covers the managed path with Airbyte. DynamoDB has no schema and MySQL insists on one, so the discovery phase invents it by sampling your table, and how much you trust that inference is the main thing this article is about.
DynamoDB to MySQL at a glance:
Why move data from DynamoDB to MySQL?
Two situations account for most of these pipelines.
The first is joining application data to relational data you already hold. Your DynamoDB table knows about sessions or events and your MySQL database knows about accounts and billing, and answering anything spanning both needs them in one place that can join.
The second is powering an internal tool with SQL rather than scans. If you want large-scale analytics instead, a warehouse or lakehouse is the better destination, because DynamoDB tables are usually chosen precisely when data outgrows what a relational database wants to hold.
What do you need before you start?
Two credentials decisions, and two that decide whether the result is trustworthy:
AWS credentials, or better, an IAM role. Supply an access key and secret, or omit both and the connector falls back to the default credentials provider, picking up the role attached to the workload running it. On self-managed Airbyte the second option avoids long-lived keys in configuration.
A cursor attribute that satisfies the rules. Incremental sync needs a top-level attribute, not one nested inside a map, of string or integer type, in ISO 8601 or epoch format, and never blank on any item. Single-table designs that bury timestamps inside nested attributes cannot use them without restructuring.
A realistic view of volume. Airbyte recommends relational destinations for roughly 10GB or less. That is worth checking honestly here, because the reason a table lives in DynamoDB is often that it grew past what a single MySQL instance handles comfortably.
A MySQL user with write access. On the target schema, ideally one dedicated to synced data so the pipeline cannot collide with application tables. Watch identifier lengths too, since MySQL allows 64 characters and flattened attribute names can run long.
If your organisation restricts inbound traffic by IP, add the Airbyte Cloud IP addresses to the allow list on the MySQL side before you begin.
How do you build a DynamoDB to MySQL pipeline in Airbyte?
Step 1: Establish what the items actually contain
Sit down with whoever owns the table and list the attributes, including optional ones and any that changed type over the years. This is the only way to check the discovered schema against reality, and on a relational destination it also tells you which columns will need a considered type rather than whatever was inferred.
Step 2: Configure the DynamoDB source
Click Sources in the left navigation, then New Source, and select DynamoDB, following adding a source. Supply the region and either your access keys or nothing at all if you are using a role. Then review the discovered schema against your list from step 1, and refresh it after any deploy that adds attributes.
Step 3: Configure the MySQL destination
Click Destinations, then New Destination, and select MySQL, following adding a destination. Supply the host, port, database and credentials. Airbyte adds its own metadata columns, so plan to expose views to any consuming application rather than the raw tables.
Step 4: Create the connection and plan for deletes
Click Connections, then New connection, select your tables and a sync mode. The source is cursor-based rather than reading DynamoDB Streams, so deletions never reach MySQL and updates are only seen when they advance the cursor attribute.
Where deletions genuinely occur and you cannot add a soft-delete flag, a periodic full refresh is the remedy. On DynamoDB that is a full scan consuming read capacity, so schedule it deliberately rather than nightly out of habit.
How does the schema get invented?
The connector scans your table with a limit of 1,000 items. If the returned data exceeds 1MB it scans again with the same limit, repeating until it has at least 1,000 items. It then combines every top-level attribute it saw and infers each attribute's type from its value.
Two consequences follow. An attribute appearing only on items outside that sample will not be in the catalogue, and the connector assumes an attribute has the same type everywhere, which DynamoDB does not enforce. Both are inherent to inferring a schema from a store that does not have one.
The reason this matters more on MySQL than on a lakehouse is that there is no raw layer to fall back on. Where a lakehouse keeps the original record alongside the typed columns, letting you recover a missed field later, a relational table holds what the schema said and nothing else. Getting the inference checked before the first sync is therefore worth more here.
What do you do about nested attributes?
DynamoDB items routinely nest maps and lists inside attributes, and Airbyte preserves that structure rather than guessing at a flattening. MySQL has a JSON type and none of the ergonomics a warehouse offers for working with it at scale.
So the modelling layer is closer to a requirement than a nicety. Build views extracting the specific fields your application or your reports read, and point them at those rather than at the raw tables, which also hides Airbyte's metadata columns and gives you a stable interface.
Anchor those views on DynamoDB's own keys. The partition key groups related items and the sort key orders within a partition, and together they are the natural unique identifier. Partition keys are usually meaningful too, since applications choose them to group items read together, which makes them worth promoting to a proper column.
Frequently asked questions
Does Airbyte use DynamoDB Streams for change data capture?
No. The source is cursor-based. Deletions are not captured and updates are only seen if they advance the cursor attribute.
Why is an attribute missing from my table?
Discovery did not see it in the sampled items. Refresh the source schema, and note that unlike a lakehouse there is no raw record to recover it from afterwards.
Is MySQL big enough for DynamoDB data?
For a focused table, comfortably. Airbyte recommends relational destinations for roughly 10GB or less, and DynamoDB tables often exist precisely because the data outgrew that.
Can I use a nested field as the cursor?
No. Cursor fields must be top level, string or integer, in ISO 8601 or epoch format, and never blank.
Can I do this without writing code?
The Airbyte setup is entirely UI-driven. You will want SQL views extracting nested attributes, which on this destination is closer to a requirement than a nicety.
Get your DynamoDB data into MySQL
Check the inferred schema carefully before the first sync, because a relational destination keeps no raw record to recover a missed attribute from. Check your volume against the guidance, pick a cursor that satisfies the rules, decide what a deletion should mean, and expose views rather than raw tables.
Airbyte's connector catalog includes 600+ pre-built connectors, so application data can reach a database and an analytical store at once. For the analytical version, see DynamoDB to Databricks, and for another relational destination, DynamoDB to PostgreSQL.
Integrate with 700+ apps using Airbyte
Move data from 700+ sources into warehouses, lakes, and beyond. Set up pipelines in minutes with pre-built connectors and the Connector Builder.
