NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
Go modules · #61 by repository stars
Last release 9 days ago
25 Sep 2026
Ships on a steady schedule
a new release about every 2 weeks
Rarely documented
notes for 6 of 48 stable releases
Nothing withdrawn
no release was ever pulled
5 years old
1021 releases · first in 2022
One column per quarter.
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
🔄 Breaking Changes (With Backward Compatibility)
We are excited to announce the release of go-zero v1.9.3! This release brings several important enhancements and bug fixes that improve the framework's reliability, performance, and alignment with industry best practices.
Contributor: @zhoushuguang
A new consistent hash load balancer has been added to the zRPC package, enabling session affinity for gRPC services.
Key Features:
core/hash/ConsistentHash implementationUsage Example:
// Set hash key in context
ctx := zrpc.SetHashKey(ctx, "user_123")
// Requests with the same key will be routed to the same backend
resp, err := client.SomeMethod(ctx, req)Configuration:
c := zrpc.RpcClientConf{
Endpoints: []string{"localhost:8080", "localhost:8081"},
BalancerName: "consistent_hash", // Use consistent hash balancer
}Benefits:
Contributor: @kevwan
Fixed an issue where OpenTelemetry trace propagation headers were not being properly forwarded through the gateway to upstream gRPC services, breaking distributed tracing.
Problem:
The gateway was not forwarding critical W3C Trace Context headers (traceparent, tracestate, baggage) to gRPC metadata, causing trace context to be lost at the gateway boundary.
Solution:
ProcessHeaders function to forward trace propagation headersImpact:
Technical Details:
// Trace headers now properly forwarded
var traceHeaders = map[string]bool{
"traceparent": true, // W3C Trace Context
"tracestate": true, // Additional trace state
"baggage": true, // W3C Baggage propagation
}Contributor: @kevwan
Problem:
When running multiple services (e.g., REST + RPC) in the same process, the trace agent could be initialized multiple times, potentially causing resource leaks or unexpected behavior.
Solution:
sync.Once to ensure trace agent is initialized only onceprometheus.StartAgent and logx.SetUpsync.OnceFunc for shutdown to prevent double cleanupCode Changes:
var (
once sync.Once
shutdownOnceFn = sync.OnceFunc(func() {
if tp != nil {
_ = tp.Shutdown(context.Background())
}
})
)
func StartAgent(c Config) {
if c.Disabled {
return
}
once.Do(func() {
if err := startAgent(c); err != nil {
logx.Error(err)
}
})
}Benefits:
Contributor: @lerity-yao (first contribution! 🎊)
Problem:
When scanning database results into struct fields with pointer types, zero values (0, false, empty string) were not being properly distinguished from NULL values. This caused nil pointers to be set to zero values incorrectly.
Solution:
Enhanced the getValueInterface function to properly initialize nil pointers before scanning, ensuring the SQL driver can correctly populate them with zero or non-zero values.
Code Changes:
func getValueInterface(value reflect.Value) (any, error) {
if !value.CanAddr() || !value.Addr().CanInterface() {
return nil, ErrNotReadableValue
}
// Initialize nil pointer before scanning
if value.Kind() == reflect.Pointer && value.IsNil() {
baseValueType := mapping.Deref(value.Type())
value.Set(reflect.New(baseValueType))
}
return value.Addr().Interface(), nil
}Impact:
type User struct {
Name string `db:"name"` // Always set
Age *int `db:"age"` // Can distinguish NULL vs 0
Active *bool `db:"active"` // Can distinguish NULL vs false
}
// Before: age=0 and age=NULL both resulted in nil pointer
// After: age=0 → *int(0), age=NULL → nil pointer ✓Benefits:
Contributor: @kevwan
Motivation:
Aligned with gRPC official best practices which discourage blocking dials.
Change:
// zrpc/config.go
type RpcClientConf struct {
// Before: NonBlock bool `json:",optional"`
// After:
NonBlock bool `json:",default=true"` // Now defaults to true
}Why This Matters:
grpc.WithBlock() is an anti-patternMigration Guide:
For most users, no action required - the new default is the recommended behavior.
If you explicitly need blocking behavior (not recommended):
// Option 1: Configuration
c := zrpc.RpcClientConf{
NonBlock: false, // Explicit blocking
}
// Option 2: Client option (deprecated)
client := zrpc.MustNewClient(c, zrpc.WithBlock())Backward Compatibility:
NonBlock: false continue to workWithBlock() option available (marked deprecated)NonBlock: trueDocumentation:
See GRPC_NONBLOCK_CHANGE.md for detailed migration guide and rationale.
We're thrilled to welcome new contributors to the go-zero community! 🎉
Thank you for your contributions! We look forward to your continued involvement in the project.
go get -u github.com/zeromicro/go-zero@v1.9.3# Update go.mod
go get -u github.com/zeromicro/go-zero@v1.9.3
go mod tidyzrpc/internal/balancer/consistenthash)SetHashKey() and GetHashKey()sync.Once patterngetValueInterface() with nil pointer initializationsql.Null* typesWithBlock() option for compatibilitySpecial thanks to all contributors, issue reporters, and community members who made this release possible. Your feedback and contributions continue to make go-zero better!
If you encounter any issues or have suggestions for future releases, please:
Happy coding with go-zero! 🚀
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →