Skip to content
Development docs, for main @ 60ec1d6 - what's coming, not yet released. This page for v2026.11.13, the latest release →

Kernel tuning (sysctl)

A node’s kernel parameters: the ones HAProxy depends on, which you can change - tested on trial, kept once applied, back to Janus’s defaults any time - and the CIS benchmark’s, which nothing changes.

There’s no shell and no sysctl command on a node: the parameters go through the API - the node page’s System › Sysctl, janusctl system sysctl, or the SystemService.Sysctl* calls (API reference).

Only these parameters, each within its bounds: the node refuses any other key and any other value, whoever asks. Janus’s defaults are HAProxy’s own recommendations (HAProxy Enterprise: tune the operating system), unless the CIS benchmark or Janus’s own listeners say otherwise - the source port range starts at 10240, above janusd’s 9505 and the Janus exporter’s 10056, as HAProxy’s guidance asks - and the kernel’s own value for the parameters that depend on the machine’s memory, read at boot.

ParameterJanus’s defaultAllowedTakes effectHAProxy recommends
net.core.somaxconn600004096-65535 connectionsHAProxy’s next reload60000
net.ipv4.ip_local_port_range10240 65023low 1024-32768, high 5119-65535 portsnew connections1024 65023
net.ipv4.ip_local_reserved_ports(none)up to 32 ports or ranges, 1024-65535new connections-
net.ipv4.tcp_tw_reuse10, 1, 2new connections1
net.ipv4.tcp_fin_timeout3030-120 secondsat once30
net.ipv4.tcp_synack_retries31-5 retriesat once3
net.ipv4.ip_nonlocal_bind10, 1HAProxy’s next reload1
net.ipv6.ip_nonlocal_bind10, 1HAProxy’s next reload1
net.core.netdev_max_backlog100001000-65536 packetsat once10000
net.ipv4.tcp_rmemthe kernel’s: 4096 131072, maximum from the memory (32 MiB at most)min 4 KiB-64 KiB, default 4 KiB-4 MiB, max 64 KiB-64 MiBnew connections4096 16060 262144 (optional)
net.ipv4.tcp_wmemthe kernel’s: 4096 16384, maximum from the memory (4 MiB at most)min 4 KiB-64 KiB, default 4 KiB-4 MiB, max 64 KiB-64 MiBnew connections4096 16384 262144 (optional)
net.ipv4.tcp_memthe kernel’s: from the memory at boot: about a sixteenth of it for the second value, three quarters and one and a half times that for the othersmin 4096-67108864, default 4096-67108864, max 4096-67108864 pagesat once-
fs.file-maxthe kernel’s: about 10% of the memory, at 1 KiB a file8192-67108864 filesat once-
net.ipv4.tcp_keepalive_time720060-7200 secondsat once-
net.ipv4.tcp_keepalive_intvl7510-75 secondsat once-
net.ipv4.tcp_keepalive_probes93-20 probesat once-
net.ipv4.tcp_fastopen10, 1, 2, 3at once-
net.netfilter.nf_conntrack_maxthe kernel’s: from the memory: 1 per 128 KiB up to 1 GiB, then 65536, 262144 above 4 GiB16384-4194304 entriesat once-

