You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
monitor.app 1.9.1: CPU rises with uptime, from 6% to 25% of a core over 4.5 hours #71
This was a soak test of the #70 build (the #69 fix, released as 1.9.1). One dashboard window stayed open on an M5 Max from 21:33 to 02:00 EDT (2026-09-25 to 2026-09-26). top took a 5-second reading every 5 minutes.
hour (EDT)
readings
mean CPU, % of a core
phys_footprint at end of hour
21:00
6
5.7
371 MB
22:00
12
7.5
480 MB
23:00
12
10.0
389 MB
00:00
12
13.0
432 MB
01:00
11
25.0
494 MB
02:00
1
25.1
489 MB
CPU rose each hour. Readings from 01:25 to 02:00 were 21.1–28.3%.
Mach ports stayed flat at 357–424.
Footprint moved between 360 and 496 MB and did not grow steadily.
Profile
sample <pid> 5 at 01:39, 4 h 01 min uptime. Most wall time is idle (__workq_kernreturn, mach_msg2_trap). Of the app's own frames, the largest are:
ChartCard.chart(_:), the inner ForEach closure at ChartCard.swift:509–512 (the per-sample PlottableValue and mark construction): about 160 samples in total.
The leaf frames are Swift value copies and generic-metadata lookups (swift_cvw_initWithCopyImpl, handleRefCountsDestroy, _swift_getGenericMetadata). These are consistent with copying per-sample values on each redraw.
Hypothesis (unverified)
The chart builds one mark per sample. If a card's range reads from HistoryStore and the range is not yet full, the number of marks grows with uptime until it fills. The per-redraw cost would then rise the same way. This does not explain the step at about 01:25. That step may be a range change, or a history tier that started to feed the chart.
Checks to separate the causes:
Log the mark count for each card on each redraw.
Downsample each series to about the chart's pixel width before building the marks.
Repeat the soak with a fixed 5-minute range on all cards.
Background load in the window: a Spotlight updater at about 100% of a core at times, and Time Machine (backupd) after 01:55. Both are outside Monitor's own CPU figure.
The soak ended at 13:00 EDT with 15 h 28 min uptime. That was 187 readings, one every 5 minutes. monitor.app is still running; only the logger stopped.
hour (EDT)
readings
mean CPU, % of a core
phys_footprint at end of hour
04:00
12
25.7
587 MB
05:00
12
28.6
606 MB
06:00
12
30.5
581 MB
07:00
12
30.8
606 MB
08:00
12
39.2
662 MB
09:00
12
33.1
642 MB
10:00
12
36.9
686 MB
11:00
12
32.9
720 MB
12:00
12
37.3
719 MB
13:00
1
42.2
726 MB
Summary over the whole soak:
Mean CPU rose from 5.7% in the first hour to 30–39% after 8 hours.
The footprint rose from about 371 MB to 726 MB.
Mach ports stayed flat, at about 357–426.
Both CPU and footprint still rise with uptime. That fits the per-mark chart hypothesis above, and it may also be a retained-sample leak. A profile at a fixed chart range would separate the two.
Activity
evandhoffman commentedon Sep 26, 2026
The same soak, continued to 03:30 EDT (6 h uptime):
--opus
evandhoffman commentedon Sep 26, 2026
The soak ended at 13:00 EDT with 15 h 28 min uptime. That was 187 readings, one every 5 minutes. monitor.app is still running; only the logger stopped.
Summary over the whole soak:
Both CPU and footprint still rise with uptime. That fits the per-mark chart hypothesis above, and it may also be a retained-sample leak. A profile at a fixed chart range would separate the two.
--opus