SupercovCompare
← All comparisons

Go · Comparison

Go covermode: set vs count vs atomic

All three modes report the same percentage. Use set for coverage and atomic for counts from goroutines: count recorded 5,348 of 8,002 calls.

Which covermode should you use?

Use the default, set, when you want a coverage percentage: all three modes report the same percentage. Use atomic when you want counts and the code runs in goroutines. go test -race picks atomic for you. Use count only for code that runs in one goroutine.

What each mode records

From go help testflag:

set: bool: does this statement run?
count: int: how many times does this statement run?
atomic: int: count, but correct in multithreaded tests;
        significantly more expensive.
go test -covermode=atomic -coverprofile=cover.out ./...
go tool cover -html=cover.out

-covermode turns coverage on by itself, so -cover is not needed with it.

Same tests, three profiles

One function and three tests on Go 1.27.1. One test calls the function 8,000 times from eight goroutines, and the other two call it once each: 8,002 calls.

ModeCoverageCount for the first statement
set100.0%1
count100.0%5,348
atomic100.0%8,002

count lost a third of the calls. Goroutines that update the same counter at the same moment overwrite each other. Five more runs gave between 5,334 and 7,618, never 8,002.

The percentage is right in every mode. Only the counts are wrong, which matters if you read them as a heat map in go tool cover -html.

With the race detector

go test -race -cover uses atomic without being asked; the profile starts with mode: atomic. Asking for another mode fails:

-covermode must be "atomic", not "set", when -race is enabled

If your CI runs tests with -race, leave -covermode out.

What no mode records

All three count statements. None records which way an if went, or which test ran a statement. The function above is:

if signedIn && !expired {
	return true
}
return false

Every mode reports 100%, and no test tries a signed-in session that has expired.

What Supercov adds

npx supercov -- go test ./...
npx supercov runs latest gaps

Supercov runs your own go test command on Go 1.22 or newer. On the same tests it reported 4/4 lines, 4/4 branches and 1/2 MC/DC conditions, and named !expired as the condition no test showed changing the result. Coverage is recorded per test.

For more Go tools, see Go test coverage: go test -cover, gomcdc and Supercov.

Example evidence: fixture source, commands and recorded results (JSON). Measured October 12, 2026 with Supercov 4.3.0. These small examples are not a performance benchmark or a general conformance test.