tune SearXNG VPN request timeouts and retries

This commit is contained in:
Frank committed 2026-08-25 17:58:22 -07:00
1 parent e1f05bd3c2
commit a05584b155
4 files changed
+40 -19

No files matched your search

+16 -11
View File
@@ -137,12 +137,12 @@ Tune the `outgoing` block and the suspend model to survive load:
```yaml ```yaml
outgoing: outgoing:
request_timeout: 6.0 # raise from 2.0 so slow engines aren't dropped as unresponsive request_timeout: 4.0 # current Dankclaw value; modest VPN-latency allowance
max_request_timeout: 15.0 max_request_timeout: 12.0
pool_connections: 200 # bigger pool = more concurrent connections per engine host pool_connections: 100
pool_maxsize: 40 # keep-alive connections per host pool_maxsize: 20
enable_http2: true # multiplexing = fewer distinct "new connection" events per engine enable_http2: true
retries: 3 # on 429/5xx, retry against a different proxy + source IP retries: 1 # avoid amplifying 429/CAPTCHA responses from one exit IP
useragent_suffix: "ops@yourhomelab.example" # so a per-engine blocker can reach you useragent_suffix: "ops@yourhomelab.example" # so a per-engine blocker can reach you
search: search:
@@ -159,8 +159,12 @@ Notes:
that is a historical-searx concept. The functional equivalent is the suspend that is a historical-searx concept. The functional equivalent is the suspend
schedule above (widen to back off before blocking, narrow to recover faster). schedule above (widen to back off before blocking, narrow to recover faster).
- `request_timeout` interacts with the suspend model: too tight → engines look - `request_timeout` interacts with the suspend model: too tight → engines look
"unresponsive"; too loose → slow pages. Aim per-engine `timeout` at "unresponsive"; too loose → slow pages. Dankclaw uses 4 seconds globally and
*proxy-add-on time + engine latency*, capped by `max_request_timeout`. 12 seconds as the cap; raise it only when measurements show real upstream
latency rather than 429/CAPTCHA responses.
- Keep retries low: retrying a 429/CAPTCHA through the same VPN exit can make the
provider's rate limit worse. A retry count of 1 is a bounded compromise for a
transient network failure.
- `safe_search: 0` when diagnosing — a too-strict global safe search can make an - `safe_search: 0` when diagnosing — a too-strict global safe search can make an
engine return zero rows and *look* blocked. engine return zero rows and *look* blocked.
@@ -288,9 +292,10 @@ misleading).
1. **Verify first** — `/json` + `?engines=google` and the searx-checker to see 1. **Verify first** — `/json` + `?engines=google` and the searx-checker to see
exactly which engines are down and why. Confirm the running SearXNG version exactly which engines are down and why. Confirm the running SearXNG version
(check whether `parsers`/`rate_limit` exist in the pinned build). (check whether `parsers`/`rate_limit` exist in the pinned build).
2. **Tighten Fix B** — raise `outgoing.request_timeout`, add `retry_on_http_error: 2. **Use conservative request tuning** — Dankclaw now allows 4 seconds per
[403, 429]` on the Google engines, widen `suspended_times`. Cheapest, no new upstream request, caps it at 12 seconds, and retries once. This addresses
infra. modest VPN latency without multiplying 429/CAPTCHA traffic. Adjust only
after measuring the resulting error and latency profile.
3. **Duplicate the Google engines** (Fix A) so a CAPTCHA ban on one leaves the 3. **Duplicate the Google engines** (Fix A) so a CAPTCHA ban on one leaves the
other returning results. other returning results.
4. **If Google still re-blocks** — Fix C Option 1: point the Google engines at a 4. **If Google still re-blocks** — Fix C Option 1: point the Google engines at a
+8 -5
View File
@@ -61,9 +61,9 @@ valkey:
url: "valkey://searxng-valkey:6379/0" url: "valkey://searxng-valkey:6379/0"
outgoing: outgoing:
request_timeout: 3.0 request_timeout: 4.0
max_request_timeout: 10.0 max_request_timeout: 12.0
retries: 3 retries: 1 # avoid amplifying upstream 429/CAPTCHA responses
``` ```
## Volumes ## Volumes
@@ -96,8 +96,11 @@ Reach SearXNG through Caddy (`search.dankclaw.local`) for browser use. A local s
## Unblocking Google & Search Providers ## Unblocking Google & Search Providers
SearXNG queries all ~50 upstream engines from one Gluetun VPN exit IP. The The current request policy allows a modest amount of VPN latency (`4.0s` per
rate-sensitive engines (Google, DuckDuckGo) then answer with reCAPTCHA / 429, request, `12.0s` maximum) while limiting retries to one. This can recover slow
providers, but it cannot fix an upstream CAPTCHA or 429 caused by the shared
VPN exit IP. SearXNG queries all ~50 upstream engines from one Gluetun VPN exit
IP. The rate-sensitive engines (Google, DuckDuckGo) then answer with reCAPTCHA / 429,
and SearXNG **suspends** the offending engine for hours to days, which is what and SearXNG **suspends** the offending engine for hours to days, which is what
shows up as "Google went unavailable". This is upstream, not local. shows up as "Google went unavailable". This is upstream, not local.
+3 -3
View File
@@ -21,13 +21,13 @@ valkey:
url: "valkey://searxng-valkey:6379/0" url: "valkey://searxng-valkey:6379/0"
outgoing: outgoing:
request_timeout: 3.0 request_timeout: 4.0
max_request_timeout: 10.0 max_request_timeout: 12.0
pool_connections: 100 pool_connections: 100
pool_maxsize: 20 pool_maxsize: 20
enable_http2: true enable_http2: true
keepalive_expiry: 5.0 keepalive_expiry: 5.0
retries: 3 retries: 1
plugins: plugins:
searx.plugins.unit_converter.SXNGPlugin: searx.plugins.unit_converter.SXNGPlugin:
+13
View File
@@ -57,6 +57,19 @@ assert not missing, f"pass_ip missing {missing}; got {pass_ip}"
PYEOF PYEOF
} }
@test "SearXNG outgoing policy allows modest VPN latency without retry amplification" {
python3 - "$REPO_ROOT/shared/searxng/settings.yml" <<'PYEOF'
import sys, yaml
with open(sys.argv[1]) as fh:
data = yaml.safe_load(fh)
outgoing = data.get("outgoing", {})
assert outgoing.get("request_timeout") == 4.0, outgoing
assert outgoing.get("max_request_timeout") == 12.0, outgoing
assert outgoing.get("retries") == 1, outgoing
assert outgoing["request_timeout"] < outgoing["max_request_timeout"], outgoing
PYEOF
}
@test "deploy.sh copies limiter.toml into /opt/searxng/config" { @test "deploy.sh copies limiter.toml into /opt/searxng/config" {
grep -q "shared/searxng/limiter.toml" "$REPO_ROOT/scripts/deploy.sh" \ grep -q "shared/searxng/limiter.toml" "$REPO_ROOT/scripts/deploy.sh" \
|| { echo "deploy.sh does not copy shared/searxng/limiter.toml"; return 1; } || { echo "deploy.sh does not copy shared/searxng/limiter.toml"; return 1; }