Beyond `omitempty`: Understanding `omitzero` in Go 1.24
Preface In Go version 1.24, the encoding/json package introduced the omitzero tag, making the behavior of ignoring zero-value fields more explicit and customizable. This article provides a detailed explanation of how to use the omitzero tag. The omitzero Tag The omitzero tag is used to control which zero-value fields should be omitted when serializing Go objects into JSON. Unlike the omitempty tag, which omits empty-value fields, zero values and empty values, while similar, are not equivalent in Go. For example: For the time.Time type, the zero value is "0001-01-01T00:00:00Z", which is not considered an empty value. For a slice field like IntSlice []int, both [] and nil are considered empty values. Why Use omitzero Precise control: Explicitly omits zero-value fields, rather than empty-value fields. Custom control: By implementing the IsZero() bool method, you can define custom logic for determining a field’s zero value. Using the omitzero Tag package main import ( "encoding/json" "fmt" "time" ) type User struct { Name string `json:"name,omitzero"` Age int `json:"age,omitzero"` Hobbies []string `json:"hobbies,omitzero"` BornAt time.Time `json:"born_at,omitzero"` } func main() { user := User{ Name: "Leapcell", Age: 18, Hobbies: []string{}, } bytes, _ := json.MarshalIndent(user, "", " ") fmt.Println(string(bytes)) } Running string(bytes) will output the following JSON result: { "name": "Leapcell", "age": 18, "hobbies": [] } If the omitempty tag were used instead, the hobbies field would be omitted. Furthermore, even if born_at is a zero value, it would still be serialized as "born_at": "0001-01-01T00:00:00Z". By using the omitzero tag, we can more precisely control which fields are ignored, ensuring that only zero-value fields are excluded. The IsZero() bool Method The IsZero() bool method is used to customize the logic for determining whether a field is a zero value. If you want to change how a field’s zero value is determined, you can implement the IsZero method for that field. Here's an example: package main import ( "encoding/json" "fmt" "time" ) type Age int func (age *Age) IsZero() bool { return *age

Preface
In Go version 1.24, the encoding/json
package introduced the omitzero
tag, making the behavior of ignoring zero-value fields more explicit and customizable. This article provides a detailed explanation of how to use the omitzero
tag.
The omitzero
Tag
The omitzero
tag is used to control which zero-value fields should be omitted when serializing Go objects into JSON. Unlike the omitempty
tag, which omits empty-value fields, zero values and empty values, while similar, are not equivalent in Go. For example:
- For the
time.Time
type, the zero value is"0001-01-01T00:00:00Z"
, which is not considered an empty value. - For a slice field like
IntSlice []int
, both[]
andnil
are considered empty values.
Why Use omitzero
- Precise control: Explicitly omits zero-value fields, rather than empty-value fields.
-
Custom control: By implementing the
IsZero() bool
method, you can define custom logic for determining a field’s zero value.
Using the omitzero
Tag
package main
import (
"encoding/json"
"fmt"
"time"
)
type User struct {
Name string `json:"name,omitzero"`
Age int `json:"age,omitzero"`
Hobbies []string `json:"hobbies,omitzero"`
BornAt time.Time `json:"born_at,omitzero"`
}
func main() {
user := User{
Name: "Leapcell",
Age: 18,
Hobbies: []string{},
}
bytes, _ := json.MarshalIndent(user, "", " ")
fmt.Println(string(bytes))
}
Running string(bytes)
will output the following JSON result:
{
"name": "Leapcell",
"age": 18,
"hobbies": []
}
If the omitempty
tag were used instead, the hobbies
field would be omitted. Furthermore, even if born_at
is a zero value, it would still be serialized as "born_at": "0001-01-01T00:00:00Z"
. By using the omitzero
tag, we can more precisely control which fields are ignored, ensuring that only zero-value fields are excluded.
The IsZero() bool
Method
The IsZero() bool
method is used to customize the logic for determining whether a field is a zero value. If you want to change how a field’s zero value is determined, you can implement the IsZero
method for that field. Here's an example:
package main
import (
"encoding/json"
"fmt"
"time"
)
type Age int
func (age *Age) IsZero() bool {
return *age <= 0
}
type User struct {
Name string `json:"name,omitzero"`
Age Age `json:"age,omitzero"`
Hobbies []string `json:"hobbies,omitzero"`
BornAt time.Time `json:"born_at,omitzero"`
}
func main() {
user := User{
Name: "Leapcell",
Age: -1,
Hobbies: []string{},
}
bytes, _ := json.MarshalIndent(user, "", " ")
fmt.Println(string(bytes))
}
In this example, the Age
field defines its own zero-value logic by implementing the IsZero
method. If Age
is less than or equal to 0, IsZero
returns true
, and the field will be omitted during serialization. The output will be:
{
"name": "Leapcell",
"hobbies": []
}
Summary
In Go, by using the omitzero
tag, we can precisely control which fields are omitted during JSON serialization, ensuring that only zero-value fields are excluded. Additionally, by implementing the IsZero
method, we can define custom zero-value logic for specific fields, enabling more flexible and context-aware serialization behavior.
We are Leapcell, your top choice for hosting Go projects.
Leapcell is the Next-Gen Serverless Platform for Web Hosting, Async Tasks, and Redis:
Multi-Language Support
- Develop with Node.js, Python, Go, or Rust.
Deploy unlimited projects for free
- pay only for usage — no requests, no charges.
Unbeatable Cost Efficiency
- Pay-as-you-go with no idle charges.
- Example: $25 supports 6.94M requests at a 60ms average response time.
Streamlined Developer Experience
- Intuitive UI for effortless setup.
- Fully automated CI/CD pipelines and GitOps integration.
- Real-time metrics and logging for actionable insights.
Effortless Scalability and High Performance
- Auto-scaling to handle high concurrency with ease.
- Zero operational overhead — just focus on building.
Explore more in the Documentation!
Follow us on X: @LeapcellHQ