Notion to MySQL: How to Move Your Data

Move Notion into MySQL with Airbyte. Why pages must be shared with your integration, handling the 30-level block tree, and the Data Sources rename.

Summarize with AI:

Moving Notion into MySQL puts workspace content somewhere an application or an internal tool can query it. Notion is excellent at being written in and awkward to query programmatically, so teams building a search feature, a documentation dashboard or an internal directory over it end up wanting the data elsewhere.

This guide covers the managed path with Airbyte. The thing that determines whether the result is complete has nothing to do with configuration: an integration only sees pages that someone has explicitly shared with it, so your dataset is as complete as your colleagues' diligence.

Notion to MySQL at a glance:

CapabilitySupportedWhat it means for this pipeline
Page accessShared explicitlyPages not shared with the integration never appear
Blocks nesting30 levels deepA recursive tree landing in a flat relational table
Excluded blocksThree typesChild page, child database and AI blocks are not retrieved
Rate limit3 a secondPer integration, so a large workspace takes time
Databases streamRenamedData Sources replaced it as of connector version 4.0.0

Why move data from Notion to MySQL?

Two situations account for most of these pipelines, and neither is analytics.

The first is feeding an application. An internal tool, an onboarding portal or a public help centre needs content that people maintain in Notion, and a database it already queries is a far simpler dependency than Notion's API with its own rate limits and sharing model.

The second is documentation governance: which pages are stale, which spaces are abandoned, who is actually writing. If you want to build a search corpus over the prose instead, a vector store is the better destination and the chunking question is a different article.

What do you need before you start?

One of these is a task for other people rather than for you, and it is the one that decides completeness:

A Notion integration and its access token. Created from your Notion integrations page, with the read content capability enabled, and read user information as well if you want the users stream. The token is found on the integration's secrets tab. The Notion source documentation covers both this and the OAuth alternative.

Every page you want, shared with that integration. With access token authentication you must manually share each page, opening it in Notion, using the menu at the top right and adding your connection. Pages nobody shares simply do not appear, and nothing reports their absence.

A deliberate start date. Optional, and if you leave it blank Airbyte sets it to two years before the current date. That is a sensible default and it is still a default rather than a decision, so set it to what your application actually needs.

A MySQL user with write access. On the target schema, ideally one dedicated to synced data rather than one your application also writes to, so the pipeline cannot collide with application tables.

If you are upgrading an existing connection, note that the Databases stream was replaced by Data Sources in version 4.0.0, reflecting Notion's own renaming. The Notion migration guide covers what to change.

How do you build a Notion to MySQL pipeline in Airbyte?

Step 1: Agree how pages get shared

Decide who shares pages with the integration and how new ones get added, because that process rather than any setting determines what your application can see. Sharing a top-level page brings its children along, so agreeing a small number of parent pages to share is far more maintainable than asking everyone to remember individually.

Step 2: Configure the Notion source

Click Sources in the left navigation, then New Source, and select Notion, following adding a source. Paste the access token, or supply client identifier, client secret and access token if you made the integration public for OAuth. Set the start date, then run the connection test.

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 expose views to the consuming application rather than the raw tables, which also insulates it from future schema changes on the source.

Step 4: Select streams and schedule realistically

Click Connections, then New connection, and select streams with a sync mode each. Pages and data sources give you structure, blocks give you content, and comments and users fill in collaboration. Take blocks only if you need the content itself, because it is by far the largest stream.

Notion enforces roughly three requests per second per integration, so a large workspace takes a while regardless of scheduling. The connector handles this properly: when it receives a rate limit response it respects the retry header and retries automatically, and those requests do not count against its retry budget.

Why is your dataset only as complete as your sharing?

Because Notion's integration model is opt-in per page. An integration has no workspace-wide read by default, so a page nobody has connected is invisible to it. That is a different model from most connectors, where a token's permissions decide visibility and everything within them is available.

The failure this produces is quiet and misleading. Somebody searches your internal tool for a document they know exists, finds nothing, and concludes the tool is broken rather than that the page was never shared. From the pipeline's point of view everything succeeded.

Two things help. Share a small number of high-level pages rather than many individual ones, since children come along with their parent. And record what is in scope somewhere your users can see, so an absent document reads as out of scope rather than as a fault.

How do you handle the block tree in a relational table?

Carefully, because it is a tree and MySQL is not. The blocks stream retrieves content blocks for all synced pages, including recursively nested child blocks up to thirty levels deep, so a single page can produce a great many rows related to each other by parent.

Reassembling a page therefore means walking that hierarchy, which in modern MySQL is a recursive common table expression rather than something you can do with a simple join. Write that once as a view producing page content in order, and let your application read the view rather than making every consumer solve the tree.

Note also what is excluded: child page, child database and AI block types are not retrieved. So a page that mostly links to other pages will look surprisingly empty in the blocks stream, and its structure lives in the pages and data sources streams instead. That is worth knowing before someone reports missing content.

Frequently asked questions

Why are some Notion pages missing?

They have not been shared with your integration. With access token authentication each page must be connected manually, and sharing a parent brings its children along.

What happened to the Databases stream?

It was replaced by Data Sources as of connector version 4.0.0, following Notion's own renaming. A data source is a structured table containing pages and properties. See the migration guide if you are upgrading.

Which block types are not included?

Child page, child database and AI blocks are excluded. Page structure comes from the pages and data sources streams rather than from blocks.

Why is my sync slow?

Notion enforces roughly three requests per second per integration. The connector retries rate-limited requests automatically without consuming its retry budget, so a large workspace simply takes time.

Can I do this without writing code?

The Airbyte setup is entirely UI-driven. You will want a MySQL view using a recursive common table expression to reassemble page content from the block tree, which is where the work sits.

Get your Notion data into MySQL

Agree the sharing process before anything technical, because it decides completeness. Share a few parent pages rather than many individual ones, take the blocks stream only if you need content, write the recursive view once so consumers do not each solve the tree, and publish what is in scope so absent pages read as deliberate.

Airbyte's connector catalog includes 600+ pre-built connectors, so workspace content can reach an application and a warehouse at once. For the same source in a warehouse, see Notion to BigQuery, and for another wiki whose streams describe governance rather than prose, Confluence to Snowflake.

Start syncing now →

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.