Performance
What a release build of Kern actually costs: startup, memory at rest, data operations on a large database, bundle sizes and whiteboard frame times.
How it was measured
On the development machine: Windows 11 Home (26200), 12 logical cores, 32 GB RAM, WebView2 154, release build with LTO. Scripts drive the real release binary over the WebView2 DevTools protocol.
Numbers are single runs on one machine. Treat them as indicative, not as guarantees.
Startup
| Metric | Result | Target |
|---|---|---|
| Launch → interface rendered (first run after build) | 430 ms | ≤ 2 s |
| Launch → interface rendered (relaunch) | 419 ms | ≤ 2 s |
Measured from process spawn to the shell's first commit. The "first run" was not a true cold boot — the OS file cache was warm from the build.
Startup defers non-essential work: the scheduler waits 6 seconds before its first tick; whiteboards, notes, settings and the calendar are lazy chunks; and only the dashboard's queries run at launch.
Idle resources
Dashboard open, 60 seconds after launch, no debugger attached.
| Process | Private memory | CPU |
|---|---|---|
| kern.exe (Rust host) | 7.3 MB | 0.00 % |
| WebView2 browser | 37.1 MB | 0.21 % |
| WebView2 renderer | 45.8 MB | 0.16 % |
| WebView2 GPU | 95.5 MB | 0.05 % |
| WebView2 utility ×2, crashpad | 22.1 MB | 0.05 % |
| Total | ≈ 208 MB | ≈ 0.47 % of one core |
The summed working set (≈ 394 MB) double-counts shared pages between WebView2 processes, so private memory is the better measure. Almost all of it is WebView2's fixed cost; the app's own native process uses 7 MB.
There are no polling loops in the interface. "Today" flips via a single timeout at local midnight, the focus timer only ticks while running, and the backend scheduler wakes every 20 seconds — 60 with Reduce background activity.
Data
5,000+ tasks across 9 projects, invoked from the interface over IPC.
| Operation | Median |
|---|---|
| Create task, including the IPC round-trip | 1.3 ms |
| Update task (patch + activity + full-text trigger) | 2.7 ms |
| Query all open top-level tasks (5,005 rows, with labels and subtask counts) | 51 ms |
| Query one project's tasks (1,000 rows) | 10.8 ms |
| Full-text search (28 hits) | 1.3 ms |
| Projects list with progress statistics | 4.7 ms |
| Dashboard overview counts | 1.7 ms |
| Open My Tasks with 5,005 tasks (click → rows painted) | 204 ms |
Large lists are virtualised above 250 rows, so only around 50 rows are mounted. Memory after loading the 5,000-task list was about 368 MB private.
Bundle and installer
| Artifact | Size |
|---|---|
| NSIS installer | 3.6 MB |
| MSI installer | 4.4 MB |
| Main JS chunk (React, query, dashboard, tasks) | 816 KB — 256 KB gzipped |
| Notes chunk (TipTap/ProseMirror), lazy | 521 KB — 181 KB gzipped |
| Whiteboard chunk (React Flow + editor), lazy | 271 KB — 87 KB gzipped |
| Storage chart (Chart.js), lazy | 141 KB — 49 KB gzipped |
| Settings chunk, lazy | 42 KB |
| API account pages, lazy | 19 KB — 6 KB gzipped |
| Project Code tab (GitHub & git), lazy | 18 KB — 6 KB gzipped |
Everything heavy is a lazy chunk, which is what keeps the first paint under half a second.
Whiteboard stress test
600 objects and 400 connectors — text cards, stickies and shapes in a 30×20 grid with chained connectors, on a 2560×1369 window. Pan and zoom were driven by scripted wheel events while frame intervals were recorded.
| Metric | Before LOD | With LOD |
|---|---|---|
| Save full scene (diffed upsert) | 30 ms | 25 ms |
| Open board (click → nodes on screen) | 1.33 s | 1.26 s |
| Frame interval, median | 5.9 ms | 5.9 ms |
| Frame interval, 95th percentile | 35.2 ms | 23.6 ms |
Fitting the whole board on screen (23% zoom) shows all 600 objects at once. Below 40% zoom the canvas drops card bodies, metadata, handles, edge labels and shadows — level of detail — since they're unreadable at that scale. Above 150 objects, only visible elements are rendered. Rich editors mount only while a card is being edited.
Other measurements
Debug build, development machine, single runs.
| Operation | Result |
|---|---|
| Storage scan of Kern's data (848 files) | 38–60 ms, background thread |
| Rescan after adding one attachment (unchanged folders from cache) | 38 ms |
| Favicon, first fetch (page + icon) | 140–610 ms, background thread |
| Favicon, cached lookup | 3 ms |
| GitHub issue import (4 issues) / no-op re-sync | 1.0 s / 0.4 s |
| Strikethrough animation | 260 ms transform, no layout reads per frame |
Not measured
- Board drag responsiveness. Verified with scripted drags — cards move between columns and persist — but not instrumented. Cards render through a drag overlay that tracks the pointer directly.
- Image-heavy whiteboards. Not stress-tested.
- True cold boot, after a restart with an empty file cache.
Reproducing it
The measurement scripts are Node with playwright-core, connecting over CDP.
Launch the release binary with:
WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS=--remote-debugging-port=9223
Connect, then read the ready timestamp the shell sets on first commit. Per-process memory and CPU come from the process tree.
The authoritative version of this report is PERFORMANCE.md in the
Kern repository, which is updated when
the measurements are rerun.