Skip to content

net/http2: optimize Date header generation to reduce per-request formatting overhead #79914

@solos

Description

@solos

Go version

go1.27 darwin/arm64

Output of go env in your module/workspace:

AR='ar'
CC='clang'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='clang++'
GCCGO='gccgo'
GO111MODULE='on'
GOARCH='arm64'
GOARM64='v8.0'
GOAUTH='netrc'
GOBIN='/Volumes/drive/go/bin'
GOCACHE='/Volumes/drive/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/Users/solos/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/3z/2dkz0r7553j_yn8gxvjqdh700000gn/T/go-build885166265=/tmp/go-build -gno-record-gcc-switches -fno-common'
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMOD='/Volumes/drive/dev/go/src/go.mod'
GOMODCACHE='/Volumes/drive/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPACKAGESDRIVER=''
GOPATH='/Volumes/drive/go'
GOPRIVATE=''
GOPROXY='https://mirrors.aliyun.com/goproxy/,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/Users/solos/Library/Application Support/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.27-devel_48fbc8e14e 2026-06-09'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

I am working on optimizing the net/http2 package for high-concurrency scenarios. Currently, in the writeChunk function, the server generates a Date header by calling time.Now().UTC().Format() for every single outgoing response frame.

While correct, this introduces significant CPU overhead due to redundant time formatting operations when handling thousands of requests per second. Since the HTTP Date header only requires second-level precision, updating it on every request is inefficient.

What did you see happen?

Currently, the Date header is formatted from scratch for every single HTTP/2 response. In high-throughput benchmarks, profiling shows that time.Now().UTC().Format() consumes a noticeable amount of CPU time and causes unnecessary memory allocations due to string formatting overhead. This redundant work limits the maximum request-per-second throughput the server can achieve.

What did you expect to see?

I expected that we could reduce the overhead of Date header generation by caching the formatted date string and updating it only once per UTC second. This would eliminate the repetitive time.Format calls in the hot path.

I have prepared a patch (PR #79913) that implements this optimization using an atomic cache.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions