{"id":1439,"date":"2026-10-20T18:00:00","date_gmt":"2026-10-20T17:00:00","guid":{"rendered":"https:\/\/wade.one\/blog\/?p=1439"},"modified":"2026-10-20T18:00:00","modified_gmt":"2026-10-20T17:00:00","slug":"database-migrations-need-to-survive-two-app-versions-at-once","status":"publish","type":"post","link":"https:\/\/wade.one\/blog\/2026\/10\/20\/database-migrations-need-to-survive-two-app-versions-at-once\/","title":{"rendered":"Database Migrations Need to Survive Two App Versions at Once"},"content":{"rendered":"<p>A database migration can work perfectly on your development machine and still make a production deployment awkward. During a rolling release, some application instances may be running the old code while others use the new code. If the schema change immediately removes something the old version expects, the deployment order becomes a trap.<\/p>\n<p>The <a href=\"https:\/\/www.prisma.io\/docs\/guides\/database\/data-migration\">expand-and-contract approach<\/a> separates adding the new structure from removing the old one. Introduce a compatible shape, move the application and data across, then remove the obsolete structure when it is genuinely unused. It creates more than one step, but each step has a clearer relationship with the code currently running.<\/p>\n<p>I would pay particular attention to data written during the transition. A backfill of yesterday&#8217;s rows does not automatically handle today&#8217;s new writes, and a rollback may be useless if the older application cannot understand the updated records. Decide how those cases work before treating a successful migration command as proof that the release is safe.<\/p>\n<p>Small deployments are easier to manage when the database lets the application move gradually. The aim is a change you can explain and recover from, with checks at each boundary. Saving one migration file is not worth making every instance switch versions at exactly the same moment.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A database migration can work perfectly on your development machine and still make a production deployment awkward.<\/p>\n","protected":false},"author":0,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[13],"tags":[269,61,270],"class_list":["post-1439","post","type-post","status-publish","format-standard","hentry","category-programming","tag-database-migrations","tag-deployments","tag-prisma"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Database Migrations Need to Survive Two App Versions at Once - wade.one<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/wade.one\/blog\/2026\/10\/20\/database-migrations-need-to-survive-two-app-versions-at-once\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Database Migrations Need to Survive Two App Versions at Once - wade.one\" \/>\n<meta property=\"og:description\" content=\"A database migration can work perfectly on your development machine and still make a production deployment awkward.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/wade.one\/blog\/2026\/10\/20\/database-migrations-need-to-survive-two-app-versions-at-once\/\" \/>\n<meta property=\"og:site_name\" content=\"wade.one\" \/>\n<meta property=\"article:published_time\" content=\"2026-10-20T17:00:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/Wade-Logo-cropped.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1518\" \/>\n\t<meta property=\"og:image:height\" content=\"1506\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@wadewomersley\" \/>\n<meta name=\"twitter:site\" content=\"@wadewomersley\" \/>\n<meta name=\"twitter:label1\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/10\\\/20\\\/database-migrations-need-to-survive-two-app-versions-at-once\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/10\\\/20\\\/database-migrations-need-to-survive-two-app-versions-at-once\\\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"Database Migrations Need to Survive Two App Versions at Once\",\"datePublished\":\"2026-10-20T17:00:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/10\\\/20\\\/database-migrations-need-to-survive-two-app-versions-at-once\\\/\"},\"wordCount\":219,\"publisher\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/#\\\/schema\\\/person\\\/8b4739f8f8bb2cff5d792d4b8779fcc3\"},\"keywords\":[\"database-migrations\",\"deployments\",\"prisma\"],\"articleSection\":[\"Programming\"],\"inLanguage\":\"en-GB\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/10\\\/20\\\/database-migrations-need-to-survive-two-app-versions-at-once\\\/\",\"url\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/10\\\/20\\\/database-migrations-need-to-survive-two-app-versions-at-once\\\/\",\"name\":\"Database Migrations Need to Survive Two App Versions at Once - wade.one\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/#website\"},\"datePublished\":\"2026-10-20T17:00:00+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/10\\\/20\\\/database-migrations-need-to-survive-two-app-versions-at-once\\\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/10\\\/20\\\/database-migrations-need-to-survive-two-app-versions-at-once\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/10\\\/20\\\/database-migrations-need-to-survive-two-app-versions-at-once\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/wade.one\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Database Migrations Need to Survive Two App Versions at Once\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/wade.one\\\/blog\\\/\",\"name\":\"wade.one\",\"description\":\"wade womersley - york based software engineer\",\"publisher\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/#\\\/schema\\\/person\\\/8b4739f8f8bb2cff5d792d4b8779fcc3\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/wade.one\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/#\\\/schema\\\/person\\\/8b4739f8f8bb2cff5d792d4b8779fcc3\",\"name\":\"Wade Womersley\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/02\\\/200px.png\",\"url\":\"https:\\\/\\\/wade.one\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/02\\\/200px.png\",\"contentUrl\":\"https:\\\/\\\/wade.one\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/02\\\/200px.png\",\"width\":202,\"height\":200,\"caption\":\"Wade Womersley\"},\"logo\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/02\\\/200px.png\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Database Migrations Need to Survive Two App Versions at Once - wade.one","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/wade.one\/blog\/2026\/10\/20\/database-migrations-need-to-survive-two-app-versions-at-once\/","og_locale":"en_GB","og_type":"article","og_title":"Database Migrations Need to Survive Two App Versions at Once - wade.one","og_description":"A database migration can work perfectly on your development machine and still make a production deployment awkward.","og_url":"https:\/\/wade.one\/blog\/2026\/10\/20\/database-migrations-need-to-survive-two-app-versions-at-once\/","og_site_name":"wade.one","article_published_time":"2026-10-20T17:00:00+00:00","og_image":[{"width":1518,"height":1506,"url":"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/Wade-Logo-cropped.png","type":"image\/png"}],"twitter_card":"summary_large_image","twitter_creator":"@wadewomersley","twitter_site":"@wadewomersley","twitter_misc":{"Estimated reading time":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/wade.one\/blog\/2026\/10\/20\/database-migrations-need-to-survive-two-app-versions-at-once\/#article","isPartOf":{"@id":"https:\/\/wade.one\/blog\/2026\/10\/20\/database-migrations-need-to-survive-two-app-versions-at-once\/"},"author":{"name":"","@id":""},"headline":"Database Migrations Need to Survive Two App Versions at Once","datePublished":"2026-10-20T17:00:00+00:00","mainEntityOfPage":{"@id":"https:\/\/wade.one\/blog\/2026\/10\/20\/database-migrations-need-to-survive-two-app-versions-at-once\/"},"wordCount":219,"publisher":{"@id":"https:\/\/wade.one\/blog\/#\/schema\/person\/8b4739f8f8bb2cff5d792d4b8779fcc3"},"keywords":["database-migrations","deployments","prisma"],"articleSection":["Programming"],"inLanguage":"en-GB"},{"@type":"WebPage","@id":"https:\/\/wade.one\/blog\/2026\/10\/20\/database-migrations-need-to-survive-two-app-versions-at-once\/","url":"https:\/\/wade.one\/blog\/2026\/10\/20\/database-migrations-need-to-survive-two-app-versions-at-once\/","name":"Database Migrations Need to Survive Two App Versions at Once - wade.one","isPartOf":{"@id":"https:\/\/wade.one\/blog\/#website"},"datePublished":"2026-10-20T17:00:00+00:00","breadcrumb":{"@id":"https:\/\/wade.one\/blog\/2026\/10\/20\/database-migrations-need-to-survive-two-app-versions-at-once\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/wade.one\/blog\/2026\/10\/20\/database-migrations-need-to-survive-two-app-versions-at-once\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/wade.one\/blog\/2026\/10\/20\/database-migrations-need-to-survive-two-app-versions-at-once\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/wade.one\/blog\/"},{"@type":"ListItem","position":2,"name":"Database Migrations Need to Survive Two App Versions at Once"}]},{"@type":"WebSite","@id":"https:\/\/wade.one\/blog\/#website","url":"https:\/\/wade.one\/blog\/","name":"wade.one","description":"wade womersley - york based software engineer","publisher":{"@id":"https:\/\/wade.one\/blog\/#\/schema\/person\/8b4739f8f8bb2cff5d792d4b8779fcc3"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/wade.one\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"},{"@type":["Person","Organization"],"@id":"https:\/\/wade.one\/blog\/#\/schema\/person\/8b4739f8f8bb2cff5d792d4b8779fcc3","name":"Wade Womersley","image":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/200px.png","url":"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/200px.png","contentUrl":"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/200px.png","width":202,"height":200,"caption":"Wade Womersley"},"logo":{"@id":"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/200px.png"}}]}},"jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":1401,"url":"https:\/\/wade.one\/blog\/2026\/08\/22\/dotnets-mcp-c-sharp-sdk-2-0-makes-web-deployment-less-weird\/","url_meta":{"origin":1439,"position":0},"title":".NET&#8217;s MCP C# SDK 2.0 Makes Web Deployment Less Weird","author":"","date":"August 22, 2026","format":false,"excerpt":"The official MCP C# SDK 2.0 adopts stateless HTTP while keeping older clients and servers working during migration.","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/wade.one\/blog\/category\/programming\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1394,"url":"https:\/\/wade.one\/blog\/2026\/08\/15\/mcp-going-stateless-is-the-boring-fix-it-needed\/","url_meta":{"origin":1439,"position":1},"title":"MCP Going Stateless Is the Boring Fix It Needed","author":"","date":"August 15, 2026","format":false,"excerpt":"MCP's stateless core removes deployment plumbing that should never have been the interesting part of an agent tool.","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/wade.one\/blog\/category\/programming\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1431,"url":"https:\/\/wade.one\/blog\/2026\/10\/12\/postgresql-14-support-ends-in-november-plan-the-upgrade-now\/","url_meta":{"origin":1439,"position":2},"title":"PostgreSQL 14 Support Ends in November: Plan the Upgrade Now","author":"","date":"October 12, 2026","format":false,"excerpt":"PostgreSQL 14 reaches the end of community support on 12 November 2026.","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/wade.one\/blog\/category\/programming\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1375,"url":"https:\/\/wade.one\/blog\/2026\/07\/14\/github-models-is-shutting-down-on-july-30\/","url_meta":{"origin":1439,"position":3},"title":"GitHub Models Is Shutting Down on July 30","author":"","date":"July 14, 2026","format":false,"excerpt":"GitHub Models closes on July 30, with brownouts first, so this is a migration deadline rather than a product update to read later.","rel":"","context":"In &quot;Software Engineer&quot;","block_context":{"text":"Software Engineer","link":"https:\/\/wade.one\/blog\/category\/software-engineer\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1158,"url":"https:\/\/wade.one\/blog\/2026\/03\/26\/why-senior-engineers-still-matter-more-in-the-ai-era\/","url_meta":{"origin":1439,"position":4},"title":"Why Senior Engineers Still Matter More in the AI Era","author":"","date":"March 26, 2026","format":false,"excerpt":"AI can generate code faster, but that only makes direction, judgment, and accountability more important. Senior engineers still matter because the expensive mistakes are rarely typing mistakes.","rel":"","context":"In &quot;AI&quot;","block_context":{"text":"AI","link":"https:\/\/wade.one\/blog\/category\/ai\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1162,"url":"https:\/\/wade.one\/blog\/2026\/03\/28\/when-i-recommend-a-rewrite-and-when-i-absolutely-don-t\/","url_meta":{"origin":1439,"position":5},"title":"When I Recommend a Rewrite, and When I Absolutely Don&#8217;t","author":"Wade","date":"March 28, 2026","format":false,"excerpt":"I am usually against full rewrites, but not always. The real question is whether the current system is beyond safe improvement or whether the team is just frustrated with it.","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/wade.one\/blog\/category\/programming\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/posts\/1439","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/comments?post=1439"}],"version-history":[{"count":1,"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/posts\/1439\/revisions"}],"predecessor-version":[{"id":1462,"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/posts\/1439\/revisions\/1462"}],"wp:attachment":[{"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/media?parent=1439"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/categories?post=1439"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/tags?post=1439"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}