What each one does:

  • net.core.somaxconn - Upper limit of every listening socket’s accept queue - the backlog listen() asks for. HAProxy: HAProxy asks for a backlog equal to the frontend’s maxconn (or its backlog setting) and the kernel caps it here. SYN cookies being always on (CIS 3.3.1.18), it also bounds the SYN queue before cookies take over. HAProxy reads it when it opens its listeners: a change reaches it at its next reload. Risk: A full queue holds connections HAProxy hasn’t accepted yet, per listener: memory, on a small node. A very high limit also hides saturation - clients wait instead of failing fast. The kernel’s default: 4096. Sources: HAProxy configuration: backlog, HAProxy Enterprise: tune the operating system, HAProxy: doc/linux-syn-cookies.txt.
  • net.ipv4.ip_local_port_range - Source ports of outgoing connections: HAProxy’s connections to its servers. HAProxy: Bounds the connections (TIME_WAIT ones included) HAProxy can have at once to one server address and port; when they run out, it fails with “Out of local source ports on the system”. Janus starts at 10240, above its own listeners (janusd 9505, the Janus exporter 10056), as HAProxy’s guidance asks. Risk: An outgoing connection can take a listening port inside the range, and a reload binding that port then fails: a change is refused while a port the node listens on is inside the range without being reserved (net.ipv4.ip_local_reserved_ports). The kernel’s default: 32768 60999. Sources: HAProxy Enterprise: tune the operating system, HAProxy configuration: source.
  • net.ipv4.ip_local_reserved_ports - Ports never handed out as source ports. HAProxy: Keeps a port HAProxy - or another service - listens on, inside the source port range, from being taken by an outgoing connection. Risk: Each reserved port is one source port less. The kernel’s default: (none). Sources: Linux: IP sysctl.
  • net.ipv4.tcp_tw_reuse - Reuse of a TIME_WAIT socket for a new outgoing connection when TCP timestamps make it safe: 0 off, 1 on, 2 loopback only. HAProxy: Frees the source ports of HAProxy’s connections to its servers - needed above a few hundred connections per second. Risk: Low: a server that sends no TCP timestamps just gets no reuse. The kernel’s default: 2. Sources: HAProxy Enterprise: tune the operating system.
  • net.ipv4.tcp_fin_timeout - How long an orphaned connection stays in FIN_WAIT_2. HAProxy: HAProxy closes connections itself: a shorter timeout releases dead ones sooner. Risk: HAProxy warns of problems below 25 to 30 seconds - hence 30 at least. The kernel’s default: 60. Sources: HAProxy Enterprise: tune the operating system.
  • net.ipv4.tcp_synack_retries - SYN-ACK retransmissions for an incoming connection attempt. HAProxy: The amplification factor of a SYN flood: with 3, a half-open connection is dropped after about 15 seconds instead of 63. Risk: Too low and clients on lossy networks can’t connect - 1 only during an attack. The kernel’s default: 5. Sources: HAProxy Enterprise: tune the operating system.
  • net.ipv4.ip_nonlocal_bind - Binding to an IPv4 address the node doesn’t have (yet). HAProxy: HAProxy starts and reloads with a bind on a virtual IP (VRRP) on every node of the group, not only the one holding it - HAProxy’s advice is to always leave it on. Risk: A mistyped bind address no longer fails HAProxy’s start, where Janus would put the previous configuration back. The kernel’s default: 0. Sources: HAProxy management: well-known traps to avoid, HAProxy Enterprise: tune the operating system.
  • net.ipv6.ip_nonlocal_bind - Binding to an IPv6 address the node doesn’t have (yet). HAProxy: As for IPv4: a bind on an IPv6 virtual IP works on every node of the group. Risk: A mistyped bind address no longer fails HAProxy’s start. The kernel’s default: 0. Sources: HAProxy management: well-known traps to avoid, HAProxy Enterprise: tune the operating system.
  • net.core.netdev_max_backlog - Received packets waiting for the network stack, per CPU. HAProxy: Absorbs bursts of traffic - an effect HAProxy calls minimal. Risk: Memory and latency while the queue is full. The kernel’s default: 1000. Sources: HAProxy Enterprise: tune the operating system.
  • net.ipv4.tcp_rmem - Receive buffer of each TCP socket: minimum, default and maximum, auto-tuned in between. HAProxy: Kernel memory per connection: smaller buffers let a node hold more connections at once. Risk: A low maximum caps a connection’s throughput at about the maximum divided by the round-trip time - 256 KiB at 50 ms is about 40 Mbit/s. The kernel’s default: 4096 131072, maximum from the memory (32 MiB at most). Sources: HAProxy Enterprise: tune the operating system, HAProxy configuration: tune.rcvbuf.client.
  • net.ipv4.tcp_wmem - Send buffer of each TCP socket: minimum, default and maximum, auto-tuned in between. HAProxy: Kernel memory per connection: smaller buffers let a node hold more connections at once. Risk: A low maximum caps a connection’s throughput at about the maximum divided by the round-trip time. The kernel’s default: 4096 16384, maximum from the memory (4 MiB at most). Sources: HAProxy Enterprise: tune the operating system, HAProxy configuration: tune.sndbuf.client.
  • net.ipv4.tcp_mem - Memory all TCP sockets may take together, in 4 KiB pages: below the first value nothing holds them back, from the second TCP shrinks their buffers, at the third it gives them no more. HAProxy: HAProxy’s connections’ kernel buffers come out of it: at the third value, data waits or is dropped and connections stall - the TCP memory pressure signal. Risk: Too high, sockets can take memory HAProxy needs itself; too low, connections slow down under load. The kernel computes it once, at boot: memory plugged in later doesn’t change it. The kernel’s default: from the memory at boot: about a sixteenth of it for the second value, three quarters and one and a half times that for the others. Sources: Linux: IP sysctl.
  • fs.file-max - Open files on the whole system. HAProxy: HAProxy runs as uid 1000 without CAP_SYS_ADMIN, so it’s held to it: at the limit, accept() and socket() fail with ENFILE (“Too many sockets on the system”). Risk: More descriptors, more memory they can take. The kernel’s default: about 10% of the memory, at 1 KiB a file. Sources: HAProxy management: file-descriptor limitations.
  • net.ipv4.tcp_keepalive_time - Idle time before TCP probes a connection that has keepalive on. HAProxy: HAProxy uses it for option tcpka, clitcpka and srvtcpka when clitcpka-idle, -intvl and -cnt (srvtcpka-*) aren’t set. Risk: Aggressive values add traffic and drop connections over unstable links. The kernel’s default: 7200. Sources: HAProxy configuration: clitcpka-idle.
  • net.ipv4.tcp_keepalive_intvl - Time between two keepalive probes. HAProxy: HAProxy uses it for option tcpka, clitcpka and srvtcpka when clitcpka-idle, -intvl and -cnt (srvtcpka-*) aren’t set. Risk: Aggressive values add traffic and drop connections over unstable links. The kernel’s default: 75. Sources: HAProxy configuration: clitcpka-intvl.
  • net.ipv4.tcp_keepalive_probes - Unanswered keepalive probes before the connection is dropped. HAProxy: HAProxy uses it for option tcpka, clitcpka and srvtcpka when clitcpka-idle, -intvl and -cnt (srvtcpka-*) aren’t set. Risk: Few probes drop connections over unstable links. The kernel’s default: 9. Sources: HAProxy configuration: clitcpka-cnt.
  • net.ipv4.tcp_fastopen - TCP Fast Open: 1 as a client, 2 as a server, 3 both. HAProxy: A bind line’s tfo only works with the server bit (2): data in the SYN saves a round trip on repeat connections. The flags without a cookie or for every listener (0x4, 0x200, 0x400) aren’t offered. Risk: Some middleboxes drop SYNs that carry data, and that data can be replayed - HAProxy advises enabling it only once well tested. The kernel’s default: 1. Sources: HAProxy configuration: tfo, Linux: IP sysctl.
  • net.netfilter.nf_conntrack_max - Size of the connection-tracking table the firewall’s stateful (ct) rules use. HAProxy: With the nftables extension and stateful rules, each of HAProxy’s client and server connections takes an entry: a full table drops the packets of new connections. Risk: About 320 bytes of memory an entry. Without conntrack rules it has no effect. The kernel’s default: from the memory: 1 per 128 KiB up to 1 GiB, then 65536, 262144 above 4 GiB. Sources: Linux: netfilter conntrack sysctl.

The page and janusctl system sysctl list also show these, for diagnosis - none can change:

ParameterWhy it doesn’t changeSources
net.ipv4.tcp_max_syn_backlogRemembered connection requests that haven’t completed their handshake, per listener. No effect on Janus: SYN cookies are always on (CIS 3.3.1.18) and the kernel only reads it with them off - the SYN queue is bounded by the backlog, so net.core.somaxconn is the one to tune.HAProxy Enterprise: tune the operating system, HAProxy: doc/linux-syn-cookies.txt
fs.nr_openHighest open-files limit a process may be given. No effect: Janus’s init gives janusd and HAProxy a limit of 524288, below it - HAProxy derives its maxconn from that limit.HAProxy management: file-descriptor limitations, HAProxy configuration: fd-hard-limit
net.ipv4.tcp_congestion_controlTCP congestion control algorithm of new connections. Only cubic is built into Janus’s kernel - no BBR.HAProxy configuration: cc
net.ipv4.tcp_available_congestion_controlThe algorithms a bind or server line’s cc may name. The kernel’s list - what Janus builds in.HAProxy configuration: cc
kernel.core_patternWhere the kernel writes a crashed process’s core dump. Forbidden. A pattern starting with | would run a program as root on every crash: never changed on Janus.HAProxy configuration: set-dumpable

Janus’s baseline follows the CIS Debian Linux 13 Benchmark v1.0.0, profile Level 2 - Server, for its controls on kernel parameters (sections 1.5 and 3.3). It’s the newest CIS Linux benchmark, and these controls only check /proc/sys values, so they apply to Janus as they are; the only Level 2 ones (1.5.2 and 3.3.1.1) hold anyway. 1.3.1.4 (AppArmor) doesn’t apply: Janus confines its daemons with SELinux.

Every boot writes these values first, and again after the values you saved; no call changes them, every change is refused while one doesn’t hold, and the values a change writes are checked against them before it stays. The kernel uses each interface’s own value of a few keys, and IPv6 doesn’t copy all or default onto the interfaces that already exist - they all do before Janus’s init runs - so those are written, and checked, on every interface too. And a node boots with IPv6 off (ipv6.disable_ipv6=1, in its signed kernel command line): init turns it on once every interface has these values, so none takes a router advertisement or a redirect in the first seconds of a boot.

ControlLevelKeyJanus writesCompliant
1.5.11fs.protected_hardlinks11
1.5.22fs.protected_symlinks11
1.5.3, 1.5.101kernel.yama.ptrace_scope21 or 2 or 3
1.5.41fs.suid_dumpable00
1.5.51kernel.dmesg_restrict11
1.5.81kernel.kptr_restrict21 or 2
1.5.91kernel.randomize_va_space22
3.3.1.12net.ipv4.ip_forward00
3.3.1.21net.ipv4.conf.all.forwarding00
3.3.1.31net.ipv4.conf.default.forwarding00
3.3.1.41net.ipv4.conf.all.send_redirects, and on every interface00
3.3.1.51net.ipv4.conf.default.send_redirects00
3.3.1.61net.ipv4.icmp_ignore_bogus_error_responses11
3.3.1.71net.ipv4.icmp_echo_ignore_broadcasts11
3.3.1.81net.ipv4.conf.all.accept_redirects, and on every interface00
3.3.1.91net.ipv4.conf.default.accept_redirects00
3.3.1.101net.ipv4.conf.all.secure_redirects, and on every interface00
3.3.1.111net.ipv4.conf.default.secure_redirects00
3.3.1.121net.ipv4.conf.all.rp_filter11
3.3.1.131net.ipv4.conf.default.rp_filter11
3.3.1.141net.ipv4.conf.all.accept_source_route00
3.3.1.151net.ipv4.conf.default.accept_source_route00
3.3.1.161net.ipv4.conf.all.log_martians11
3.3.1.171net.ipv4.conf.default.log_martians11
3.3.1.181net.ipv4.tcp_syncookies11
3.3.2.11net.ipv6.conf.all.forwarding00
3.3.2.21net.ipv6.conf.default.forwarding00
3.3.2.31net.ipv6.conf.all.accept_redirects, and on every interface00
3.3.2.41net.ipv6.conf.default.accept_redirects00
3.3.2.51net.ipv6.conf.all.accept_source_route00
3.3.2.61net.ipv6.conf.default.accept_source_route00
3.3.2.71net.ipv6.conf.all.accept_ra, and on every interface00
3.3.2.81net.ipv6.conf.default.accept_ra00

What it means for HAProxy and the node:

  • No router advertisements: IPv6 addresses and their gateway are static, set in the network configuration - no SLAAC address, no default route learned from a router.
  • No IP forwarding: HAProxy’s full transparent proxy mode (source ... usesrc, which needs the servers to route back through the node) isn’t possible.
  • No core dumps after HAProxy drops its privileges (fs.suid_dumpable): set-dumpable can’t bring them back.
  • SYN cookies always on: net.ipv4.tcp_max_syn_backlog has no effect, so it’s read-only - net.core.somaxconn bounds the SYN queue.
  • Martian packets are logged in the kernel’s messages, at the kernel’s own rate limit.

A change goes on trial: the node checks it, writes it, checks the benchmark still holds, and puts the previous values back by itself unless you apply it in time.

On the node page, System › Sysctl: change values in the table (the page checks them as you type), then Test on trial…. The banner counts down: Apply keeps them, Cancel now puts the previous values back. Reset puts one parameter back to Janus’s default, Reset all to defaults… every one - on trial too.

With janusctl:

Terminal window
janusctl system sysctl list # values, defaults, the benchmark
janusctl system sysctl get net.core.somaxconn # one parameter in full
janusctl system sysctl set -no-confirm net.core.somaxconn=30000
janusctl system sysctl confirm # keep it - or: cancel
janusctl system sysctl reset -all # back to the defaults
janusctl system sysctl history # who changed what, when
janusctl system sysctl observed # what the suggestions rest on

Without -no-confirm, set and reset confirm at once over a new connection - the trial then only protects against a change that would cut the node off.

  • The trial lasts 10 minutes by default (-timeout, 1 minute to 1 hour). Testing more while a trial runs adds to it; its end - applied, cancelled or run out - concerns everything it holds, and a revert goes back to the values from before it began.
  • Applying must come over a connection opened after the latest test, proof that the node still takes new connections.
  • HAProxy reloads - seamlessly - for net.core.somaxconn and the ip_nonlocal_bind parameters, which it only reads when it opens its listeners, and again when they go back (-no-reload, or the page’s checkbox, leaves it alone: they reach it at its next reload).
  • A reboot or a restart of janusd during a trial ends it: the node comes back with the values you applied before.

The node suggests values for some parameters - from its memory, and from what it observed over the last week -, each with the rule that gave it, what it measured and where the rule comes from. A suggestion is only ever shown: on the page, Use puts it in the table, then you test it on trial and apply it like any change; janusctl system sysctl get NAME prints it, with the command that tests it. It stays within the parameter’s bounds and passes the same checks as a change - one the node would refuse isn’t shown -, and only the parameters you can change get one.

The node never applies one by itself. The Controller’s auto-scaling does, for a machine whose policy has the kernel parameters follow it - on trial and confirmed like any change, never a parameter someone else confirmed.

Every 15 seconds, janusd reads the kernel’s counters and gauges below - the source ports in use, by destination, every minute -, by hour: a counter’s increase in the hour, a gauge’s highest value. It keeps 14 days of hours on STATE (/etc/janus/config/sysctl-observations.json). A rule acts on a signal seen in 3 different hours of the last 7 days at least: a saturation that comes back, never one peak. The page’s What the node observed shows each signal, as does janusctl system sysctl observed.

SignalWhat’s readAn hour counts when
Accept queue overflows (accept_overflows)TcpExt ListenOverflows (/proc/net/netstat): connections dropped because a listening socket’s accept queue was full.It increased.
SYN cookies sent (syn_cookies)TcpExt SyncookiesSent (/proc/net/netstat): a listening socket’s SYN queue was full - a flood, or a burst bigger than the backlog.It increased.
Outgoing connections a second (outgoing_rate)Tcp ActiveOpens (/proc/net/snmp) over each minute: the connections the node opens - HAProxy’s to its servers, mostly.300 or more a second, over a minute.
Source ports to one server (source_ports)Every minute, the sockets to each destination address and port whose source port is in net.ipv4.ip_local_port_range - TIME_WAIT ones included - over the ports the range offers (reserved ones left out).Half the ports or more, to one destination.
Open files (open_files)fs.file-nr’s allocated files over fs.file-max.80% or more.
Connection tracking table (conntrack_usage)net.netfilter.nf_conntrack_count over net.netfilter.nf_conntrack_max.75% or more.
Connection tracking drops (conntrack_drops)drop, early_drop and insert_failed (/proc/net/stat/nf_conntrack): packets dropped, entries evicted or refused because the table was full.They increased.
Input backlog drops (backlog_drops)softnet_stat’s dropped column (/proc/net/softnet_stat), every CPU: packets dropped because a CPU’s input queue was full.It increased.
TCP memory pressure (tcp_memory)TcpExt TCPMemoryPressures and TCPAbortOnMemory (/proc/net/netstat): TCP’s memory reached net.ipv4.tcp_mem’s pressure mark, or connections were reset for lack of it.They increased.

HAProxy’s listening sockets are told from the others by their inodes, read from HAProxy’s own file descriptors once per process: root creates them, before HAProxy runs as uid 1000.

Each parameter tries its rules in order - what the node observed before what its memory says - and shows the first suggestion other than its value. The keepalives, TCP Fast Open, ip_nonlocal_bind, tcp_fin_timeout and the reserved ports have none: they depend on how the node is used, not on a measurement. None of the parameters follows the number of CPUs on its own - net.core.netdev_max_backlog is per CPU, but only drops show it’s short.

The kernel computes tcp_mem, file-max and nf_conntrack_max from the memory once, at boot. Memory plugged into a running machine, or taken out (the Controller’s auto-scaling), leaves them as they were: once the memory is more than a tenth away from the boot’s, their follow_memory rule suggests the boot’s value in proportion to the memory now.

