Skip to content

Log process memory at the end of each collection cycle#956

Merged
erikdarlingdata merged 1 commit into
devfrom
feature/log-process-memory-per-cycle
May 15, 2026
Merged

Log process memory at the end of each collection cycle#956
erikdarlingdata merged 1 commit into
devfrom
feature/log-process-memory-per-cycle

Conversation

@erikdarlingdata
Copy link
Copy Markdown
Owner

Summary

Add a single INFO log line at the end of every collection cycle reporting Working Set, Private Bytes, and GC heap.

Why

Two-fold motivation, both surfaced by #933:

  1. Self-reporting for bug reporters. When OP filed [BUG] Memory usage on client #933 about high memory, they had to read the number off Task Manager. With this in place, the answer is in the log they're already pasting.
  2. Continuous trace for regression diagnosis. During the recent investigation we had to sample memory externally (PowerShell every 30 s) to confirm the fix worked. With this line in the log, future memory regressions show up directly in the file we already collect from users.

Implementation

  • CollectionBackgroundService.LogProcessMemory() — three property reads, called after RunArchivalIfDueAsync and RunRetentionIfDue so it captures the cycle's quiescent state, not a mid-archival spike.
  • Errors swallowed at DEBUG level so a transient inability to read process stats never breaks the collection loop.

Output

One line per minute, format:

[CollectionBackgroundService] Process memory: WS=350 MB, Private=215 MB, GC heap=42 MB
  • WS = working set (what Task Manager shows)
  • Private = private bytes (unique-to-process, the honest "actual RAM cost")
  • GC heap = .NET managed heap only — WS - Private - GC is rough native/shared overhead

Test plan

  • Builds clean
  • Run Lite, watch the log emit one memory line per cycle
  • Confirm cadence doesn't cause log volume problems (1440 lines/day at default 1-min cadence)

🤖 Generated with Claude Code

Lite has had no internal record of its own memory usage. Bug reporters
(see #933) had to read it off Task Manager, and we had no historical
trace for diagnosing growth patterns. After every collection cycle —
which is also after archival and retention run, so it captures the
quiescent state — log:

  Process memory: WS=XXX MB, Private=XXX MB, GC heap=XXX MB

WS is Working Set (what Task Manager shows). Private is private bytes
(unique to this process, the more honest "actual RAM cost" number).
GC heap is .NET-managed memory only — together with WS-Private this
splits managed vs native vs shared.

One INFO log line per minute. Three property reads — negligible
overhead. Errors swallowed at DEBUG level (don't ever break the
collection loop because we couldn't read memory stats).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@erikdarlingdata erikdarlingdata merged commit b4aa8de into dev May 15, 2026
2 checks passed
@erikdarlingdata erikdarlingdata deleted the feature/log-process-memory-per-cycle branch May 15, 2026 15:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant