Skip to content

Memory and speed

tt-git is meant to sit open all day next to your editor. While you aren’t using it, it should cost next to nothing: no CPU, no git processes, and a few tens of megabytes of memory, even on a repository with tens of thousands of commits and hundreds of branches.

  • It redraws only when something changed. A 250 ms tick redraws only when a relative date on screen would change (“2m” becoming “3m”), plugins reloaded, or a plugin pane shows a cursor.
  • Few threads. tt-git runs on a single-threaded async runtime. git work runs on a blocking thread pool whose threads exit once they’ve been idle for a few seconds, so an idle tt-git has a handful of threads.
  • One git process per kind of load. Each kind of load keeps at most one git process in flight, with only the newest request waiting. Holding j through the graph doesn’t start a git show per row, and a graph load that’s been replaced is killed rather than finished.
  • Compact commits. Hashes are stored as 32-byte arrays rather than strings, author names and emails are shared between commits, and the graph stores only the lanes it draws, at 2 bytes a lane.
  • Cheap refreshes. A refs refresh is 6 to 8 git processes however many branches and tags there are. Reflogs and the ref fingerprint are read from files directly, without git.
  • Quiet watching. File changes in paths git ignores (node_modules/, dist/, target/) don’t trigger a reload, and a fetch that brings nothing new doesn’t reload the graph. See Refreshing.

What each pane runs, and why, is in How tt-git uses git.

Measured on a long-lived React and TypeScript web app:

History28,145 commits on all refs (27,281 on HEAD), since 2017, 42 authors
Refs810: 160 local branches, 303 remote branches, 341 tags
Tracked files3,209 (1,111 .tsx/.jsx, 1,637 .ts/.js)
Packed objects246k objects, 103 MiB
Working treeWith an installed node_modules/ (ignored)

tt-git release build, Windows 11, git 2.50, --no-plugins, default config (so the graph loads the newest 20,000 commits), sampled every second for 45 seconds after starting, with no keys pressed:

Peak working set30.5 MiB
Working set, idle28.2 to 29.2 MiB
Private bytes, idle17.9 to 18.9 MiB
Threads11 while loading, 5 at idle
CPU time0.17 s to load, 0.31 s total over 45 s
git processes at idleNone

Refs, status and the first 20,000 commits of the graph had loaded by the first sample, one second in; the extra threads wound down over the next 20 seconds. The binary is 6.4 MiB.

Two settings in the configuration file trade memory for reach:

SettingDefaultEffect
graph.max_commits20000Commits loaded at a time. Scrolling near the end loads the next batch, so a smaller number uses less memory without hiding history.
graph.max_lanes16Lanes drawn and stored before the rest collapse into ….

watch = false turns off file watching entirely; then tt-git only refreshes when you press ctrl+r or after a git command it runs itself.