I made good experiences by tweaking sysctl values at tiny relays (1 GB RAM, 1 vCPU) and do wonder about your opion/experiences: $ ssh i30 cat /etc/sysctl.d/21firewall.conf # maintained by Ansible net.ipv4.tcp_fin_timeout = 10 net.ipv4.tcp_keepalive_time = 120 net.ipv4.tcp_max_syn_backlog = 8192 net.ipv4.tcp_mem = 2000 4000 8000 net.ipv4.tcp_synack_retries = 2 net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_tw_reuse = 1 net.ipv6.ip_nonlocal_bind = 1 net.netfilter.nf_conntrack_tcp_timeout_close_wait = 10 net.netfilter.nf_conntrack_tcp_timeout_established = 600 net.netfilter.nf_conntrack_tcp_timeout_time_wait = 10 net.core.netdev_max_backlog = 131072 net.core.somaxconn = 16384 net.ipv4.tcp_max_syn_backlog = 131072 net.ipv4.tcp_notsent_lowat = 131072 net.netfilter.nf_conntrack_buckets = 131072 net.netfilter.nf_conntrack_max = 131072 -- Toralf
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 Hello. On 2026-11-02 19:51, Toralf Förster via tor-relays wrote:
I made good experiences by tweaking sysctl values at tiny relays (1 GB RAM, 1 vCPU) and do wonder about your opion/experiences:
Some of those tweaks don't make sense to me:
net.ipv4.tcp_keepalive_time = 120
Why so aggressive? You could get away with 10x that interval.
net.ipv4.tcp_synack_retries = 2
Why give up so quickly? This might cause connections to congested relays to fail. Is the goal just to reduce the number of open sockets?
net.ipv6.ip_nonlocal_bind = 1
This seems like a mistake. Tor does not make use of arbitrary source addresses. Unless you're running Unbound with a routed IPv6 netblock and want it to randomize source addresses, there's no reason to enable this. Here is what I use: net.ipv4.tcp_ecn = 1 net.ipv4.tcp_fin_timeout = 10 net.ipv4.tcp_keepalive_time = 1200 net.ipv4.tcp_tw_reuse = 1 net.ipv4.ip_local_port_range = 10000 64999 net.ipv4.tcp_max_syn_backlog = 4096 net.ipv4.tcp_max_tw_buckets = 2048 net.ipv4.tcp_max_orphans = 32768 net.netfilter.nf_conntrack_tcp_timeout_established = 43200 net.netfilter.nf_conntrack_buckets = 32768 net.netfilter.nf_conntrack_max = 131072 Increasing the local port range and max conntrack entries helps a lot. Beware that some low-end VPS providers with cheap outsourced anti-DDoS shields occasionally block outgoing connections with source ports that are lower than the Linux default of 32768. ECN also helps, but it might be worthwhile to just use kernel 7.x which has AccECN by default which is better than traditional ECN. I've also played with bpftune to dynamically adjust TCP memory-related sysctls which has helped slightly, but there's not enough variation over time for it to really shine. Also, you can't enable lockdown when eBPF is enabled. I'm sure someone could write some Tor-specific modules for bpftune that could noticeably improve relay performance, though. But by far, what helps the most is setting Tor to use a memory allocator that is more resistant to memory fragmentation. 1AEO has found mimalloc2 is the best, but Debian only has mimalloc3 which is actually worse. I use jemalloc2 on all of my relays which substantially reduces memory use and eliminates thrashing. Regards, forest -----BEGIN PGP SIGNATURE----- iHUEARYKAB0WIQQtr8ZXhq/o01Qf/pow+TRLM+X4xgUCaulJtAAKCRAw+TRLM+X4 xt+VAP4q+jPZWhlxEigTz10udYxsiZcVqw3ur+7jf0y1fowXpwD/d/Iyf6eXxh/s 9sgyfmvF6r0ywqBJTuos6jjXmeCQVQk= =ETXV -----END PGP SIGNATURE-----
On 03/11/2026 03:40, forest via tor-relays wrote:
net.ipv4.tcp_keepalive_time = 120 Why so aggressive? You could get away with 10x that interval.
net.ipv4.tcp_synack_retries = 2 Why give up so quickly? This might cause connections to congested relays to fail. Is the goal just to reduce the number of open sockets? Yes.
net.ipv6.ip_nonlocal_bind = 1 This seems like a mistake. Tor does not make use of arbitrary source addresses. Unless you're running Unbound with a routed IPv6 netblock and want it to randomize source addresses, there's no reason to enable this.
I had reboot (timing?) issues at one of my provider - gone away with that.
But by far, what helps the most is setting Tor to use a memory allocator that is more resistant to memory fragmentation. 1AEO has found mimalloc2 is the best, but Debian only has mimalloc3 which is actually worse. I use jemalloc2 on all of my relays which substantially reduces memory use and eliminates thrashing.
Hhm, at my Debian I didn't saw improvements using another memory allocator, the number of socket is the biggest problem here. -- Toralf
On Tuesday, 3 November 2026 09:31 Toralf Förster via tor-relays wrote:
On 03/11/2026 03:40, forest via tor-relays wrote:
net.ipv4.tcp_keepalive_time = 120
Why so aggressive? You could get away with 10x that interval.
:-) I have (tor has it's own keepalive foo): net.ipv4.tcp_keepalive_time=60 net.ipv4.tcp_keepalive_intvl=10 net.ipv4.tcp_keepalive_probes=3
net.ipv6.ip_nonlocal_bind = 1
This seems like a mistake. Tor does not make use of arbitrary source addresses. Unless you're running Unbound with a routed IPv6 netblock and want it to randomize source addresses, there's no reason to enable this.
I had reboot (timing?) issues at one of my provider - gone away with that.
This is often because of IPv6 autoconf. That's why I disable it completely on servers. # disable IPv6 autoconf net.ipv6.conf.default.accept_ra=0 net.ipv6.conf.all.accept_ra=0 net.ipv6.conf.default.autoconf=0 net.ipv6.conf.all.autoconf=0 -- ╰_╯ Ciao Marco! Debian GNU/Linux It's free software and it gives you freedom!
Am 03.11.26 um 19:50 schrieb boldsuck via tor-relays:
This is often because of IPv6 autoconf. That's why I disable it completely on servers.
# disable IPv6 autoconf net.ipv6.conf.default.accept_ra=0 net.ipv6.conf.all.accept_ra=0 net.ipv6.conf.default.autoconf=0 net.ipv6.conf.all.autoconf=0
I disabled the A flag in the IPv6 RA, so the machines do not do SLAAC. I set the IPv6 addresses manually. -- Gruß Marco Muell und Spam bitte an abfalleimer2002@stinkedores.dorfdsl.de
On 03/11/2026 19:50, boldsuck via tor-relays wrote:
I had reboot (timing?) issues at one of my provider - gone away with that. This is often because of IPv6 autoconf. That's why I disable it completely on servers.
# disable IPv6 autoconf net.ipv6.conf.default.accept_ra=0 net.ipv6.conf.all.accept_ra=0 net.ipv6.conf.default.autoconf=0 net.ipv6.conf.all.autoconf=0
Oh, will give it a try. Thx! -- Toralf
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 On 2026-11-03 08:31, Toralf Förster via tor-relays wrote:
Hhm, at my Debian I didn't saw improvements using another memory allocator, the number of socket is the biggest problem here.
That's interesting. Are you sure the memory allocator was actually in use? It cuts memory use substantially. The bare minimum sysctls needed to completely fix the issue are: net.ipv4.ip_local_port_range = 10000 64999 net.ipv4.tcp_max_syn_backlog = 4096 net.ipv4.tcp_max_tw_buckets = 2048 net.ipv4.tcp_max_orphans = 16384 net.netfilter.nf_conntrack_buckets = 32768 net.netfilter.nf_conntrack_max = 131072 That completely eliminates any network resource issues even on my 1 GiB RAM, 1 vCPU relays that push nearly 200 Mbps. On 2026-11-03 18:50, boldsuck via tor-relays wrote:
net.ipv6.conf.all.accept_ra=0
It's better not to block all RA and instead just block RA that is used to configure new IPv6 addresses, otherwise you might block MTU changes. This is what I use (and note that the wildcard lets you avoid specifying "all" and "default" separately, but it only works in the config file): net.ipv6.conf.*.autoconf = 0 net.ipv6.conf.*.accept_ra_pinfo = 0 Regards, forest -----BEGIN PGP SIGNATURE----- iHUEARYKAB0WIQQtr8ZXhq/o01Qf/pow+TRLM+X4xgUCauphQwAKCRAw+TRLM+X4 xhhcAPsHELD1M2XJy6urWP0Lan/gKyJ9hVhWOb50szoWWQtB5gD/YXsUS7encS47 Jdpl8TJmDYnK6D9zc5Tw18Cj7mmHXQk= =gY1+ -----END PGP SIGNATURE-----
participants (4)
-
boldsuck -
forest -
Marco Moock -
Toralf Förster