Go 1.24 in 20 Minutes: What's New and Should You Upgrade

Go 1.24 in 20 Minutes: What's New and Should You Upgrade

On February 8, 2025, Go 1.24 was released, bringing new features, performance improvements, and tooling enhancements to the Go programming language. In this blog post, we’ll explore the key changes, their practical benefits, and whether upgrading is worth it. If you’re a Go developer or just curious about the language, take 20 minutes to dive into what Go 1.24 has in store. Links to official release notes and other resources are provided at the end.


1. Key Features of Go 1.24

Go 1.24 stays true to the language’s philosophy: simplicity, stability, and performance. The release includes improvements to the language, standard library, tools, and runtime. Let’s break down the highlights.

1.1. Full Support for Generic Type Aliases

Go 1.23 introduced experimental support for generic type aliases, and Go 1.24 makes this feature stable. You can now create aliases for generic types without restrictions, including using them across packages.

Example:

package main

import "fmt"

// Alias for a generic type
type MySlice[T any] []T

func main() {
    var s MySlice[int] = []int{1, 2, 3}
    fmt.Println(s) // [1 2 3]
}

Why it matters: Generic type aliases simplify refactoring and improve code readability, especially in large projects with heavy use of generics. They also ease integration with third-party libraries using generics.

Practical benefit: If you’re using generics, Go 1.24 lets you drop the experimental GOEXPERIMENT=aliastypeparams flag and use this feature reliably.


1.2. Performance Improvements for Maps

Go 1.24 optimizes hash tables (map), reducing overhead for read and write operations, particularly for large maps.

What’s changed?

  • Faster insertion and lookup operations.
  • Reduced memory usage for large maps.

Practical benefit: Applications that heavily use maps (e.g., for caching or data storage) will see performance gains without code changes. Benchmarks show up to 10–20% improvement in some cases.


1.3. FIPS 140: Cryptographic Security Support

Go 1.24 adds support for the FIPS 140 standard, critical for applications in regulated industries like finance and healthcare. The crypto standard library can now operate in a FIPS-compliant mode.

How it works?

  • The GOFIPS=1 flag enables a mode that uses only FIPS-compliant algorithms.
  • The crypto/rand package now leverages more robust randomness sources.

Practical benefit: If your project requires compliance with strict security standards, Go 1.24 simplifies certification. For others, it enhances the reliability of cryptographic operations.


1.4. New os.Root Type for Secure Directory Operations

The standard library introduces the os.Root type, which restricts file operations to a specific directory, protecting against accidental or malicious access outside the designated scope.

Example:

package main

import (
    "fmt"
    "os"
)

func main() {
    root, err := os.NewRoot("/tmp/safe")
    if err != nil {
        fmt.Println(err)
        return
    }
    f, err := root.Open("test.txt")
    if err != nil {
        fmt.Println(err)
        return
    }
    f.Close()
}

Why it matters: os.Root prevents path traversal attacks and simplifies writing secure file-handling code.

Practical benefit: Ideal for server applications processing user input related to the file system.


1.5. runtime.AddCleanup Replaces runtime.SetFinalizer

The new runtime.AddCleanup method replaces the deprecated runtime.SetFinalizer. It allows defining cleanup functions that run when an object is garbage-collected, with more predictable and safer behavior.

Example:

package main

import (
    "fmt"
    "runtime"
)

func main() {
    obj := new(int)
    runtime.AddCleanup(func() {
        fmt.Println("Object cleaned up")
    }, obj)
    obj = nil
    runtime.GC() // Force garbage collection for the example
}

Practical benefit: If you rely on SetFinalizer for resource management, switching to AddCleanup makes your code more robust, especially in libraries where object lifecycle control is critical.


1.6. Timing Attack Protection with subtle.WithDataIndependentTiming

For cryptographic operations on ARM64 architectures, Go 1.24 introduces subtle.WithDataIndependentTiming, which minimizes vulnerabilities related to timing analysis.

Example:

package main

import (
    "crypto/subtle"
    "fmt"
)

func main() {
    result := subtle.WithDataIndependentTiming(func() int {
        // Cryptographic operation
        return 42
    })
    fmt.Println(result)
}

Practical benefit: Developers building cryptographic libraries or timing-sensitive applications will benefit from enhanced security on ARM64 systems.


2. Tooling Improvements

Go 1.24 enhances developer tools, making building, testing, and deploying more efficient.

2.1. Improved Dependency Management

Go modules now support tool directives in go.mod to track executable dependencies, eliminating workarounds like adding tools to tools.go.

Example:

// go.mod
module example.com/myapp

go 1.24

tool github.com/golangci/golangci-lint@v1.54.0

How to use?

  • go get -tool github.com/golangci/golangci-lint adds the tool.
  • go tool golangci-lint runs it.

Practical benefit: Simplifies managing tools like linters or code generators, making dependencies more transparent.


2.2. Executable Caching

The go run and go tool commands now cache compiled binaries in GOCACHE, speeding up repeated executions but increasing cache size.

Practical benefit: Developers frequently using go run for testing will notice faster workflows. Monitor cache size on CI/CD systems.


2.3. Test Enhancements

A new test analyzer detects errors in test, fuzz, benchmark, and example declarations (e.g., incorrect signatures or invalid identifiers). It runs automatically with go test.

Example of a caught error:

func TestInvalid(t *testing.T) { // Error: incorrect signature
    t.Error("This test has a wrong signature")
}

Practical benefit: Improves test quality and prevents tests from being skipped due to coding errors.


3. Standard Library and Runtime Updates

Go 1.24 includes several smaller but valuable updates:

  • crypto/rand: Improved performance on Linux 6.11+ using getrandom via vDSO. On OpenBSD, it now uses arc4random_buf.
  • net/http: Fixed bugs and added updates for TLS servers with Encrypted Client Hello (ECH) support.
  • runtime.GOROOT: Deprecated; use go env GOROOT for accurate results.
  • telemetry: Go continues to collect opt-in anonymous telemetry. Enable with go telemetry on to help improve the language.

4. Platform Changes

  • WebAssembly: Expanded type support for go:wasmimport and go:wasmexport (adds bool, string, uintptr, etc.). Reduced initial memory size for WASM applications.
  • Linux: Requires kernel version 3.2 or newer.
  • Windows/ARM: The 32-bit port is marked as broken (see issue #70705).

Practical benefit: WebAssembly developers will enjoy more compact and flexible applications. Verify compatibility if using older Linux versions or Windows/ARM.


5. Should You Upgrade?

Pros of Upgrading:

  1. Performance: Optimized map and crypto/rand provide gains without code changes.
  2. Security: FIPS 140 and os.Root enhance application robustness.
  3. Tooling: Improved dependency management and caching streamline development.
  4. Generics: Full generic type alias support simplifies working with generic types.
  5. Future-proofing: Go 1.25 is on the horizon, and upgrading to 1.24 prepares your project.

Cons and Risks:

  1. Cache Size: Binary caching increases GOCACHE storage needs.
  2. Deprecated APIs: Migrating from runtime.SetFinalizer to runtime.AddCleanup or runtime.GOROOT to go env GOROOT requires refactoring.
  3. Platform Constraints: Ensure your systems meet new requirements (e.g., Linux 3.2+).

Recommendations:

  • Upgrade if: You use generics, work with cryptography, target WebAssembly, or want performance boosts.
  • Hold off if: Your project relies on older Linux versions, Windows/ARM, or you’re not ready to refactor deprecated APIs.
  • Testing: Run tests with Go 1.24 before upgrading (use GOTOOLCHAIN=go1.24.0 for validation).

6. How to Upgrade?

  1. Download Go 1.24: Get binaries from go.dev or use a package manager.
  2. Check Dependencies: Run go mod tidy to ensure package compatibility.
  3. Test: Execute go test ./... and verify CI/CD pipelines.
  4. Deploy: Confirm your environment (servers, containers) supports Go 1.24.

Update go.mod:

go 1.24

7. Conclusion

Go 1.24 is an evolutionary release that strengthens the language’s position in performance, security, and developer experience. Full generic type alias support, map optimizations, new cryptographic features, and tooling improvements make it a compelling upgrade for most projects. However, verify platform compatibility and test thoroughly before migrating.

For a deeper dive, check the official release notes. For an interactive look at the changes, explore this community resource by @ohmypy.

What do you think? Are you planning to upgrade to Go 1.24? Share your thoughts in the comments!


Resources:

DigitalOcean Referral Badge