Pomodoro Bar · Engineering notes · October 11, 2026

A timer should do less.

Pomodoro Bar 1.1.6 keeps the WPF app and removes unnecessary refresh work. Here is what changed, what we measured, and where the results are less conclusive.

The problem was continuous work

The earlier implementation refreshed the UI ten times a second, including when the timer was paused or its windows were hidden. A countdown needs to display seconds; most other states need considerably less work.

The replacement schedules the next visible countdown second, reminder, completion, or rounded end-time preview. When both windows are hidden, it waits for the next timer event. Restoring a window or resuming Windows catches the display up immediately.

What else changed

  • Cache countdown text, layout, geometry, brushes, duration labels, and parsed drafts rather than rebuilding unchanged resources.
  • Animate only a visible bar during an active warning. Hidden completion audio continues independently.
  • Use native Windows tray and monitor APIs instead of loading WinForms for those tasks.
  • Keep default WPF rendering: a software-rendering experiment saved more RAM but increased CPU in the repeat test.

Seven states, before and after.

Before → after. CPU is a percentage of total machine capacity; resident memory is the process working set, not uniquely owned RAM. Allocation rate measures churn, not retained memory.

Paused, both visible

CPU (%)
0.522 → 0.129
Resident (MiB)
134.8 → 105.0
Allocation (KiB/s)
242.8 → 6.4

Running, bar only

CPU (%)
0.380 → 0.548
Resident (MiB)
147.1 → 112.5
Allocation (KiB/s)
289.8 → 18.5

Running, both visible

CPU (%)
0.373 → 0.399
Resident (MiB)
150.5 → 120.7
Allocation (KiB/s)
289.0 → 36.0

Running, both hidden

CPU (%)
0.142 → 0.077
Resident (MiB)
142.5 → 114.2
Allocation (KiB/s)
289.7 → 5.3

Paused, both hidden

CPU (%)
0.288 → 0.067
Resident (MiB)
142.8 → 112.1
Allocation (KiB/s)
239.7 → 5.0

Running, active draft

CPU (%)
0.428 → 0.441
Resident (MiB)
145.9 → 120.1
Allocation (KiB/s)
367.6 → 81.7

Completion, silent audio

CPU (%)
0.810 → 0.246
Resident (MiB)
146.7 → 117.8
Allocation (KiB/s)
438.7 → 54.2

What the results support

These matched runs showed roughly 18–24% lower resident memory and 78–98% less allocation churn. Paused, hidden, and completion states used less CPU. Some visible-running states used more CPU in this first comparison; those increases are included above.

A repeated bar-only run measured 0.762% → 0.612% total CPU and 126.9 → 107.8 MiB resident memory. The optimized run recorded 30 scheduler wakes, 30 bar renders, and no hidden-editor syncs in about 30 seconds. UI-thread CPU time fell from 0.6875 to 0.15625 seconds.

How we measured—and what this does not prove

We compared pre-optimization commit 8e7aac4 with the optimized WPF build using the same tracked resource harness. The old build’s seven states ran first; the optimized build’s states ran next. Builds did not overlap the measurements.

The harness used the real tray and silent test audio, with updates, IPC, and real user settings disabled. Sampling overhead is included. GPU, Desktop Window Manager, real alarm playback, and update downloads are outside these steady-state numbers.

These are short runs on one machine. Background activity, rendering drivers, foreground policy, and process aging introduce variation. This is not a battery-life test, a long-term leak test, or a guarantee that CPU will stay below a particular percentage.

Working-set trimming and forced garbage collections were not used to make the numbers look smaller. The app retains WPF; it has not been rewritten in Rust or C++.

Reproduce or inspect the work

The repository documents the seven-state harness and bar-only repeat mode, including the software-rendering experiment. Raw readings are retained locally; the checked-in report contains the summarized measurements and limitations.