Go 1.27 in practice: generic methods, goroutine leak profiles and a UUID package
A working developer's tour of the Go 1.27 release notes: generic methods, the goroutineleak profile, a standard uuid package, json v2 and go fix updates.

New Go releases tend to be quiet, and that is part of why people like the language. Go 1.27 keeps that character, but it does include a few changes you will notice in daily work. This is a tour of the ones that seem most useful, written from the official Go 1.27 release notes, with notes on what to check before you upgrade.
Generic methods
Until now, a Go type could have generic functions and generic types, but a method could not bring its own type parameters. You worked around it with a package-level function. In 1.27, according to the notes, "a method declaration may declare its own type parameters."
The standard library's own example is in math/rand/v2. There was already a generic function N that returns a random value of any integer type up to a limit. Now *Rand has an N method as well, so you can call it on a generator you own, instead of the shared global one.
Here is the shape of the feature in your own code:
type Store struct{ db *sql.DB }
// Get decodes a row into any type T the caller names.
func (s *Store) Get[T any](ctx context.Context, id string) (T, error) {
var out T
// ... query and decode into out
return out, nil
}
user, err := store.Get[User](ctx, "u_123")
Two limits are worth remembering. Methods declared on an interface still cannot have type parameters, and a generic method cannot be used to satisfy an interface method. So this is a convenience for concrete types, not a new way to build abstractions. If you were about to reach for it to model an "interface with generic methods", the notes say plainly that it will not work.
Two smaller language changes arrive alongside it. A struct literal key can now be any valid field selector, not only a top-level field name. And type inference for generic functions has been widened to every place where a generic function is assigned to, or converted to, a matching function type. Both remove small bits of ceremony.
A goroutine leak profile you can turn on
Leaked goroutines are one of the classic ways a Go service slowly gets heavier. Memory climbs, nothing crashes, and a restart hides it for a while.
Go 1.26 had a goroutineleak profile as an experiment. In 1.27 it is generally available in runtime/pprof, and over HTTP at /debug/pprof/goroutineleak if you already expose net/http/pprof. The experiment flag is gone.
The notes define a leak as a goroutine blocked on a concurrency primitive, such as a channel, mutex or condition variable, that can never be unblocked. The detection leans on the garbage collector. If the primitive is unreachable from any goroutine that could run, nobody can ever wake the blocked one, so it is reported.
Note
The notes state a limit: leaks can be missed when the blocking primitive is reachable through a global variable or through local variables of goroutines that are still runnable. A clean profile is good news, not a proof.
A typical leak the profile can catch looks like this:
func fetch(ctx context.Context, url string) (string, error) {
ch := make(chan string) // unbuffered
go func() { ch <- slowCall(url) }() // blocks forever if the caller left
select {
case v := <-ch:
return v, nil
case <-ctx.Done():
return "", ctx.Err()
}
}
If the context is cancelled first, nobody reads from ch, and the goroutine waits forever. The fix is a buffered channel of size one. Having a profile that names such goroutines turns an afternoon of guessing into a short list.
A uuid package in the standard library
The release notes say "the new uuid package generates and parses UUIDs." That is all the page says about it, so check the package documentation for the exact functions and versions it supports. For many projects this means one dependency less. Teams that use UUIDs as database keys or as idempotency keys will likely want to look at it first. Do not swap the dependency in a hurry: confirm that it produces the identifier version your schema and sort order assume.
JSON, now on the v2 implementation
encoding/json is now backed by the v2 implementation, and the new encoding/json/v2 and jsontext packages are available directly. For most programs the old API behaves as before, but this is the change I would test most carefully, because JSON sits on every boundary. The release notes mention an opt-out, GOEXPERIMENT=nojsonv2, and say it is expected to go away in a future release. Treat it as a short bridge while you find any differences in your own payloads, not as a setting to keep.
Smaller items that affect your workflow
go fixgains modernizers namedatomictypes,embedlit,slicesbackwardandunsafefuncs. Thefmtappendfanalyzer was removed, andwaitgroupwas renamedwaitgroupgo. Rungo fixon a clean branch and review the diff like any other change.go mod tidynow merges duplicaterequireblocks for modules that declarego 1.27or later, leaving at most one block for direct and one for indirect dependencies. Expect a one-time diff ingo.mod.go testruns thestdversionvet check by default, which flags use of standard library symbols newer than your module's Go version.- The old
asynctimerchansetting is gone, so channels created by thetimepackage are always unbuffered. - The notes say small allocations, under 80 bytes, can be up to 30% cheaper. Treat that as an upper bound and measure your own service.
A sensible upgrade path
- Read the notes top to bottom once. They are short.
- Bump the toolchain in a branch, build, and run your tests with the race detector.
- Run
go vetand read any newstdversionor printf findings. - If you handle a lot of JSON, replay recorded payloads through old and new builds and compare.
- Turn on the goroutine leak profile in staging and look at it after a load test.
- Only then change
go.modtogo 1.27, so the tidy and vet changes arrive as a separate, reviewable commit.
None of this is dramatic, which is the point. Generic methods will likely tidy a few APIs, the leak profile gives you a new place to look when memory creeps, and the rest is housekeeping that is cheap to do on a calm afternoon.


