I did not find time to finish my notes about Go v1.25 before release of Go v1.26, so let us handle both at once.

Go v1.25 did bring some convenient tooling, but the language specification stays the same. However, Go v1.26 brought after something new to language specification — extension of new built-in function, which might be quite handy.

The both worked hard on introducing so-called Green Tea garbage collector.


Go v1.25

Go v1.25 arrive in August 2025. As said before, it did not bring any core language change. It was more about toolchain, runtime and libraries being tuned.

Bootstrap seemed to be the same as for v1.24. As far as I assume, it requires Go v1.22.6 or later for bootstrap.

Release notes are here. Later, interactive tour have been found useful.

Go v1.25: The useful

Brand new testing/synctest package brings isolated bubbles with virtualized time. So, any calls to time.Sleep are rewind and does not take precious time of your unit tests. Time in each bubble is set to 2000-01-01T00:00Z, and it advances when every goroutine in that bubble is blocked.

Already used it and I like it as it works nicely for simple use. Be careful, as it does not work well with tickers AFAIK.

The default behavior of the GOMAXPROCS has changed, so it should be container-aware. E.g., on Linux GO runtime considers CPU bandwidth limit (corresponding to “CPU limit” option) of the cgroup containing the process, if any.

Truly important not just for k8s.

Fix of bug with delayed nil pointer check (e.g. accessing f.Name() before error check after os.Open).

Better to know about bugs as soon as possible. It was introduced by Go v1.21…

Better performing implementation of standard JSON package might be enabled by GOEXPERIMENT=jsonv2. The ordinary encoding/json standard package is replaced by encoding/json/v2 on the background with the same interface but different error messages.

JSON processing was pretty slow, so better performance in that often used encoding is nice.

unicode.CategoryAliases map introduce aliases like Letter for category L. New categories Cn (unassigned codepoints; already included in C category) and LC (cased letters).

Better handling of Unicode code points.

Go v1.25: The Perhaps-important

New ignore directive in go.mod can be used to specify directories (with all content recursively) ignored by the go command when using patterns like ./.... However, they will still be included in zip files.

It might be useful in some situations.

Each test can be also extended with extra information (e.g., ID of bug task) via t.Attr("task", "BUG-42") called in test.

It might sound unnecessary, but extra information about test for JSON format might be used.

go doc -http starts the server showing documentation and opens it in browser.

Quick check of documentation in your web browser.

go version -m -json prints to output JSON with embedded version information, so it might be processed (e.g., by jq commandline tool).

Finally standardized way for version information of Go applications for CI/CD pipelines.

Experimental version of the Green Tea garbage collector with 10—40 % reduction of GC overhead. It might be enabled by GOEXPERIMENT=greenteagc.

Big improvement in GC as far as I have understood it.

Trace flight recorder based on ring buffer can be used for write trace of a few last seconds into the file.

Might be viable for inspection of behavior that lead to application crash.

sync.WaitGroup has new wg.Go method introducing a common and convenient pattern of creating and counting currently running goroutines. One simply does not need to handle wg.Add and deferred wg.Done by own, but only as far as the given function does not panic.

We all used to know how to work with sync.WaitGroups, but similar approach can be seen as a good step for code standardisation.

HTTP server can be extended by CSRF protection via new type http.CrossOriginProtection.

Based on sec-fetch-site header and comparison of hostname from origin header (skipped if missing). Mind that wildcard subdomains are considered as trusted, so they have to be all added as trusted origin. Also GET, HEAD, and OPTIONS methods are not checked for CSRF.

Unhandled re-panicked panic is reported on single line like panic: PANIC [recovered, repanicked] instead of on two separate lines as originally.

Small, but nice convenient.

One can extract type-asserted value back from reflective value (got by reflect.ValueOf) when using generic function reflect.TypeAssert[T]. This approach avoids any extra memory allocations (as one does not need to box it in some kind of interface).

Go v1.25: The Do-not-care

go build -asan defaults to report the output of leak detection algorithm if any memory allocated by C us not released while not being referenced by any other memory allocated by both Go and C. Reporting might be disabled by setting ASAN_OPTIONS=detect_leaks=0.

