Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net: crypto/tls.(*Conn).SetReadDeadline consumes CPU #9071

gopherbot opened this issue Nov 8, 2014 · 2 comments

net: crypto/tls.(*Conn).SetReadDeadline consumes CPU #9071

gopherbot opened this issue Nov 8, 2014 · 2 comments


Copy link

@gopherbot gopherbot commented Nov 8, 2014

by david.birdsong:

What does 'go version' print?
go version go1.3.3 linux/amd64

What steps reproduce the problem?
build listener, no deps:

1. connect 8 clients to the tls port on port 5114
2. connect 1 client on the raw port on 5566
3. send basic tcp handshakes to the tls port every 3 seconds ( a tcp ping from a load
4. send ~5Mb/s of traffic to either port for 5-40 mins

What happened?
after random intervals after start, user cpu consumes or comes close to consuming cores
call graph shows 
tls.(*Conn).SetReadDeadline executing suspiciously during a majority of the samples

it appears that any goroutine executing tls.(*Conn).SetReadDeadline pegs a CPU core

What should have happened instead?
not sure, but user cpu should not increase so much.

Please provide any additional information below.
this code sample is ripped out of a larger server. in the larger server (heka),
throughput for the server is severely hampered by the increase in user cpu. In this
contrived example, only user CPU increases, but throughput is maintained.

This code snippet will reproduce this condition at random times. We have a TCP proxy
listening for syslog data from our vendor that connects to the TLS port. We also have
unencrypted data flowing over the raw TCP port. The trigger is unknow--sometimes it
takes 5 mins for CPU to jump and throughput to drop, other times ~30-40 minutes.

I can try to get tcpdumps if that's needed.
Copy link

@ianlancetaylor ianlancetaylor commented Nov 8, 2014

Comment 1:

Labels changed: added repo-main, release-go1.5.

@gopherbot gopherbot added new labels Nov 8, 2014
@bradfitz bradfitz modified the milestone: Go1.5 Dec 16, 2014
@rsc rsc removed the repo-main label Apr 14, 2015
Copy link

@bradfitz bradfitz commented May 6, 2015

Your svg shows handleConnection calling SetReadDeadline. And indeed, it calls it in a loop:

func handleConnection(conn net.Conn, stopChan chan bool, wg *sync.WaitGroup) {
    defer func() {

    var (
        e      error
        buffer []byte
    buffer = make([]byte, 16384)

    running := true
    for running {
        e = conn.SetReadDeadline(time.Now().Add(5 * time.Second))
        select {
        case _, running = <-stopChan:
            _, e = conn.Read(buffer)
            if e != nil {
                if neterr, ok := e.(net.Error); ok && neterr.Timeout() {
                } else {
                    running = false


If one of them ever times out, neterr.Timeout() will be true and you'll loop forever.

If you can still reproduce with that fixed and Go tip or Go 1.4.2, let us know.

@bradfitz bradfitz closed this May 6, 2015
@golang golang locked and limited conversation to collaborators Jun 25, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants
You can’t perform that action at this time.