Title: Migration runner: chunked autocommit phases still run inside the mega-transaction · Issue #8410 · formbricks/formbricks · GitHub
Open Graph Title: Migration runner: chunked autocommit phases still run inside the mega-transaction · Issue #8410 · formbricks/formbricks
X Title: Migration runner: chunked autocommit phases still run inside the mega-transaction · Issue #8410 · 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/8410
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:17.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":0},"url":"https://github.com/8410/formbricks/issues/8410"}
| 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:446eab37-137c-2e17-a3a7-8849eb7542ea |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | B3C0:1F1E93:152F21E:1ED3AED:6A4BB35D |
| html-safe-nonce | 41abe2e23c710a298ed781e156c8c70f9609164a35a75b4c9bcccad6eb71b4c3 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJCM0MwOjFGMUU5MzoxNTJGMjFFOjFFRDNBRUQ6NkE0QkIzNUQiLCJ2aXNpdG9yX2lkIjoiNTkzMDAwMTUxNDE4MTE0NTQzNyIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | e6c398048142054a6643a98bc2f5154ea88bc0c26f1d70591c1801d563b00f25 |
| hovercard-subject-tag | issue:4793087499 |
| 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/8410/issue_layout |
| twitter:image | https://opengraph.githubassets.com/9261312ae3bc42a7ff211bf3cae14d14427c42382c0b43e80b61cafc8980c6ef/formbricks/formbricks/issues/8410 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/9261312ae3bc42a7ff211bf3cae14d14427c42382c0b43e80b61cafc8980c6ef/formbricks/formbricks/issues/8410 |
| 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 | ae1c14875555a1dd92bdef45baa6dd9aa796df891e4e471989f7117fe3139fc1 |
| 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 | 68fba4ebcf15cde644b66de9a06e0a8582279435 |
| ui-target | canary-2 |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width