Lỗi ghi log của Codex có thể gây ra lượng ghi ở mức TB lên SSD cục bộ, làm hao mòn tuổi thọ SSD nhanh chóng
(github.com/openai)- Codex liên tục ghi lượng lớn dữ liệu vào cơ sở dữ liệu log phản hồi SQLite cục bộ, và trong một môi trường người dùng đã ghi khoảng 37TB lên SSD chính sau 21 ngày hoạt động
- Quy đổi ra tương đương khoảng 640TB mỗi năm, tức khoảng 640 lần ghi toàn bộ ổ mỗi năm với SSD 1TB, và có thể tiêu hao hết tuổi thọ ghi được bảo hành của một số SSD tiêu dùng (khoảng 600 TBW) trong vòng chưa đầy 1 năm
- Số hàng được giữ lại chỉ khoảng 500 nghìn, nhưng bộ đếm AUTOINCREMENT đã vượt 5,5 tỷ ID, tạo ra khoảng cách khoảng 10.000 lần giữa số hàng còn giữ và số ID chèn tích lũy
- Nguyên nhân là bộ đồng bộ log phản hồi SQLite được đặt với mặc định TRACE toàn cục (
Targets::new().with_default(Level::TRACE)), khiến cả log nội bộ của dependency lẫn payload giao thức raw dung lượng lớn đều bị ghi vĩnh viễn - Vấn đề đã được đóng sau khi hai PR được hợp nhất vào ngày 22 tháng 6 năm 2026, nhờ chặn được khoảng 85% log
Triệu chứng chính và phạm vi ảnh hưởng
- Codex liên tục ghi lượng lớn vào các tệp sau
~/.codex/logs_2.sqlite~/.codex/logs_2.sqlite-wal~/.codex/logs_2.sqlite-shm
- Sau 21 ngày hoạt động, SSD chính bị ghi khoảng 37TB; kiểm tra theo tiến trình/tệp xác nhận log SQLite của Codex là nguồn ghi liên tục chính
- Quy đổi ra khoảng 640TB mỗi năm, tương đương khoảng 640 lần ghi toàn bộ ổ mỗi năm với SSD 1TB
- Một số SSD tiêu dùng có mức 600 TBW chẳng hạn, nên có thể bị tiêu hao tuổi thọ ghi được bảo hành trong chưa tới 1 năm
Dữ liệu chứng cứ
-
Evidence1 — khuếch đại ghi (write amplification)
- Kích thước hiện tại của tệp
logs_2.sqlite: 1.2 GiB - Số hàng hiện được giữ lại: 506.149
- Tổng
row idđã cấp phát tích lũy: 5.543.677.486 - Khoảng cách khoảng 10.000 lần giữa số hàng được giữ lại (khoảng 0,5M) và số ID chèn tích lũy (5,5 tỷ+); ngay cả khi chưa tính WAL, chỉ mục, pruning, checkpoint, ghi lại trang và khuếch đại ở cấp thiết bị, vẫn có thể ước tính churn log trong quá khứ ở quy mô hơn 10TB
- Kích thước hiện tại của tệp
-
Evidence2 — phân bố level/target
- 681.774 hàng được giữ lại, nội dung log giữ lại ước tính khoảng 1.035,6 MiB
- Tỷ trọng theo level: TRACE 70,7%, INFO 25,7%, DEBUG 3,0%, WARN 0,6%
- Các cặp target+level lớn nhất
codex_api::endpoint::responses_websocket(TRACE) 527,4 MiBcodex_otel.log_only(INFO) 141,2 MiBcodex_otel.trace_safe(INFO) 121,2 MiBlog(TRACE) 97,4 MiB
- Nguồn hàng đầu chủ yếu là log TRACE toàn cục, log telemetry được mirror, và việc ghi lại payload raw websocket/SSE
codex_otel.log_only+codex_otel.trace_safechiếm thêm 25,3%; nếu lọc các category này thì có thể loại bỏ khoảng 96% số byte log được giữ lại trong mẫu- Nguồn TRACE xuất hiện thường xuyên nhất (
target=log) có nhiều mục cấp thấp nhưinotify event(ví dụld.so.cache128.764 lần), lời gọi nội bộ tokio-tungstenite,WouldBlock, v.v.
-
Đo khuếch đại ghi
- Trong mẫu 15 giây, số hàng được giữ lại vẫn là 681.774, nhưng có khoảng 36.211 hàng được chèn
- Khuếch đại ghi xảy ra do mô hình insert-and-prune lặp lại: chèn → lập chỉ mục → ghi WAL → pruning
Nguyên nhân ước tính
- Bộ đồng bộ log phản hồi SQLite được cài với mặc định TRACE toàn cục (
Targets::new().with_default(Level::TRACE)) - Vì vậy, mọi target bao gồm log dependency/nội bộ và payload giao thức raw dung lượng lớn đều bị lưu vĩnh viễn ở level TRACE
Hướng sửa được đề xuất
- Vẫn giữ log phản hồi nhưng thu hẹp phạm vi lưu vĩnh viễn theo mặc định
- Không dùng TRACE toàn cục cho bộ đồng bộ log phản hồi SQLite
- Nâng ngưỡng hoặc loại bỏ các nhiễu giá trị thấp như
target=log,hyper_util, nội bộ tokio-tungstenite, spam inotify, log SDK OpenTelemetry cấp thấp - Thay vì lưu toàn bộ payload raw websocket/SSE, chỉ lưu tóm tắt (loại sự kiện, thời gian xử lý, thành công/thất bại, mức dùng token, độ dài byte của payload)
- Tránh lưu các sự kiện mirror
codex_otel.log_only/codex_otel.trace_safetrừ khi thực sự hữu ích cho gỡ lỗi - Chỉ giới hạn theo thread là chưa đủ, cần thêm giới hạn kích thước/cường độ ghi toàn cục cho DB log
- Một tùy chọn như
sqlite_logs_enabled = falsecũng hữu ích, nhưng giải pháp cốt lõi là lọc mặc định tốt hơn
Báo cáo tái hiện trên nhiều nền tảng
-
macOS
- Trong môi trường macOS 15.7.7 / Codex 26.616.51431,
logs_2.sqlitecó kích thước 113M,MAX(id)=34.277.360với 31.405 hàng được giữ lại; hai mẫu 60 giây xác nhận khoảng 60 lần ghi mỗi giây - Có báo cáo rằng tiến trình
codexđã ghi khoảng 50GB trong các phiên kéo dài 1–2 giờ
- Trong môi trường macOS 15.7.7 / Codex 26.616.51431,
-
Windows
- Trên Codex Desktop cho Windows (
codex.exe app-server --analytics-default-enabled), các hàng TRACE vẫn liên tục được chèn dù không cóRUST_LOG=warnvà cũng không có cấu hình trace tường minh - Có khoảng 71k hàng được giữ lại, giá trị
logstrongsqlite_sequencevượt 18,5 triệu, cho thấy nhiều đợt churn insert/prune trước đó - Trong phân bố 10 phút có 1.812 hàng TRACE; các target TRACE hàng đầu gồm
codex_api::endpoint::responses_websocket(3,5MB+),codex_api::sse::responses - Hành vi kỳ vọng: khi
RUST_LOG=warn, không nên lưu liên tục TRACE dependency/nội bộ và payload dung lượng lớn
- Trên Codex Desktop cho Windows (
Rủi ro bổ sung và biện pháp giảm nhẹ tạm thời
-
Rủi ro mất dữ liệu
- Nếu khởi động lại khi đĩa đã đầy, Linux có thể không đăng nhập được
- Chế độ
/goalcủa Codex có thể cố giải phóng dung lượng đĩa bằng cách xóa tệp/thư mục, dẫn đến mất dữ liệu
-
Script giảm nhẹ tạm thời
trim-codex-wal.shdùngPRAGMA wal_checkpoint(TRUNCATE)để cắt bớt WAL đang hoạt động, có thể chạy bằng cron mỗi 15 phútfix-codex-wal.shxóa tệp log/WAL rồi gửi SIGTERM→SIGKILL tới các tiến trình liên quan đến Codex để giải phóng dung lượng đĩa ngay lập tức- Thêm trigger SQLite (
block_log_inserts) để bỏ qua việc chèn vào bảnglogssẽ làm WAL ngừng tăng; khi hoàn tác thì dùngDROP TRIGGER IF EXISTS block_log_inserts- Vì
VACUUMsẽ ghi lại toàn bộ DB nên có thể tạo ra một đợt ghi rất lớn một lần trên các tệp lớn; nên thêm trigger, xác nhận WAL đã ngừng tăng rồi mới chạyDELETE/VACUUM - Do đây là thay đổi vào schema SQLite riêng, các bản cập nhật/migration Codex sau này có thể tạo lại bảng hoặc xóa trigger
- Vì
- Cho tới khi có bản sửa vĩnh viễn, cũng có đề xuất đặt DB này trên ramdisk để tránh làm hại SSD
Cách giải quyết và đóng vấn đề
- Vào ngày 22 tháng 6 năm 2026, hai PR được hợp nhất giúp giảm khoảng 85% log, nhờ đó issue được đánh dấu hoàn tất
- Dừng ghi log mọi sự kiện Responses WebSocket (#29432)
- Lọc các target nhiễu khỏi log vĩnh viễn (#29457)
- Một bản vá được đề xuất riêng dùng mặc định lưu
INFO+thay cho TRACE toàn cục, đồng thời nângcodex_otel.log_only,codex_otel.trace_safe,hyper_util,log,opentelemetry_sdk... lênWARN+ - Bản sửa đã được phát hành trong
rust-v0.142.0
1 bình luận
Ý kiến trên Hacker News
Tôi xem Codex là một trong những ví dụ tai tiếng nhất của slopware
Trên macOS, chỉ cần để cửa sổ hiện ra thôi mà nó đã dùng GPU 100% chỉ để hiển thị thông báo spinner
Trên MBP M5, chỉ riêng thông báo spinner đã làm GPU lên 100%, và quạt kêu rất to trong phần lớn thời gian chờ model, nên cần cẩn thận khi dùng pin
Vấn đề này đã được đưa lên GitHub gần 6 tháng rồi, có lẽ từ sau khi mớ tạp nham làm bằng vibe coding được phát hành
Muốn tự sửa cũng không được vì không hiểu sao nó lại là mã nguồn đóng
Có rất nhiều tranh cãi về model nào tốt hơn, liệu vibe coding có khả thi không, nhưng đây có vẻ là mức độ mà một trong những công ty có nhiều tiền, nhân lực và năng lực model nhất có thể làm được với vibe coding
Trong bối cảnh CEO đã tuyên bố là đang “tập trung vào coding”, một sai lầm nghiêm trọng như vậy trông như dấu hiệu cho thấy có điều gì đó thật sự hỏng hóc bên trong công ty, và trên Polymarket cũng hầu như không còn ai tin OpenAI sẽ sớm tung ra model dẫn đầu
Thật bi kịch vì thế giới cần một đối thủ của Anthropic
Cứ như thể “cuộc cách mạng AI tác tử” lẽ ra phải giải quyết được những vấn đề này rồi chứ
Chẳng lẽ bên trong họ cũng đang hiện “đang xử lý, vui lòng chờ” hoặc “nhiệm vụ quá khó”
Không ai muốn trở thành gương mặt đại diện công khai cho một codebase rác rưởi
Nếu còn đang dùng chính đống mã đó để biện minh cho mức giá vô lý, thì gánh nặng ấy chắc còn tăng gấp ba
Tôi không hiểu nổi
Ngay cả khi dùng Google AI Studio trên trình duyệt thì CPU cũng bị kéo lên 100%
Cuối cùng cứ như là phải tự làm ứng dụng cho mọi thứ vậy
Trên X đã có cách khắc phục tạm thời cho vấn đề này[1]
sqlite3 ~/.codex/logs_2.sqlite "CREATE TRIGGER IF NOT EXISTS block_log_inserts BEFORE INSERT ON logs BEGIN SELECT RAISE(IGNORE); END;"Ngoài ra, có người chạy
VACUUM FULLtrên file sqlite đó ở laptop thì nó giảm từ 27GB xuống còn 73MB[2][1]: https://xcancel.com/bdsqlsz/status/2067964486615810369
[2]: https://xcancel.com/jeethu/status/2068087449469780434
Mọi người đều đang chỉ trích OpenAI, và cũng có lý, nhưng cũng đáng nhắc lại rằng khác với Claude Code, Codex chính thức có thể tùy biến: https://github.com/openai/codex
Việc vá cũng khá dễ
Thật sốc
Vấn đề đã mở được một tuần rồi mà theo tôi thấy thì OpenAI cứ im lặng
Tôi cứ nghĩ những nhà cung cấp kiểu này sẽ cực kỳ nhạy cảm với những vấn đề như thế, nên thật khó hiểu
Hẳn là họ có gắn đủ loại agent để theo dõi issue tiềm năng trên GitHub và đề xuất bản sửa chứ? …chứ nhỉ?
Việc dùng chính công cụ của mình để xử lý issue GitHub theo thời gian thực lẽ ra phải là chuyện rất tầm thường mới đúng
Ví dụ tôi thích nhất là #2472: họ demo trên sân khấu ra mắt GPT-5 là đã “sửa” xong, nhưng ticket vẫn còn mở và bản “sửa” đó cũng chưa được merge
Bài viết gốc chỉ ra chuyện này là https://blog.tymscar.com/posts/openaiunmergeddemo/ và issue là https://github.com/openai/openai-python/issues/2472
Tôi dùng Codex rất nhiều và rất hài lòng với hiệu năng của nó (UX và đầu ra), nhưng thật khó hiểu khi họ vẫn chưa sửa lỗi này
Vấn đề này có vẻ đã được sửa[0] và có lẽ sẽ vào bản phát hành tiếp theo
[0] https://github.com/openai/codex/commit/e98d43ac372ddf7f513c0...
Vibe coding đã đưa khẩu hiệu “move fast and break things” lên một đẳng cấp hoàn toàn khác
Nhưng trong sản phẩm thực tế, kỹ sư phần mềm thực thụ sẽ không bao giờ bị thay thế
Hơi lạc đề một chút, nhưng các công ty này nên thôi làm bẩn thư mục gốc của repo bằng Claude.md hay copilot.md đi
Họ nên ngồi lại với nhau và thống nhất một cấu trúc thư mục quen thuộc như
docs/llm/*Cuối năm ngoái, khi Claude Code tệ hại vì độ trễ, OpenAI gần như đã vuột mất một chiến thắng trong tầm tay
Dạo này Codex bị trễ gõ chữ ngay từ lúc khởi động, còn Claude Code thì thỉnh thoảng có treo nhưng nhìn chung khi tôi nhấn phím thì… đúng nghĩa là… nó hiện ra theo đúng phím tôi nhấn
Mỗi khi cần gõ quá vài từ là tôi luôn phải nhập trong neovim
Đây thật ra là một lỗi rất điển hình
Họ đã phát hành với log theo dõi/gỡ lỗi bật cho mọi thứ, nhưng điều buồn cười là tác động lại không biểu hiện theo kiểu thông thường
Trước đây thì chỉ cần dev bật logging mức trace là ứng dụng sẽ chậm đến thảm họa và bản cập nhật kế tiếp sẽ sửa ngay, nhưng giờ bộ nhớ, tốc độ CPU và tốc độ đĩa đã tăng quá mạnh đến mức chúng ta đang ở một điểm mà kiểu lỗi đó không còn lộ ra ngay theo cách quen thuộc nữa, thật điên rồ
Mong là ai đó quyên góp ít token cho startup đầy dũng cảm này. Có vẻ họ cần được giúp đỡ