Hi folks, I made this question in the slack channel, but maybe it was not the right place.
I was doing a simple test using the official control plane:
I spun up 2 instances, behind a NAT at home. They are in the same LAN. If I just ping using the LAN addresses I get a direct hit. Then I checked the netbird client status, and they are relayed to one of the public relays you have. And pinging between then using netbird, gives times in the order of 100ms. That makes sense since it says they are relayed.
Then decided to do the same test using Tailsacle, and after the first ping they realise they are next each other and it starts getting full LAN speed.
I am using the latest Linux client. In both cases I am using the default settings, no tuning at all.
Is it possible I am miss configuring something here in this simple test?
If this is on Windows, check your network routes. The Netbird routes have a lower metric than the local LAN which causes them to win.
If you change the netbird metric to be higher than the local LAN connection wins. Issue is that every time the connecting changes, the metric is reset.
I asked copilot for some help with a script to create a scheduled task that is triggered by network connection changes, then looks for a network interface like ‘wt0*’, which is what my netbird connection alias is called. It then changes the route metric to 500 so that if there is a LAN connection to that route, the LAN route will be lower.
It has been working for me but please review and test before you use it.
# -------------------------------
# CONFIG
# -------------------------------
$TaskName = "Fix NetBird Metric"
$ScriptPath = "C:\Scripts\Fix-NetBird-Metric.ps1"
# -------------------------------
# Ensure script directory exists
# -------------------------------
$scriptDir = Split-Path $ScriptPath
if (-not (Test-Path $scriptDir)) {
New-Item -ItemType Directory -Path $scriptDir -Force | Out-Null
}
# -------------------------------
# Write the metric-fix script
# -------------------------------
$scriptContent = @'
$adapter = Get-NetIPInterface | Where-Object { $_.InterfaceAlias -like "wt0*" }
if ($adapter) {
foreach ($a in $adapter) {
Write-Output "NetBird interface found: $($a.InterfaceAlias)"
Set-NetIPInterface -InterfaceAlias $a.InterfaceAlias -InterfaceMetric 500
Write-Output "Metric set to 500"
}
} else {
Write-Output "NetBird interface not found"
}
'@
Set-Content -Path $ScriptPath -Value $scriptContent -Encoding UTF8 -Force
# -------------------------------
# Create scheduled task if missing
# -------------------------------
$task = Get-ScheduledTask -TaskName $TaskName -ErrorAction SilentlyContinue
if (-not $task) {
Write-Output "Creating scheduled task '$TaskName'..."
$action = New-ScheduledTaskAction -Execute "powershell.exe" `
-Argument "-NoProfile -ExecutionPolicy Bypass -File `"$ScriptPath`""
# Trigger 1: Run at logon
$trigger1 = New-ScheduledTaskTrigger -AtLogOn
# Trigger 2: Run when network profile changes (Event ID 10000)
$CIMTriggerClass = Get-CimClass -ClassName MSFT_TaskEventTrigger -Namespace Root/Microsoft/Windows/TaskScheduler:MSFT_TaskEventTrigger
$Trigger2 = New-CimInstance -CimClass $CIMTriggerClass -ClientOnly
$Trigger2.Subscription =
@"
<QueryList><Query Id="0" Path="Microsoft-Windows-NetworkProfile/Operational"><Select Path="Microsoft-Windows-NetworkProfile/Operational">*[System[Provider[@Name='Microsoft-Windows-NetworkProfile'] and EventID=10000]]</Select></Query></QueryList>
"@
$Trigger2.Enabled = $True
Register-ScheduledTask -TaskName $TaskName `
-Action $action `
-Trigger $trigger1, $trigger2 `
-RunLevel Highest `
-Description "Forces NetBird interface metric to 500 whenever it reconnects." `
-User 'System' -Force `
| Out-Null
Write-Output "Scheduled task created."
} else {
Write-Output "Scheduled task already exists."
}
# -------------------------------
# Run the metric fix immediately
# -------------------------------
Write-Output "Running metric fix now..."
powershell.exe -NoProfile -ExecutionPolicy Bypass -File $ScriptPath