ParameterRuleWhen, and what it suggestsSources
net.core.somaxconnsomaxconn.overflowsAccept queues overflowed in 3 different hours of the last 7 days or more, and one of HAProxy’s listeners has net.core.somaxconn as its backlog - the kernel’s limit, not one HAProxy asked for: twice the value, at most 65535.HAProxy configuration: backlog, Linux: IP sysctl
net.core.somaxconnsomaxconn.memoryAn eighth of the node’s memory for full accept queues during an overload, at about 4 KiB a waiting connection, shared by HAProxy’s listeners: the power of two below, 4096 at least - only when lower than the value.HAProxy configuration: backlog
net.ipv4.ip_local_port_rangeport_range.usageSockets to one destination took half the source ports or more, in 3 different hours of the last 7 days or more: the widest range the node allows - from the first multiple of 1024 above the ports it listens on (reserved ones aside) to 65023, HAProxy’s upper end - when wider than the current one.HAProxy Enterprise: tune the operating system, HAProxy configuration: source
net.ipv4.tcp_tw_reusetw_reuse.rateThe node opened 300 connections a second or more, in 3 different hours of the last 7 days or more: TIME_WAIT sockets reused for new outgoing connections (1) - needed above a few hundred a second.HAProxy Enterprise: tune the operating system
net.ipv4.tcp_synack_retriessynack_retries.cookiesSYN cookies went out in 3 different hours of the last 7 days or more - SYN queues full, from floods or bursts: 2, so a connection that never completes leaves the queue after about 7 seconds (15 with 3) - only lowered.HAProxy: doc/linux-syn-cookies.txt, Linux: IP sysctl
net.core.netdev_max_backlognetdev_max_backlog.dropsCPUs’ input queues dropped packets in 3 different hours of the last 7 days or more: twice the value, at most 65536.Linux: IP sysctl, HAProxy Enterprise: tune the operating system
net.ipv4.tcp_rmemtcp_rmem.memoryTCP’s memory came under pressure in 3 different hours of the last 7 days or more: HAProxy’s smaller buffers for many connections, 4096 16060 262144 - only when the maximum is higher.HAProxy Enterprise: tune the operating system
net.ipv4.tcp_wmemtcp_wmem.memoryTCP’s memory came under pressure in 3 different hours of the last 7 days or more: HAProxy’s smaller buffers for many connections, 4096 16384 262144 - only when the maximum is higher.HAProxy Enterprise: tune the operating system
net.ipv4.tcp_memtcp_mem.follow_memoryThe machine’s memory changed by more than a tenth since it booted - plugged in or taken out while it runs, by the Controller’s auto-scaling: the value the kernel computed at boot, in proportion to the memory now - when it differs from the value by more than a tenth.Linux: IP sysctl
fs.file-maxfile_max.usageOpen files reached 80% of fs.file-max in 3 different hours of the last 7 days or more: twice the highest count, rounded up to a multiple of 1024.HAProxy management: file-descriptor limitations
fs.file-maxfile_max.follow_memoryThe machine’s memory changed by more than a tenth since it booted - plugged in or taken out while it runs, by the Controller’s auto-scaling: the value the kernel computed at boot, in proportion to the memory now - when it differs from the value by more than a tenth.Linux: IP sysctl
net.netfilter.nf_conntrack_maxconntrack_max.usageThe table reached 75% - or dropped connections for want of room - in 3 different hours of the last 7 days or more: twice the highest count, rounded up to a multiple of 1024, no less than the memory rule below gives, at most an eighth of the memory at 320 bytes an entry.Linux: netfilter conntrack sysctl
net.netfilter.nf_conntrack_maxconntrack_max.memoryConnections tracked (the nftables extension’s stateful rules): two entries per HAProxy connection, closed ones kept 2 minutes - a thirty-second of the memory at 320 bytes an entry, rounded down to a multiple of 1024, at most 262144 (the kernel’s own value above 4 GiB) - only when higher than the value.Linux: netfilter conntrack sysctl
net.netfilter.nf_conntrack_maxconntrack_max.follow_memoryThe machine’s memory changed by more than a tenth since it booted - plugged in or taken out while it runs, by the Controller’s auto-scaling: the value the kernel computed at boot, in proportion to the memory now - when it differs from the value by more than a tenth.Linux: IP sysctl

The values you apply are saved on STATE, in /etc/janus/config/sysctl.d/90-haproxy-tuning.conf - sysctl.d’s syntax, only what differs from Janus’s defaults. At boot, Janus’s init writes:

  1. the baseline: the benchmark’s values, Janus’s own, then the defaults above - and IPv6 on, last;
  2. the saved file, line by line against the same whitelist and bounds as the API - a line that fails is skipped, logged on the console (init: sysctl: sysctl.d/90-haproxy-tuning.conf line N: ...) and recorded in the history;
  3. the benchmark’s values again, then an audit on the console: init: sysctl: CIS Debian Linux 13 Benchmark v1.0.0 (Level 2 - Server): 33/33 controls compliant.

All of it happens before janusd starts HAProxy, which opens its listeners with these values.

SELinux enforces the same whitelist underneath: only these parameters’ files are labelled sysctl_tunable_t, the only /proc/sys files janusd may write - the benchmark’s stay out of its reach, and only init writes them. No other daemon - HAProxy, an extension’s - writes a kernel parameter at all. A janusd that doesn’t run a Janus node (-manage-host off, as in local-dev) shows the parameters and changes none.

Every test, apply, cancel and revert is recorded on STATE - the newest 1000 - with who asked (the certificate’s name and roles, and the Controller user it acted for), when, and each value before and after; the lines a boot refused too. The node page shows it, as does janusctl system sysctl history. The Controller’s own audit log records the requests it relays as well.