# Client memory with many large-message mailboxes in one tree: per-mailbox vs process-wide byte budget
#
# Why: review of PR #949 (minor): "Client memory bound is per mailbox, not per process: 12 mailboxes
# of large messages took autoindex to 1.71 GB RSS versus the documented ~296 MB." Commit 69b0e8ba
# made the in-flight byte budget (IN_FLIGHT_BUDGET, 256 MB) one per process, like the parse gate.
#
# Tree: 12 extension-less mailboxes (Mail/Folder00..11) x 16 messages, each message carrying one
# 20 MB base64 attachment (15 MiB of random bytes) - 4,079,605,864 bytes on disk. Binary attachments
# become name/type/size cards, so 396 records. Generated by (random content, so not byte-reproducible):
#
#   #!/usr/bin/env python3
#   """12 extension-less mailboxes x 16 messages x 20 MB base64 attachment (the review's 'tree-many')."""
#   import base64, os, sys
#   root = sys.argv[1]; os.makedirs(os.path.join(root, "Mail"), exist_ok=True)
#   blob = base64.encodebytes(os.urandom(15 * 1024 * 1024)).decode()  # ~20 MB of base64 text
#   for b in range(12):
#       with open(os.path.join(root, "Mail", f"Folder{b:02d}"), "w") as f:
#           for m in range(16):
#               f.write(f"From sender{b}@example.org Tue Nov 14 22:13:20 2023\n"
#                       f"From: Sender {b} <sender{b}@example.org>\nTo: bob@example.org\n"
#                       f"Subject: big attachment {b}-{m}\nDate: Tue, 14 Nov 2023 22:13:20 +0000\n"
#                       f"Message-ID: <big-{b}-{m}@example.org>\nMIME-Version: 1.0\n"
#                       f"Content-Type: multipart/mixed; boundary=\"bb\"\n\n--bb\nContent-Type: text/plain\n\n"
#                       f"body xqmany{b}x{m}\n--bb\nContent-Type: application/octet-stream; name=\"blob-{b}-{m}.bin\"\n"
#                       f"Content-Disposition: attachment; filename=\"blob-{b}-{m}.bin\"\nContent-Transfer-Encoding: base64\n\n")
#               f.write(blob); f.write("--bb--\n\n")
#   print("ok")
#
# Binaries: two release builds of feat/ingest-mbox-takeout from the same tree. They differ in
# engine/crates/xerj-autoindex/src/extract/mbox.rs - the file at 69b0e8ba^ (one budget per
# extract_parallel call) vs 69b0e8ba (one budget per process) - and in the wording of one
# progress note in lib.rs, which the second build also carries; nothing else. Same node (127.0.0.1:12120,
# auth on, lexical embedder), same flags, alternating, fresh --state-dir and --prefix per run:
#   XERJ_API_KEY=... /usr/bin/time -f "wall=%e s maxrss=%M kB exit=%x" \
#     xerj autoindex tree-many --url http://127.0.0.1:12120 --prefix <p> --brain <p> --state-dir <s> --yes --progress plain
# maxrss is GNU time's "Maximum resident set size": the largest single process (autoindex itself).
# Date: 2026-09-19. The box was shared (1-minute load ~51-53 during these runs).
#
run 1  one budget per mailbox (mbox.rs at 69b0e8ba^)  wall=4.56 s maxrss=1420068 kB exit=0  1-min load=50.88
        xerj-done ok=true exit=0 reason=completed wall=4.5s files=12 records=396 datasets=1 junk_files=0 code_files=0 code_files
run 1  process-wide budget   (mbox.rs at 69b0e8ba) wall=4.05 s maxrss=918432 kB exit=0  1-min load=52.01
        xerj-done ok=true exit=0 reason=completed wall=4.0s files=12 records=396 datasets=1 junk_files=0 code_files=0 code_files
run 2  one budget per mailbox (mbox.rs at 69b0e8ba^)  wall=3.25 s maxrss=1315372 kB exit=0  1-min load=52.01
        xerj-done ok=true exit=0 reason=completed wall=3.2s files=12 records=396 datasets=1 junk_files=0 code_files=0 code_files
run 2  process-wide budget   (mbox.rs at 69b0e8ba) wall=3.30 s maxrss=927796 kB exit=0  1-min load=53.45
        xerj-done ok=true exit=0 reason=completed wall=3.2s files=12 records=396 datasets=1 junk_files=0 code_files=0 code_files
#
# Reading: 1,386.8 / 1,284.5 MiB with a budget per mailbox, 896.9 / 906.0 MiB with one per process
# (-29 to -35 %). The budget bounds the raw bytes of messages in flight; it does not bound the
# parser's working memory (a decoded 15 MiB attachment per message being parsed) or the one
# message each open mailbox is assembling, which is why ~0.9 GiB remains. The ~296 MiB client
# figure of the 1 GB run is a ONE-mailbox figure and the docs say so.
