Go version
go version go1.27.0 linux/amd64
Output of go env in your module/workspace:
GOARCH='amd64'
GOOS='linux'
GOVERSION='go1.27.0'
GOTOOLCHAIN='go1.27.0'
GOEXPERIMENT=''
GOAMD64='v1'
CGO_ENABLED='1'
(Other values redacted)
What did you do?
I read @lemire's tweet "The new Go JSON API: twice as fast, or 1.5x slower?" and replicated the benchmarks on macOS and on Linux.
Using benchstat on Lemire's benchmark output files when marshaling an array of 10,000 small structs:
# macOS arm64 (Apple M4 Max)
│ legacy (nojsonv2) │ Go 1.27 (v1 API) │ Go 1.27 (v2 API) │
│ sec/op │ sec/op vs base │ sec/op vs base │
MarshalRecords (10k) 1.633m ± 1% 2.477m ± 2% +51.73% (p=0.000 n=8) 2.486m ± 2% +52.30% (p=0.000 n=8)
A 52% speed regression on MarshalRecords is what Lemire observed and shared.
Note: I used the AI agent Antigravity for the tasks described below.
git clone https://github.com/lemire/Code-used-on-Daniel-Lemire-s-blog.git repo
cd repo/2026/08/29
mkdir -p testdata
curl -fsSL -o testdata/twitter.json "https://raw.githubusercontent.com/simdjson/simdjson/master/jsonexamples/twitter.json"
curl -fsSL -o testdata/canada.json "https://raw.githubusercontent.com/miloyip/nativejson-benchmark/master/data/canada.json"
curl -fsSL -o testdata/citm_catalog.json "https://raw.githubusercontent.com/simdjson/simdjson/master/jsonexamples/citm_catalog.json"
GOTOOLCHAIN=go1.27.0 ./run.sh
benchstat results/$(hostname -s)-legacy.txt results/$(hostname -s)-v1v2.txt
What did you see happen?
A 40% regression on my MacBook M4:
│ Legacy (Base) │ Go 1.27 json │ Go 1.27 jsonv2 │
│ sec/op │ sec/op vs base │ sec/op vs base │
MarshalRecords 1.728ms │ 2.419ms +40.04% (p=0.008)│ 2.420ms +40.09% (p=0.008)│
A 102% regression on a Linux VM:
# Linux x86_64 (Intel Xeon @ 2.20GHz)
│ legacy (nojsonv2) │ Go 1.27 (v1 API) │ Go 1.27 (v2 API) │
│ sec/op │ sec/op vs base │ sec/op vs base │
MarshalRecords (10k) 5.826m ± 3% 11.763m ±16% +101.90% (p=0.000 n=8) 12.062m ± 7% +107.03% (p=0.000 n=8)
What did you expect to see?
Marshaling a slice of typed structs seems to have regressed significantly in Go 1.27 compared to the legacy implementation (GOEXPERIMENT=nojsonv2).
The new v2 engine emits structured tokens through jsontext.Encoder. For dense struct slices (e.g. 10,000 items of 6 fields), the overhead of per-token state machine, namespace tracking, depth validation, and BeginObject/EndObject transitions, is large.
Go version
go version go1.27.0 linux/amd64
Output of
go envin your module/workspace:What did you do?
I read @lemire's tweet "The new Go JSON API: twice as fast, or 1.5x slower?" and replicated the benchmarks on macOS and on Linux.
Using benchstat on Lemire's benchmark output files when marshaling an array of 10,000 small structs:
A 52% speed regression on MarshalRecords is what Lemire observed and shared.
Note: I used the AI agent Antigravity for the tasks described below.
What did you see happen?
A 40% regression on my MacBook M4:
A 102% regression on a Linux VM:
What did you expect to see?
Marshaling a slice of typed structs seems to have regressed significantly in Go 1.27 compared to the legacy implementation (GOEXPERIMENT=nojsonv2).
The new v2 engine emits structured tokens through jsontext.Encoder. For dense struct slices (e.g. 10,000 items of 6 fields), the overhead of per-token state machine, namespace tracking, depth validation, and BeginObject/EndObject transitions, is large.