1 điểm bởi GN⁺ 4 giờ trước | 1 bình luận | Chia sẻ qua WhatsApp
  • 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
  • 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 MiB
      • codex_otel.log_only (INFO) 141,2 MiB
      • codex_otel.trace_safe (INFO) 121,2 MiB
      • log (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_safe chiế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.cache 128.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_safe trừ 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 = false cũ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.sqlite có kích thước 113M, MAX(id)=34.277.360 vớ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ờ
  • 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=warn và 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ị logs trong sqlite_sequence vượ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

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ế độ /goal củ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.sh dùng PRAGMA wal_checkpoint(TRUNCATE) để cắt bớt WAL đang hoạt động, có thể chạy bằng cron mỗi 15 phút
    • fix-codex-wal.sh xó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ảng logs sẽ làm WAL ngừng tăng; khi hoàn tác thì dùng DROP TRIGGER IF EXISTS block_log_inserts
      • VACUUM sẽ 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ạy DELETE/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
    • 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âng codex_otel.log_only, codex_otel.trace_safe, hyper_util, log, opentelemetry_sdk... lên WARN+
  • 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

    • Claude Code cũng ở ngay bên cạnh, nên không thể bỏ qua nó trong danh sách ví dụ về slopware
    • Nếu AI thực sự cho năng suất gấp 10 lần và đang tiến gần AGI hay ASI, thì tôi không hiểu vì sao những sản phẩm như Codex hay Claude Code CLI vẫn có thể tệ đến thế
      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ó”
    • Khi làm ở một tổ chức vốn mặc định công khai mã nguồn cho mọi thứ, kể cả dự án phụ, chỉ có đúng một lý do để giữ cái gì đó ở dạng đóng. Đó là xấu hổ
      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
    • Không chỉ Codex, mà ứng dụng ChatGPT trên macOS cũng thế: nếu để mở vài tiếng, theo thời gian nó sẽ ngốn tới 60GB RAM và giết sạch các ứng dụng khác
      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
    • Ban đầu người ta nói thế giới cần Anthropic để làm đối thủ của ChatGPT, giờ thì tình thế đã xoay hẳn một vòng
  • 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 FULL trê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

    • Lần này nữa, quy tắc ở cấp cơ sở dữ liệu lại cứu cả ngày
    • Giải pháp thật sự là ngừng dùng nó và chuyển sang Pi
  • 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ễ

    • Đó là bản CLI, không phải ứng dụng Codex độc quyền đang được nói đến ở đây
  • 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

    • Có vẻ OpenAI khá yếu trong việc sửa issue
      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
    • Đã có issue GitHub về đúng vấn đề này từ tháng 4
      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

    • Ngay lúc này ở công ty tôi, chúng tôi đang phải vật lộn với một sự cố lớn do đống rác vibe coding của ai đó gây ra vì nó hỏng rất nghiêm trọng
    • Giờ thì những thứ để phá cũng sắp cạn dần rồi
    • Nếu không có nợ kỹ thuật, vibe coding nhìn chung vẫn hữu ích cho việc làm prototype
      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

    • Với tôi thì hoàn toàn ngược lại
    • Tôi thấy Claude Code gần như không dùng nổi
      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ồ

    • Một phần cũng vì tác vụ agent chạy ở phía server, nên người ta nghĩ thin client có thể ngốn sạch tài nguyên cục bộ cũng không sao
  • 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 đỡ