Original 8452d01d26d7 migration loaded the entire chat table via fetchall() (~771 MB JSON in our dataset), used per-row savepoints, and created 3 composite indexes before backfilling. This pegged pods at 2.7 GB RSS and OOMKilled repeatedly on 4 GB nodes before the migration could commit.
Paginates SELECT (50 chats per page, ORDER BY id), bulk-inserts in flushes of 500 rows with ON CONFLICT DO NOTHING on PostgreSQL (OR IGNORE elsewhere), falls back to per-row savepoint inserts if a batch fails (preserves the original skip-bad-row behavior).
Moves all 7 indexes (4 single-column + 3 composite) to after the backfill loop — much cheaper than per-row index updates.
Schema, data, and indexes at the end of the migration are identical to the original.
Test plan
Apply to a non-prod DB with a large chat table and confirm migration completes without OOM
Verify alembic_version advances to 8452d01d26d7
Verify chat_message row count matches the per-row migration on a smaller dataset
Verify all 7 indexes exist (\d chat_message)
Confirm downgrade path still works
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.
## 📋 Pull Request Information
**Original PR:** https://github.com/open-webui/open-webui/pull/24059
**Author:** [@ansonne](https://github.com/ansonne)
**Created:** 4/24/2026
**Status:** ❌ Closed
**Base:** `main` ← **Head:** `fix/chat-message-migration-oom-batched`
---
### 📝 Commits (10+)
- [`c854848`](https://github.com/open-webui/open-webui/commit/c8548488f2b07daeb747a2934e1aa547cbae6d86) feat: CI workflow
- [`2ac1eba`](https://github.com/open-webui/open-webui/commit/2ac1ebae6fcd18f748399642d64ad5e27257d36e) fix: var name
- [`3520cbc`](https://github.com/open-webui/open-webui/commit/3520cbc703747083761d6ed34a21ac0e85a3217c) feat: add aws credentials
- [`8e350c2`](https://github.com/open-webui/open-webui/commit/8e350c28e687d93195779afba93a3c47f89b9f20) feat: add latest tag
- [`4b7db7a`](https://github.com/open-webui/open-webui/commit/4b7db7af7501325effa4ec83a84a0366717d01fb) feat: ci step to change the image at ec2
- [`2d0ae86`](https://github.com/open-webui/open-webui/commit/2d0ae8655f84a06ade1f549de43619f37eb98e4a) fix: docker permission
- [`b2a1308`](https://github.com/open-webui/open-webui/commit/b2a130827b06421fd2a6ef453ca63207d62dddd3) feat: make sure https works
- [`afc2949`](https://github.com/open-webui/open-webui/commit/afc2949e6ad001166f1aff53852dc02853ee84c1) Merge remote-tracking branch 'upstream/main'
- [`80845ee`](https://github.com/open-webui/open-webui/commit/80845ee5ddffa5badf58a548dc2e0c351e81f77a) feat: Update static assets with new icons and splash images
- [`1eb6c2d`](https://github.com/open-webui/open-webui/commit/1eb6c2da0a4d7b36894b0e8d547084e6cc59f6ad) refactor: add deploy step to k8s
### 📊 Changes
**29 files changed** (+231 additions, -102 deletions)
<details>
<summary>View changed files</summary>
➕ `.github/workflows/cc-build-deploy.yaml` (+56 -0)
📝 `backend/open_webui/migrations/versions/8452d01d26d7_add_chat_message_table.py` (+133 -89)
📝 `backend/open_webui/static/apple-touch-icon.png` (+0 -0)
📝 `backend/open_webui/static/favicon-96x96.png` (+0 -0)
📝 `backend/open_webui/static/favicon-dark.png` (+0 -0)
📝 `backend/open_webui/static/favicon.ico` (+0 -0)
📝 `backend/open_webui/static/favicon.png` (+0 -0)
📝 `backend/open_webui/static/favicon.svg` (+3 -3)
📝 `backend/open_webui/static/logo.png` (+0 -0)
📝 `backend/open_webui/static/site.webmanifest` (+2 -2)
📝 `backend/open_webui/static/splash-dark.png` (+0 -0)
📝 `backend/open_webui/static/splash.png` (+0 -0)
📝 `backend/open_webui/static/web-app-manifest-192x192.png` (+0 -0)
📝 `backend/open_webui/static/web-app-manifest-512x512.png` (+0 -0)
➕ `k8s/development/values.yml` (+29 -0)
📝 `src/lib/constants.ts` (+1 -1)
📝 `static/favicon.png` (+0 -0)
📝 `static/opensearch.xml` (+2 -2)
📝 `static/static/apple-touch-icon.png` (+0 -0)
📝 `static/static/favicon-96x96.png` (+0 -0)
_...and 9 more files_
</details>
### 📄 Description
## Summary
- Original `8452d01d26d7` migration loaded the entire `chat` table via `fetchall()` (~771 MB JSON in our dataset), used per-row savepoints, and created 3 composite indexes before backfilling. This pegged pods at 2.7 GB RSS and OOMKilled repeatedly on 4 GB nodes before the migration could commit.
- Paginates SELECT (50 chats per page, `ORDER BY id`), bulk-inserts in flushes of 500 rows with `ON CONFLICT DO NOTHING` on PostgreSQL (`OR IGNORE` elsewhere), falls back to per-row savepoint inserts if a batch fails (preserves the original skip-bad-row behavior).
- Moves all 7 indexes (4 single-column + 3 composite) to after the backfill loop — much cheaper than per-row index updates.
Schema, data, and indexes at the end of the migration are identical to the original.
## Test plan
- [ ] Apply to a non-prod DB with a large `chat` table and confirm migration completes without OOM
- [ ] Verify `alembic_version` advances to `8452d01d26d7`
- [ ] Verify `chat_message` row count matches the per-row migration on a smaller dataset
- [ ] Verify all 7 indexes exist (`\d chat_message`)
- [ ] Confirm downgrade path still works
---
<sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
📋 Pull Request Information
Original PR: https://github.com/open-webui/open-webui/pull/24059
Author: @ansonne
Created: 4/24/2026
Status: ❌ Closed
Base:
main← Head:fix/chat-message-migration-oom-batched📝 Commits (10+)
c854848feat: CI workflow2ac1ebafix: var name3520cbcfeat: add aws credentials8e350c2feat: add latest tag4b7db7afeat: ci step to change the image at ec22d0ae86fix: docker permissionb2a1308feat: make sure https worksafc2949Merge remote-tracking branch 'upstream/main'80845eefeat: Update static assets with new icons and splash images1eb6c2drefactor: add deploy step to k8s📊 Changes
29 files changed (+231 additions, -102 deletions)
View changed files
➕
.github/workflows/cc-build-deploy.yaml(+56 -0)📝
backend/open_webui/migrations/versions/8452d01d26d7_add_chat_message_table.py(+133 -89)📝
backend/open_webui/static/apple-touch-icon.png(+0 -0)📝
backend/open_webui/static/favicon-96x96.png(+0 -0)📝
backend/open_webui/static/favicon-dark.png(+0 -0)📝
backend/open_webui/static/favicon.ico(+0 -0)📝
backend/open_webui/static/favicon.png(+0 -0)📝
backend/open_webui/static/favicon.svg(+3 -3)📝
backend/open_webui/static/logo.png(+0 -0)📝
backend/open_webui/static/site.webmanifest(+2 -2)📝
backend/open_webui/static/splash-dark.png(+0 -0)📝
backend/open_webui/static/splash.png(+0 -0)📝
backend/open_webui/static/web-app-manifest-192x192.png(+0 -0)📝
backend/open_webui/static/web-app-manifest-512x512.png(+0 -0)➕
k8s/development/values.yml(+29 -0)📝
src/lib/constants.ts(+1 -1)📝
static/favicon.png(+0 -0)📝
static/opensearch.xml(+2 -2)📝
static/static/apple-touch-icon.png(+0 -0)📝
static/static/favicon-96x96.png(+0 -0)...and 9 more files
📄 Description
Summary
8452d01d26d7migration loaded the entirechattable viafetchall()(~771 MB JSON in our dataset), used per-row savepoints, and created 3 composite indexes before backfilling. This pegged pods at 2.7 GB RSS and OOMKilled repeatedly on 4 GB nodes before the migration could commit.ORDER BY id), bulk-inserts in flushes of 500 rows withON CONFLICT DO NOTHINGon PostgreSQL (OR IGNOREelsewhere), falls back to per-row savepoint inserts if a batch fails (preserves the original skip-bad-row behavior).Schema, data, and indexes at the end of the migration are identical to the original.
Test plan
chattable and confirm migration completes without OOMalembic_versionadvances to8452d01d26d7chat_messagerow count matches the per-row migration on a smaller dataset\d chat_message)🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.