v2.10 speeds up encoding by up to 2.88× and decoding by up to 1.87× with zero memory regressions (B/op, allocs/op), reduces memory use, adds the toindefarray struct tag option, and fixes bugs. The Contributing Guidelines, Security Policy, and templates were extensively updated.
Encoding sorted nested maps of dynamic JSON-like data drops from 70 allocs/op to 1 and from 7.2 KiB/op to 4.0 KiB/op in the benchmarks below. Encoding time.Time, big.Int, Tag and Marshaler values, and decoding into time.Time, big.Int and Tag, use 1 to 2 fewer allocs/op (20% to 50% fewer).
These gains come without using Go's unsafe package. Performance in user apps depends on configuration and data.
Tests were refactored and coverage increased to 97.7%. Fuzz tests (not yet public) were also extended.
Performance and Benchmarks
Benchmarks ran with Go 1.26.10 on linux/amd64 (benchstat n=10, p=0.000):
- CBOR Speedup by Data Type: groups of different benchmarks summarized per row
- CBOR Encoding Reflection-Free Speedup: dynamic JSON-like data types and common types
CBOR Speedup by Data Type
| Decoding | Speedup | ΔSec/op |
|---|---|---|
| Single values (bool, int, float, byte string, text string) | 1.10× to 1.51×¹ | -8.87% to -33.92%¹ |
| Epoch time, bignum, other tags | 1.18× to 1.64× | -15.33% to -38.91% |
| Arrays and maps to non-struct | 1.33× to 1.87× | -24.63% to -46.49% |
| Arrays and maps to structs | 1.06× to 1.52× | -5.46% to -34.40% |
| Real-world (COSE, CWT, SenML, WebAuthn) | 1.35× to 1.64× | -26.06% to -39.19% |
¹ -60.64% (2.54× speedup) when decoding into a named []byte type that has methods.
| Encoding | Speedup | ΔSec/op |
|---|---|---|
| Single values (bool, int, float, byte slice, string) | 1.32× to 1.55× | -24.49% to -35.41% |
| time.Time, big.Int, Tag, Marshaler² | 1.15× to 1.63× | -12.94% to -38.84% |
| Slices and maps | 1.35× to 2.88× | -25.97% to -65.26% |
| Structs | 1.57× to 2.17× | -36.37% to -53.96% |
| Structs with omitempty fields | 0.95׳ to 1.35× | +5.01%³ to -25.96% |
| Real-world (COSE, CWT, SenML, WebAuthn) | 1.12× to 1.33× | -10.66% to -24.77% |
² For addressable values (reached through a pointer, struct field, slice element or map value).
³ Only when every field is omitempty and empty: 7.6 ns slower for a 32-field struct, 2.37 ns faster for an 8-field struct. This is the only performance regression in all 215 benchmarks.
CBOR Encoding Reflection-Free Speedup
PR #870 optimized common types: int, int64, uint, uint64, float64, bool, string, nil, []byte, []any, map[any]any, map[string]any, and map[string]string.
| Marshal Benchmark v2.9.6 → v2.10 | Speedup | Time ΔSec/op | Memory ΔB/op | Memory ΔAllocs/op |
|---|---|---|---|---|
| []any | 2.50× | -607.5 ns (-60.03%) | - | - |
| map[string]any | 2.60× | -821.9 ns (-61.47%) | - | - |
| map[string]string | 2.59× | -335.9 ns (-61.34%) | - | - |
| nested_map[any]any | 2.88× | -16.542 µs (-65.26%) | - | - |
| nested_map[string]any | 2.78× | -14.201 µs (-64.01%) | - | - |
| nested_map[any]any, bw_lex | 2.53× | -22.36 µs (-60.54%) | -3314 (-44.72%) | -69 (-98.57%) |
| nested_map[string]any, bw_lex | 2.41× | -19.52 µs (-58.54%) | -3323 (-44.79%) | -69 (-98.57%) |
- bw_lex =
SortBytewiseLexical. Memory improvements are from #774 and #860.
Upgrade Notes
- Go 1.24 or newer is required (#773).
- Pointer-receiver marshal methods (user-implemented methods) are called on the original value instead of a copy when the value is addressable (#866).
Marshalconfigured to useTagsForbiddenreturns an error for abig.Intoutside [-2^64, 2^64-1], andEncModecreation returns an error for settings that would emit tags ifTagsForbiddenis also set (#868).Decoderadvances past well-formed data items rejected byDecOptionsvalue or serialization restrictions (e.g.NaN,IndefLength), andSkipskips them without an error (#872).Marshalconfigured to emit text-based time returns an error fortime.Timeoutside RFC 3339 limits (#873).
TinyGo (experimental)
TinyGo support for v2.10.0 is available in tag tinygo-beta/v2.10.0-tinygo0.42 (branch feature/cbor-tinygo-beta). It requires TinyGo 0.42.0 or newer. It is experimental and not fuzz tested. For details, see TinyGo (https://github.com/fxamacker/cbor#tinygo) in the README.
What's Changed
⭐ Features
- feat: add toindefarray struct tag option for CBOR indefinite-length arrays by @tdnguyenND in https://github.com/fxamacker/cbor/pull/770
🚀 Optimizations
- Optimize encoding speed primarily for slices, maps, and structs by @fxamacker in https://github.com/fxamacker/cbor/pull/806
- Reduce decoding time up to 17% for all CBOR data types by @fxamacker in https://github.com/fxamacker/cbor/pull/807
- Reduce decoding time by inlining well-formedness checks by @fxamacker in https://github.com/fxamacker/cbor/pull/810
- Optimize decoding CBOR byte string by @fxamacker in https://github.com/fxamacker/cbor/pull/811
- Optimize decoding CBOR text string by up to 16% by @fxamacker in https://github.com/fxamacker/cbor/pull/812
- Reduce allocs and bound memory of keyValue pool by @fxamacker in https://github.com/fxamacker/cbor/pull/860
- Reduce allocations when encoding addressable values by @fxamacker in https://github.com/fxamacker/cbor/pull/866
- Add reflection-free encoding for common types (up to 2.8x faster) by @fxamacker in https://github.com/fxamacker/cbor/pull/870
- Reduce allocs to speed up time.Time, Tag, and big.Int by @fxamacker in https://github.com/fxamacker/cbor/pull/886
🛠 Improvements
- Refactor to use slices.SortFunc (Go 1.21+) by @fxamacker in https://github.com/fxamacker/cbor/pull/774
- Update to require go 1.24 and modernize code by @fxamacker in https://github.com/fxamacker/cbor/pull/773
- Small refactor and cleanups by @fxamacker in https://github.com/fxamacker/cbor/pull/815
- Refactor encoding functions to prepare for reflection-free path by @fxamacker in https://github.com/fxamacker/cbor/pull/861
- Refactor struct field sorter to use slices.SortFunc by @fxamacker in https://github.com/fxamacker/cbor/pull/877
🐞 Bug Fixes
- Enforce TagsForbidden for bignums and ByteSliceLaterFormat by @fxamacker in https://github.com/fxamacker/cbor/pull/868
- Advance Decoder past restricted CBOR data items by @fxamacker in https://github.com/fxamacker/cbor/pull/872
- Reject marshaling out-of-range time.Time to RFC 3339 by @fxamacker in https://github.com/fxamacker/cbor/pull/873
- Fix some error messages returned by EncMode() and DecMode() by @fxamacker in https://github.com/fxamacker/cbor/pull/883
- Fix float range check when decoding Unix time by @fxamacker in https://github.com/fxamacker/cbor/pull/889
🧪 Testing
- Shorten benchmark names by @fxamacker in https://github.com/fxamacker/cbor/pull/816
- Move tests and helpers to new files by @fxamacker in https://github.com/fxamacker/cbor/pull/878
- Add checkMarshal test helpers by @fxamacker in https://github.com/fxamacker/cbor/pull/879
- Add checkUnmarshal test helpers by @fxamacker in https://github.com/fxamacker/cbor/pull/881
- Add test helpers for modes, tags, and round trips by @fxamacker in https://github.com/fxamacker/cbor/pull/884
- Refactor invalid option tests to table-driven tests by @fxamacker in https://github.com/fxamacker/cbor/pull/885
- Add checkNoError and checkErrorCase test helpers by @fxamacker in https://github.com/fxamacker/cbor/pull/887
- Standardize test failure messages and fix several test bugs by @fxamacker in https://github.com/fxamacker/cbor/pull/888
- Add more benchmarks by @fxamacker in https://github.com/fxamacker/cbor/pull/891
📖 Documentation
- Update comments to use newer terminology by @fxamacker in https://github.com/fxamacker/cbor/pull/779
- Update TinyGo section in README.md by @fxamacker in https://github.com/fxamacker/cbor/pull/793
- Update doc.go and README.md for v2.10.0 by @fxamacker in https://github.com/fxamacker/cbor/pull/890
📖 Contributing Guidelines, Security Policy, and Templates
- Update PR template to clarify approval requirement by @fxamacker in https://github.com/fxamacker/cbor/pull/849
- Rewrite security policy and reporting guidelines by @fxamacker in https://github.com/fxamacker/cbor/pull/864
- Rewrite PR template to reduce risks from AI and uncoordinated PRs by @fxamacker in https://github.com/fxamacker/cbor/pull/865
- Rewrite bug report form to reduce security risks by @fxamacker in https://github.com/fxamacker/cbor/pull/867
- Rewrite feature request form to help triage and reduce risks by @fxamacker in https://github.com/fxamacker/cbor/pull/869
- Replace docs issue template with an issue form by @fxamacker in https://github.com/fxamacker/cbor/pull/874
- Update security policy, PR template, and issue forms by @fxamacker in https://github.com/fxamacker/cbor/pull/875
- Update CONTRIBUTING.md to reduce risks by @fxamacker in https://github.com/fxamacker/cbor/pull/862
- Improve issue forms for triage and previews by @fxamacker in https://github.com/fxamacker/cbor/pull/880
CI / GitHub Actions
🔎 Details
- Bump govulncheck from v1.1.4 to v1.3.0 by @fxamacker in https://github.com/fxamacker/cbor/pull/772
- Add more linters to .golangci.yml and lint by @fxamacker in https://github.com/fxamacker/cbor/pull/775
- Update CodeQL actions to v4.36.3 and add CodeQL group to dependabot.yml by @fxamacker in https://github.com/fxamacker/cbor/pull/790
- Bump golangci-lint to v2.13.2 and lint by @fxamacker in https://github.com/fxamacker/cbor/pull/814
- Update CI to add Go 1.27 and bump govulncheck by @fxamacker in https://github.com/fxamacker/cbor/pull/852
- Change Go version for golangci-lint 2.13.2 by @fxamacker in https://github.com/fxamacker/cbor/pull/863
Other Changes
- Use a security-hardened .gitignore by @fxamacker in https://github.com/fxamacker/cbor/pull/826
Ported from release-2.9
Already released in v2.9.3 through v2.9.6.
🔎 Details
- Port PR 803 to master branch by @fxamacker in https://github.com/fxamacker/cbor/pull/804
- Port #817 from v2.9.4 to master by @fxamacker in https://github.com/fxamacker/cbor/pull/818
- Port #821 from release-2.9 to master by @fxamacker in https://github.com/fxamacker/cbor/pull/822
- Port #827 from release-2.9 to master by @fxamacker in https://github.com/fxamacker/cbor/pull/839
- Port #828 from release-2.9 to master by @fxamacker in https://github.com/fxamacker/cbor/pull/840
- Port #829 from release-2.9 to master by @fxamacker in https://github.com/fxamacker/cbor/pull/841
- Port #831 from release-2.9 to master by @fxamacker in https://github.com/fxamacker/cbor/pull/842
- Port #834 from release-2.9 to master by @fxamacker in https://github.com/fxamacker/cbor/pull/843
- Port #835 from release-2.9 to master by @fxamacker in https://github.com/fxamacker/cbor/pull/844
- Port #833 from release-2.9 to master by @fxamacker in https://github.com/fxamacker/cbor/pull/845
- Port #837 from release-2.9 to master by @fxamacker in https://github.com/fxamacker/cbor/pull/846
- Port #838 from release-2.9 to master by @fxamacker in https://github.com/fxamacker/cbor/pull/850
- Port #851 from release-2.9 to master by @fxamacker in https://github.com/fxamacker/cbor/pull/853
- Port #854 from release-2.9 to master by @fxamacker in https://github.com/fxamacker/cbor/pull/856
- Port #857 from release-2.9 to master by @fxamacker in https://github.com/fxamacker/cbor/pull/858
- Port #855 from v2.9.6 to master by @fxamacker in https://github.com/fxamacker/cbor/pull/859
Dependabot Updates
🔎 Details
- Bump github/codeql-action from 4.35.2 to 4.35.4 by @dependabot[bot] in https://github.com/fxamacker/cbor/pull/771
- Bump github/codeql-action from 4.35.4 to 4.35.5 by @dependabot[bot] in https://github.com/fxamacker/cbor/pull/776
- Bump github/codeql-action from 4.35.5 to 4.36.0 by @dependabot[bot] in https://github.com/fxamacker/cbor/pull/778
- Bump github/codeql-action from 4.36.0 to 4.36.2 by @dependabot[bot] in https://github.com/fxamacker/cbor/pull/781
- Bump actions/checkout from 6.0.2 to 7.0.0 by @dependabot[bot] in https://github.com/fxamacker/cbor/pull/783
- Bump actions/setup-go from 6.4.0 to 6.5.0 by @dependabot[bot] in https://github.com/fxamacker/cbor/pull/785
- Bump the codeql group with 3 updates by @dependabot[bot] in https://github.com/fxamacker/cbor/pull/791
- Bump the codeql group with 3 updates by @dependabot[bot] in https://github.com/fxamacker/cbor/pull/794
- Bump actions/setup-go from 6.5.0 to 7.0.0 by @dependabot[bot] in https://github.com/fxamacker/cbor/pull/795
- Bump the codeql group with 3 updates by @dependabot[bot] in https://github.com/fxamacker/cbor/pull/799
- Bump actions/checkout from 7.0.0 to 7.0.1 by @dependabot[bot] in https://github.com/fxamacker/cbor/pull/800
- Bump the codeql group with 3 updates by @dependabot[bot] in https://github.com/fxamacker/cbor/pull/801
- Bump the codeql group with 3 updates by @dependabot[bot] in https://github.com/fxamacker/cbor/pull/808
- Bump the codeql group across 1 directory with 3 updates by @dependabot[bot] in https://github.com/fxamacker/cbor/pull/813
- Bump the codeql group with 3 updates by @dependabot[bot] in https://github.com/fxamacker/cbor/pull/823
- Bump the codeql group with 3 updates by @dependabot[bot] in https://github.com/fxamacker/cbor/pull/836
- Bump the codeql group with 3 updates by @dependabot[bot] in https://github.com/fxamacker/cbor/pull/847
- Bump the codeql group with 3 updates by @dependabot[bot] in https://github.com/fxamacker/cbor/pull/871
- Bump the codeql group with 3 updates by @dependabot[bot] in https://github.com/fxamacker/cbor/pull/882
New Contributors
- @tdnguyenND made their first contribution in https://github.com/fxamacker/cbor/pull/770
Full Changelog: https://github.com/fxamacker/cbor/compare/v2.9.6...v2.10.0