Go Goroutine Dump Analyzer

Paste a SIGQUIT or panic dump and get the shape of it: how many goroutines are in each state, which stacks they share, how long the oldest has waited, and which groups are crowded enough to be worth a look.

Nothing you paste is transmitted. There is no endpoint behind this page: the Go that reads the dump is compiled to WebAssembly and runs in this tab, so it never leaves the browser. That matters more here than on the other pages in this section — a production dump carries your file paths, your function names and the shape of your system — and what makes it safe is structural rather than a promise.

Start from one of these

    Why grouping is the whole job

    A production dump is thousands of goroutines long, and almost all of it is repetition: a handful of distinct stacks, each held by hundreds of goroutines doing the same thing. Reading it line by line is how people give up on these.

    What you actually need is the shape. How many are waiting, on what, and for how long — and which stacks are held by far more goroutines than the program should have. So this groups twice: by state, because “4,000 in chan receive” is the whole story on most days, and by stack, because goroutines sharing a stack were started by the same code and are stuck for the same reason.

    Grouping ignores the pointer arguments and the +0x1a code offsets. Those differ between goroutines doing identical work, and grouping on them would put every worker in a group of one — which is the reading problem, not the solution. The arguments are still shown, because occasionally they are the only way to tell two identical stacks apart.

    What the flag means, and what it does not

    A group is flagged when enough goroutines share a stack and they are waiting rather than running. That is what a leak looks like. It is also exactly what a healthy worker pool looks like, and what a server holding a thousand live connections looks like.

    So the flag is a place to start, not a finding. This page will tell you that twelve goroutines have been waiting on the same channel receive for forty minutes; whether that is your connection pool or your bug is something only you can say. The one thing it will not do is call something a leak because it counted past a threshold.

    Wait durations are not what you think

    The runtime prints , 15 minutes in a goroutine's header only once it has been blocked for at least a minute. A dump with no durations anywhere does not mean nothing is waiting — it means everything is recent. The report says so explicitly when it happens, because concluding “nothing is stuck” from their absence is the easiest wrong reading of a dump there is.

    Panic dumps

    A panic dump has a message before the first goroutine, and that message is the most important line in the file. It is kept and shown, and the goroutine in the running state is the one that panicked — everything else was merely alive at the time.

    How to get a dump

    From a running program: Ctrl-\ in its terminal, or kill -QUIT <pid>. Set GOTRACEBACK=all first if you want every goroutine rather than a summary. From inside a program: runtime.Stack(buf, true). From a crash: an unrecovered panic prints one on its way out.

    The other tools