# 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. Web page: https://supercov.com/compare/go-covermode · Published 2026-10-12 All Supercov pages for agents: https://supercov.com/llms.txt · Full text: https://supercov.com/llms-full.txt ## 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`: ```text 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. ``` ```sh 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. | Mode | Coverage | Count for the first statement | | --- | --- | --- | | `set` | 100.0% | 1 | | `count` | 100.0% | 5,348 | | `atomic` | 100.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: ```text -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: ```go 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 ```sh 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](https://supercov.com/compare/go-test-coverage.md). Example evidence: [fixture source, commands and recorded results (JSON)](https://supercov.com/downloads/tool-comparisons-2026-10-12.json). Measured October 12, 2026 with Supercov 4.3.0. These small examples are not a performance benchmark or a general conformance test.