Sysctl knob(s) to set TCP 'nagle' time-out?

Matthew Dillon dillon at
Mon Jun 23 08:27:12 UTC 2008

:I'm wondering if anything exists to set this.. When you create an INET  
:without the 'TCP_NODELAY' flag the network layer does 'naggling' on your
:transmitted data. Sometimes with hosts that use Delayed_ACK  
:delayed_ack) it creates a dead-lock where the host will not ACK until  
:it gets
:another packet and the client will not send another packet until it  
:gets an ACK..
:The dead-lock gets broken by a time-out, which I think is around 200ms?
:But I would like to change that time-out if possible to something  
:lower, yet
:I can't really see any sysctl knobs that have a name that suggests  
:they do
:So does anyone know IF this can be tuned and if so by what?
:(And yes you could solve it by setting the TCP_NODELAY flag on the  
:but not everything has programmed in options to set it and you don't  
:have access to the source, besides setting a sysctl value would be much
:simpler than recompiling stuff)

    There is a sysctl which adjusts the delayed-ack timing, its
    called net.inet.tcp.delacktime.  The default is 1/10 of a second
    (100 == 100 ms = 1/10 of a second).

    BUT, it shouldn't be possible for nagle to deadlock against delayed acks
    unless the TCP implementation is broken somehow.  A delayed ack is
    simply that... the ack is delayed 100 ms in order to improve its
    chances of being piggy-backed on return data.  The ack is not blocked
    completely, just delayed, and certain events (such as the receiving
    end turning around and sending data back, which is typical for an
    interactive connection)... certain events will cause the delayed ack
    to be aborted and for the ack to be immediately sent with the return data.

    Can it break down and cause excessive lag?  Yes, it can.  Interactive
    games almost universally have to disable Nagle because the lag is
    actually due to the data relay from client 1 -> server then relaying
    the interactive event to client 2.  Without an immediate interactive
    response to client 1 the ack gets delayed and the next event from 
    client 1 hits Nagle and stops dead in the water until the first event
    reaches client 2 and client 2 reacts to it (then client 2 -> server -> 
    (abort delayed ack and send) -> client 1 (client 1's nagle now allows
    the second event to be transmitted).  That isn't a deadlock, just 
    really poor interactive performance in that particular situation.

    Delayed acks also have a safety valve.  The spec says that an ack
    cannot be delayed more then two packets.  In a batch link when the
    second (unacked) packet is received, the delayed ack is aborted and
    an ack is immediately returned to the sender.  This is to prevent
    congestion control (which is based on acks) from getting completely
    out of whack and also to prevent the TCP window from getting exhausted.

    In anycase, the usual solution is to disable Nagle rather then mess
    with delayed acks.  What we need is a new Nagle that understands the
    new reality for interactive connections... something that doesn't break
    performance in the 'server in the middle' data relaying case.


More information about the freebsd-stable mailing list