Tracing Goroutines in Realtime with eBPF

Go dev ‘freezes time’ to spy on tiny workers — Rust wants a turn

TLDR: A new tool called xgotop uses eBPF to pause and inspect Go’s tiny background tasks in near real time. The community is split between excitement, Rust feature requests, DTrace veterans comparing notes, and a debate over whether goroutine leaks are common and if this will work across Go versions.

Move over, boring logs — one Go dev just hit the slow-mo button on code. Their hackathon-winning tool, xgotop, uses eBPF (a Linux feature that can run tiny programs) to “freeze-frame” Go’s mini workers, called goroutines, and watch them switch jobs and grab memory in near real time. The crowd went wild, but not quietly.

The loudest chorus? Rust fans knocking on the door. “Is there something similar for async Rust?” asked one, kicking off a friendly turf war. Old-school sleuths showed up with receipts too, flexing with DTrace links and a subtle “been there, traced that” energy. Meanwhile, practical devs worried about the boring stuff: “Will this work across different Go versions?” and “Do goroutine leaks even happen that much?” Cue the debate: some claim Go makes it hard to shoot your foot; others say leaks are real and this is the microscope they needed.

Humor flowed like logs: CSI memes (“freeze… enhance”), jokes about stalking “tiny digital hamsters,” and puns on xgotop being the “fitness tracker” for goroutines. The dev promises a Part Two with a full standalone tool, which only cranked the hype. Verdict: equal parts wow, skepticism, and can-you-port-this-to-my-language energy — classic internet engineering theater.

Key Points

  • xgotop is an eBPF-based tool to trace Go goroutine state changes and memory allocations in near real time.
  • The article is part one: it covers design rationale, Go runtime internals, and a bpftrace proof of concept.
  • Goroutines have parent-child relationships; their metadata is in the Go runtime g struct, including IDs, state, and start function.
  • Key goroutine states are listed (_Gidle, _Grunnable, _Grunning, _Gsyscall, _Gwaiting, _Gdead, _Gcopystack, _Gpreempted, _Gleaked, _Gdeadextra).
  • Part two will convert the bpftrace PoC into a standalone tool using eBPF ring buffers, hash maps, LRU caches, configurable sampling, C, Go, and cilium/ebpf-go.

Hottest takes

"Cool! is there something similar for async rust ?" — xtoilette
"Interesting to see an ebpf approach... I did the same with Dtrace" — broken_broken_
"how common is it for go devs to experience leaking goroutines ?" — trueno
Made with <3 by @siedrix and @shesho from CDMX. Powered by Forge&Hive.