"Can you move our Odoo to a new server without losing anything?" is one of the most common - and most reasonable - fears a founder has. An Odoo migration to a new server touches everything at once: the database, the filestore, the custom modules, the configuration. And the worst failure mode is silent: a handful of rows that quietly didn't make it, discovered weeks later when a report doesn't reconcile. This is how you make that move boring instead of terrifying.
Why migrations scare people, rightly
A migration is scary because it's all-or-nothing in perception but partial in reality. The naive approach - export a backup, restore it on the new box, point DNS, hope - works most of the time, which is exactly what makes it dangerous. When it doesn't work, you often can't tell immediately. A filestore that didn't copy fully means attachments 404 later. A sequence that reset means invoice numbers collide. A custom module that wasn't carried over means a menu is simply gone. The stakes are high and the feedback is delayed, which is the worst combination for confidence.
Inspect before you move
The first step in a safe Odoo migration to a new server is not a transfer - it's an inspection. Before anything moves, you measure exactly what's on the source: how many databases, which Odoo version, which PostgreSQL version, the size and shape of the filestore, and every custom or third-party module in the addons path. You can't validate a move you never measured, and most migration disasters trace back to a surprise that inspection would have caught - an undocumented module, a version mismatch, a filestore living somewhere non-standard.
Inspection also tells you whether this is a plain move or a move-plus-upgrade. If the target needs a newer Odoo version, that's a different job with its own rehearsal - see upgrades without the panic. Keeping the two concerns separate is part of what keeps a migration clean: move first, upgrade second, never both blind at once.
Transfer, then prove it
The transfer itself is server-to-server rather than a fragile export/import dance through a laptop. The database goes across with pg_dump and restore, the filestore is copied in full, and the addons and configuration come with it so the new box is a faithful replica, not an approximation.
But the transfer is not the end - proving it is. The step that turns a migration from an act of faith into an engineering task is completeness validation on the far side. Row counts have to match, table by table. If the source has a given number of records in a model, the target must have exactly the same number. Across a real Odoo, that's several hundred tables to reconcile - the last one we walked through was over 700. When every count matches, the move is provably complete, not just apparently complete.
Rollback as a default, not an afterthought
Even a careful migration can hit something unexpected, so the safe design assumes it might. If validation finds a discrepancy - a count that's off, a table that didn't reconcile - the move rolls back automatically and puts you exactly where you started. There is no half-migrated limbo where the old system is already torn down and the new one isn't trustworthy yet. The original stays live and untouched until the replica is proven, and the cutover is the very last thing that happens.
This is also why an agent-driven migration is preview-first. Before the transfer runs, the agent shows the plan: what it read during inspection, what it's about to move, and what the rollback path is. Nothing destructive happens on the source without a human confirming the plan first. The gate is what lets you automate something this consequential without holding your breath.
The boring result
Done this way, the outcome is anticlimactic in the best sense: 700+ tables moved, zero data loss, a cutover nobody noticed. That's the whole goal. A migration should not require heroics or a war room - it should be a measured, validated move with a safety net under every step. The excitement is a sign something went wrong, not a sign it went well. And because the original is never torn down until the replica is proven, the worst realistic case is that you spend an evening and end up exactly where you started - annoying, but not a disaster. That asymmetry, small downside against a clean move, is what lets you schedule a migration on a normal week instead of dreading it for a quarter.
FAQ
How do I migrate Odoo to a new server without losing data?
Inspect the source first so you know exactly what moves, do a server-to-server transfer of the database and filestore, then validate completeness by matching row counts table by table. Keep automatic rollback ready so any discrepancy returns you to the original untouched. That sequence is what makes an Odoo migration to a new server provably lossless.
How long does an Odoo migration take?
A straight move with no version change is usually measured in hours, dominated by how large the filestore and database are to copy. The validation adds time but not risk. Where migrations balloon into weeks is when they're combined with a version upgrade or custom-module rework - which is why it's cleaner to treat those as separate jobs.
Is pg_dump enough to move Odoo?
pg_dump handles the database, but Odoo also has a filestore of attachments and documents that lives outside PostgreSQL, plus custom modules and configuration. A complete migration copies all of those, then verifies the result - the database alone is only part of the system.
