Skip to content

migration · 6 min read ·

What actually breaks in a Bubble migration

Nothing here is a reason not to migrate. Every one of them is a reason not to migrate blind, which is a different claim and a more useful one.

Lucian LutasFACTIONER SRL

Nothing on this list is a reason not to migrate. Every one of them is a reason not to migrate blind, which is a different claim and a much more useful one.

These are the six things that reliably turn out to be harder than the plan said. The migration page lists them in a sentence each. This is the version with the mechanics, because knowing that hidden workflow logic is a risk does not help you. Knowing how to go and find yours does.

1. Logic nobody documented

The failure looks like this: three weeks after cutover, a customer says the thing that used to happen when they cancel is not happening any more. Nobody knew that thing existed. It was in a nested conditional inside a workflow written two years ago by a contractor.

This is the single most common source of post-migration bugs and it is not a coding problem. It is an archaeology problem. The workflows are readable, so the information is all there, but it is spread across an editor that shows you one branch at a time and gives you nothing that resembles a search across behaviour.

Finding yours: go through every workflow and write down, in a sentence, what it does and when it runs. Every conditional branch is its own sentence. The output is boring and long and it is the single most valuable document in the project, because it converts the migration from an interpretation exercise into a checklist. This is audit work, not migration work, and it is why we charge for the audit separately: it is a week of reading before anyone writes any code.

2. Scheduled workflows

The worst thing about scheduled and recurring workflows is that they are invisible until you go looking. Nothing on any screen tells you they exist. They are just running, quietly, and they have been for years.

Miss one and nothing breaks on cutover day. The email silently stops sending, and you find out three weeks later when somebody asks why they have not had their monthly summary.

Finding yours: the Logs tab is the honest source, because it shows what actually ran rather than what someone remembers setting up. Look at a window long enough to catch the monthly ones, which means at least a full month, and be aware that your plan's log retention decides whether that is even possible. On the Starter plan you get two days of logs, and on Growth fourteen. Neither of those is a month. If you are on a plan with short retention and you need to find your recurring jobs, that is a real argument for spending one month on a higher tier before the migration starts rather than after.

Dead scheduled workflows are worth finding for a second reason. They consume Workload Units on every run, forever, whether or not anything downstream cares about the result. Some climbing bills are not growth at all.

3. Privacy rules

Rules accumulate. Some are load-bearing, some fixed a bug that no longer exists, and the person who could tell them apart has left. Every one has to be read, understood and reproduced as a Postgres policy, and understood is the expensive word.

The specific trap is field-level rules: a rule that hides one field rather than the whole record. Those are invisible in the running app, so nobody remembers they exist, and reproducing them wrongly hands a salary column to the wrong role on cutover day.

Finding yours: there is a full procedure in what Bubble's privacy rules become in real code, including the audit you can run yourself in an afternoon whether or not you migrate.

4. Plugins with no equivalent

Most plugins are wrappers around an API you can call directly. A minority are custom components doing real work with no vendor behind them, and there is no honest way to price rebuilding one without opening the app.

Finding yours: sort them into wrappers, UI components, and the awkward ones, then ask of each awkward one what the smallest thing that would satisfy your users is. The answer is usually a lot less than the plugin does. Full method in Bubble plugins that have no code equivalent.

5. Files

Uploads are not in your database export. They are URLs pointing at Bubble's storage, and an app whose database migrated cleanly without its files works perfectly until someone opens an attachment.

The risk is not difficulty, it is volume and permissions. Volume because moving everything takes as long as it takes. Permissions because the default when you bulk-move files is public, and a private document that becomes a readable one is a different category of problem from a broken link.

Finding yours: count them and total their size before you plan the timeline, and keep the old URLs in a column until you have opened some of the new ones by hand. Procedure in how to get your data out of Bubble.

6. Running both systems at once

For part of the project your data lives in two places. This is the direct cost of never taking the app offline, and it is worth being explicit that it is a cost rather than pretending incremental migration is free.

What it means in practice: writes have to go somewhere definitive, and reads have to know where to look. The workable version is that each data type has exactly one owner at any moment, and moving ownership is a deliberate step with a date on it. The version that goes wrong is two systems both accepting writes to the same records, which produces conflicts that are genuinely hard to untangle after the fact.

Planning for it: decide the order data types move, write it down, and make each move a single event rather than a gradual drift. The synchronisation work is real and it should be a line in the quote rather than a surprise.

The honest summary

Five of these six are discoverable before anyone commits to anything, using your own app and your own afternoon. That is the actual argument for a paid audit: not that migration is dangerous, but that the variance in what it costs comes almost entirely from things you can go and look at first.

An audit that finds your app is straightforward should reduce your quote. If whoever is quoting you does not want to look before giving you a number, ask why.

The audit does all six properly, on your app, in a week. Or run the cost calculator first and find out whether any of this is worth your time yet.

Run the same numbers on your own app.

The calculator uses the same published pricing config this post does, and it will tell you to stay on Bubble if that is what your numbers say.