Most “Usenet is slow” problems are not the provider. They are a client that is not reachable, a blocked port, a full disk, or too little RAM for the cache — all things you can rule out in about fifteen seconds with a read-only script.

This is that script. It checks the five things that account for most complaints, prints a plain report, and changes nothing — no files, no settings, no restarts. Read it before you run it; every line is visible below.

What it checks

  • Client reachability — is SABnzbd or NZBGet actually answering on its web port?
  • DNS — does your provider’s news server resolve?
  • Port 563 — is the encrypted Usenet port reachable? If not, downloads cannot start.
  • Port 119 — is the plaintext port needlessly open? You want it closed in favour of 563.
  • Disk and RAM — is there enough headroom for the download and the article cache?

Get it

↓ Download usenet-stack-check.sh

Then run it, optionally pointing it at your own setup:

chmod +x usenet-stack-check.sh
./usenet-stack-check.sh

# with your own details:
SAB_SERVER=news.yourprovider.com DL_PATH=/data/downloads ./usenet-stack-check.sh

The script

#!/usr/bin/env bash
# usenet-stack-check.sh — READ-ONLY health check for a Usenet stack.
# Changes nothing: no writes, no restarts, no settings touched.
# Usage: ./usenet-stack-check.sh
# Env:   SAB_URL, SAB_KEY, NZB_URL, NZB_USER, NZB_PASS,
#        SAB_SERVER, DL_PATH, INCOMPLETE
set -uo pipefail

WARN=0; OK=0
c_ok()   { printf '  [ ok ] %s\n' "$1"; OK=$((OK+1)); }
c_warn() { printf '  [warn] %s\n' "$1"; WARN=$((WARN+1)); }
c_fail() { printf '  [fail] %s\n' "$1"; WARN=$((WARN+1)); }
hdr()    { printf '\n%s\n' "$1"; }
have()   { command -v "$1" >/dev/null 2>&1; }

SAB_URL="${SAB_URL:-http://localhost:8080}"; SAB_KEY="${SAB_KEY:-}"
NZB_URL="${NZB_URL:-http://localhost:6789}"; NZB_USER="${NZB_USER:-}"; NZB_PASS="${NZB_PASS:-}"
SAB_SERVER="${SAB_SERVER:-news.newsgroupdirect.com}"
DL_PATH="${DL_PATH:-}"; INCOMPLETE="${INCOMPLETE:-}"

hdr "Download client"
if have curl; then
  if [ -n "$SAB_KEY" ]; then
    body="$(curl -fsS --max-time 8 "${SAB_URL}/api?mode=version&output=json&apikey=${SAB_KEY}" 2>/dev/null)"
    [ -n "$body" ] && c_ok "SABnzbd API reachable (${body})" || c_warn "SABnzbd API not answering at ${SAB_URL}"
  else
    code="$(curl -s -o /dev/null -w '%{http_code}' --max-time 8 "${SAB_URL}/" 2>/dev/null)"
    [ "$code" != "000" ] && [ -n "$code" ] && c_ok "SABnzbd UI responds (HTTP ${code})" || c_warn "nothing at ${SAB_URL}"
  fi
  code="$(curl -s -o /dev/null -w '%{http_code}' --max-time 8 "${NZB_URL}/" 2>/dev/null)"
  [ "$code" != "000" ] && [ -n "$code" ] && c_ok "NZBGet UI responds (HTTP ${code})" || c_warn "nothing at ${NZB_URL}"
fi

hdr "Provider connectivity"
if have dig; then ip="$(dig +short +time=3 +tries=1 "$SAB_SERVER" A 2>/dev/null | head -n1)"
else ip="$(getent hosts "$SAB_SERVER" 2>/dev/null | awk '{print $1}' | head -n1)"; fi
[ -n "$ip" ] && c_ok "DNS: ${SAB_SERVER} -> ${ip}" || c_fail "DNS could not resolve ${SAB_SERVER}"

port_open() { if have nc; then nc -z -w "$3" "$1" "$2" >/dev/null 2>&1
  else (exec 3<>"/dev/tcp/$1/$2") >/dev/null 2>&1 && exec 3<&- 3>&-; fi; }

port_open "$SAB_SERVER" 563 8 && c_ok "port 563 (SSL) reachable" || c_fail "port 563 NOT reachable"
port_open "$SAB_SERVER" 119 5 && c_warn "port 119 (plaintext) also open" || c_ok "port 119 closed (good)"

hdr "Disk and memory"
if [ -r /proc/meminfo ]; then
  m="$(awk '/MemAvailable/ {print int($2/1024)}' /proc/meminfo)"
  [ "${m:-0}" -lt 1024 ] && c_warn "only ${m} MB RAM available" || c_ok "${m} MB RAM available"
fi
if [ -n "$DL_PATH" ] && [ -d "$DL_PATH" ]; then
  gb=$(( $(df -Pk "$DL_PATH" | awk 'NR==2 {print $4}') / 1024 / 1024 ))
  [ "$gb" -lt 10 ] && c_warn "${DL_PATH}: only ${gb} GB free" || c_ok "${DL_PATH}: ${gb} GB free"
fi

hdr "Summary"
printf '  passed: %d   warnings/failures: %d\n' "$OK" "$WARN"
[ "$WARN" -eq 0 ] && exit 0 || exit 1

(The downloadable version above is the full script, including the coloured output and the extra per-path and per-tool checks — this listing is the condensed form for reading.)

What to do with the result

  • Port 563 failing — check the server hostname against your provider’s account page, then your router/firewall. Nothing else works until this passes.
  • Port 119 open — switch the client to 563 with SSL. See the SSL section of the setup guide.
  • Low RAM warning — reduce the article cache, or move the client to a box with more memory. See the config builder for a size that matches your line.
  • Low disk warning — incomplete downloads plus PAR2 repair can need more than the release size. Clear space before you start a large queue.

If everything passes and it is still slow, the bottleneck is the backbone or the route — which is a provider question, not a client one. Compare providers with the comparison tool.

Frequently asked questions

Is this script safe to run?

Yes. It is strictly read-only: it makes no changes, creates no files, restarts nothing and touches no settings. It only checks connectivity, disk and memory and prints a report. You can read every line before running it.

What does it actually check?

Five things that cause most 'my Usenet is slow or broken' complaints: whether SABnzbd/NZBGet is answering, whether your provider resolves in DNS and accepts connections on port 563, whether the plaintext port 119 is needlessly open, and whether you have enough disk and RAM headroom for the download and the article cache.

Why port 563 specifically?

563 is the standard encrypted Usenet port. If it is unreachable, nothing else matters — the download cannot start. The script also flags port 119 being open, because plaintext Usenet is both slower on some UK ISPs and visible in transit; you should be on 563.

Does it need my provider password?

No. It never logs in to your provider — it only checks that the host resolves and the port is open, which needs no credentials. Optionally you can pass a SABnzbd API key to check the client's API rather than just its web page.