Important for those working tightly with C.

The unique package now reclaims interned values more eagerly, more efficiently, and in parallel. As a consequence, applications using Make are better handling situations when lots of truly unique values are interned. Also, less stress on GC is needed when releasing interned values.

Important for anyone who needs to intern a lot of data.

Bigger changes were introduced by os standard package. Less blocking of OS threads, deadline methods support, NewFile support handles opened for asynchronous I/O, more methods on os.Root type, and stuff around new os/fs.ReadLinkFS interface.

It is a bigger topic, so not sure how much useful it might be.

And a lot of minor stuff in standard packages. As usually, cryptography touched a lot, but also native Go parser.


Go v1.26

Go v1.26 arrive in February 2026. It brings also something nice for language specification.

Bootstrap requires Go v1.24.6 or later.

Release notes are here. A great source is also interactive tour.

Go v1.26: The useful

Old good new built-in function returning a pointer to newly created variable, can work with expression. Until now, it worked just with data type.

One can call any function and get pointer to the result of function’s return value. This might simplify code and one can get rid of common utility function like ptr.To.

Lifted restriction on a generic type, so it can refer to itself in its type parameter.

type Adder[A Adder[A]] interface {
    Add(A) A
}

func algo[A Adder[A]](x, y A) A {
    return x.Add(y)
}

Nice code simplification can be brought by generic function errors.AsType (as generic counterpart to errors.As).

One does not have to introduce pointer variable to the error type upfront, and it seems that also type switch might be used for processing of multiple error types. That it super convenient for a developer.

The Green Tea GC already replaced the original GC implementation.

As said before, 10—40 % lower overhead on GC is a nice benefit.

Introduction of buffer.Peak to check if/what bytes are waiting next in a buffer without consuming them.

They let us just shortly peak at bytes. More powerful parser can be built.

No need to replace fmt.Errorf with no placeholders for errors.New, as the former one if optimized on allocations. Slight overhead is still included, but it is not that high.

One can be using just fmt.Errorf by default.

Now, log/slog offers multiHandler for sending logs to multiple handlers (outputs).

Perhaps the last important thing missing for log/slog standard package.

Go v1.26: The Perhaps-important

go fix revamped to be a home of Go modernizers.

Not yet sure, shat it means, but it might help with adoption of new language constructs. Hopefully, it will not be too much stubborn.

On 64-bit platforms, the runtime now randomizes the heap base address at startup.

A step closer for more secure applications. When they disable GOEXPERIMENT=norandomizedheapbase64, debugging might get harder.

New pprof goroutineleak profile (see /debug/pprof/goroutineleak endpoint) can be enabled by GOEXPERIMENT=goroutineleakprofile. A leaked goroutine is blocked by some concurrent primitive (e.g., channel or sync.Mutex) that cannot possibly become unblocked.

It might be a good tool to see, that one overlooked high-level design issue.

New experimental simd/archsimd package enabled by GOEXPERIMENT=simd. It provides access to platform-specific SIMD operations.

A big step for parallel computations.

Experimental runtime/secret package provides a facility for securely erasing temporaries used in code that manipulates secret information. It might be enabled by GOEXPERIMENT=runtimesecret and usage of secret.Do.

Security is usually solved ex-post, but one should be aware of this new package being introduced.

Go v1.26: The Do-not-care

The baseline runtime overhead of cgo calls and syscalls has been reduced by ~30%.

Not working with cgo that much. Definitely not directly. But in syscalls, it might bring some improvement.

go tool doc was completely replaced by go doc.

I did not know about go tool doc to be honest.

Yet again, standard crypto packages are evolving. This time, some of offered algorithms ignore io.Reader parameter (while always using crypto/internal/sysrand.Read), so nil might be often passed. Also, brand-new testing.cryptotest package was introduced.

Good to know, but currently not working that much with crypto package.

Standard net/netip.Prefix.Compare method can be used for comparison and sorting of IP subnets (invalid-first, address family, network IP, prefix length, host IP).

Good to know that it exists.


<
Previous Post
Elder Futhark
>
Blog Archive
Archive of all previous blog posts