Title: Migration runner: chunked autocommit phases still run inside the mega-transaction · Issue #8411 · formbricks/formbricks · GitHub
Open Graph Title: Migration runner: chunked autocommit phases still run inside the mega-transaction · Issue #8411 · formbricks/formbricks
X Title: Migration runner: chunked autocommit phases still run inside the mega-transaction · Issue #8411 · formbricks/formbricks
Description: Summary packages/database/migration/20260625104904_canonicalize_language_codes/migration.ts's run() executes inside the migration runner's prisma.$transaction(..., { timeout: 30min }) callback. Steps 3 and 4 of the migration use the pris...
Open Graph Description: Summary packages/database/migration/20260625104904_canonicalize_language_codes/migration.ts's run() executes inside the migration runner's prisma.$transaction(..., { timeout: 30min }) callback. Ste...
X Description: Summary packages/database/migration/20260625104904_canonicalize_language_codes/migration.ts's run() executes inside the migration runner's prisma.$transaction(..., { timeout: 30min }) callb...
Opengraph URL: https://github.com/formbricks/formbricks/issues/8411
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Migration runner: chunked autocommit phases still run inside the mega-transaction","articleBody":"## Summary\n\n`packages/database/migration/20260625104904_canonicalize_language_codes/migration.ts`'s `run()` executes inside the migration runner's `prisma.$transaction(..., { timeout: 30min })` callback. Steps 3 and 4 of the migration use the `prisma` autocommit handle to commit chunked updates for `Response` and `ContactAttribute` (the two highest-volume tables), but this chunked work still runs *inside* the runner's outer transaction. As a result:\n\n- The chunked phases (steps 3–4) still consume the same 30-minute transaction budget as steps 1–2.\n- Locks acquired by steps 1–2 (on `Language`, `SurveyLanguage`, and `Survey` content rows) are held until `run()` returns, i.e. until steps 3–4 also finish.\n\n## Discussion / accepted trade-offs\n\nPer discussion on PR #8407 (review thread on `migration.ts` lines 29-32):\n\n- Response ingestion is not stalled by this: there's no `responseCount` column/trigger on `Survey`, and an insert's `KEY SHARE` lock on the `Survey` FK row is compatible with the content updates' `FOR NO KEY UPDATE` locks. What is blocked is survey *editing* during the migration — already true before this PR.\n- The timeout failure mode converges: committed chunks from steps 3–4 survive a transaction rollback/timeout, and retries re-walk mostly read-only ranges, so each retry attempt is progressively faster. Worst case is a crash-looping deploy that converges after a few attempts, not a stuck migration.\n\nGiven these mitigations, the PR author chose not to gate PR #8407 on this issue, but agreed it should be tracked as a follow-up.\n\n## Required changes\n\nEither:\n1. Add an opt-out in the migration runner (`packages/database/src/scripts/migration-runner.ts`) allowing a migration to declare that it should run partially or fully outside the mega-transaction, or\n2. Split this migration into two: a bounded-transaction migration for steps 1–2 (catalog + survey content), and a separate autocommit/chunked migration for steps 3–4 (`Response` + `ContactAttribute`).\n\n## Acceptance criteria\n\n- Chunked, high-volume update phases (Response/ContactAttribute canonicalization, and any future similar work) do not run inside the runner's long-lived transaction.\n- Locks from earlier bounded-transaction steps are released before chunked autocommit work begins.\n- Existing idempotency/retry behavior of the migration is preserved.\n\n## References\n\n- PR: https://github.com/formbricks/formbricks/pull/8407\n- Discussion: https://github.com/formbricks/formbricks/pull/8407#discussion_r3511286832\n\nRequested by: @xernobyl","author":{"url":"https://github.com/coderabbitai[bot]","@type":"Person","name":"coderabbitai[bot]"},"datePublished":"2026-07-02T09:27:29.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":0},"url":"https://github.com/8411/formbricks/issues/8411"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:dfacdff5-d74e-11c0-4dfa-35f734ce66c5 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | 8F24:73975:4211A5:5D4290:6A4BC8AD |
| html-safe-nonce | 4cd4061b71297a976cfb85196416b7bb79832923f0c79d616feee3c1b41ef650 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI4RjI0OjczOTc1OjQyMTFBNTo1RDQyOTA6NkE0QkM4QUQiLCJ2aXNpdG9yX2lkIjoiMzY1ODgyMjk1NzI1MDUwMDMwIiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0= |
| visitor-hmac | 45ea34b96c9eda97ec012946e59b12feded0d5a70d4244dab50b1a1934541c41 |
| hovercard-subject-tag | issue:4793088821 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/formbricks/formbricks/8411/issue_layout |
| twitter:image | https://opengraph.githubassets.com/237fb89a523689ad20745b59ecc33b83d93990d8cf7696abab9c5dc53e2c4336/formbricks/formbricks/issues/8411 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/237fb89a523689ad20745b59ecc33b83d93990d8cf7696abab9c5dc53e2c4336/formbricks/formbricks/issues/8411 |
| og:image:alt | Summary packages/database/migration/20260625104904_canonicalize_language_codes/migration.ts's run() executes inside the migration runner's prisma.$transaction(..., { timeout: 30min }) callback. Ste... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | coderabbitai[bot] |
| hostname | github.com |
| expected-hostname | github.com |
| None | 14aa00ce5bdb34d0eefb5facbffd7de9e144c688d8a93ef8df902d5f94b51dd7 |
| turbo-cache-control | no-preview |
| go-import | github.com/formbricks/formbricks git https://github.com/formbricks/formbricks.git |
| octolytics-dimension-user_id | 105877416 |
| octolytics-dimension-user_login | formbricks |
| octolytics-dimension-repository_id | 500289888 |
| octolytics-dimension-repository_nwo | formbricks/formbricks |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 500289888 |
| octolytics-dimension-repository_network_root_nwo | formbricks/formbricks |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 58b8f89190447502561829f30862aa0a99d53367 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width