Skip to content

Instantly share code, notes, and snippets.

@hexsprite
Created April 17, 2026 17:39
Show Gist options
  • Select an option

  • Save hexsprite/4bd18da914eee1d763e2730457cf3729 to your computer and use it in GitHub Desktop.

Select an option

Save hexsprite/4bd18da914eee1d763e2730457cf3729 to your computer and use it in GitHub Desktop.
Network repro matrix script for comparing intermittent curl timing stalls across Macs
#!/usr/bin/env bash
set -euo pipefail
REQUESTS="${REQUESTS:-15}"
STALL_SECS="${STALL_SECS:-0.5}"
MAX_TIME="${MAX_TIME:-45}"
CONNECT_TIMEOUT="${CONNECT_TIMEOUT:-40}"
OUTFILE="${OUTFILE:-network_repro_$(date +%Y%m%d_%H%M%S).csv}"
usage() {
cat <<'EOF'
Usage:
./network_repro_matrix.sh [requests]
Environment overrides:
REQUESTS=20 Number of requests per target/mode
STALL_SECS=0.5 Threshold used to mark a request as a stall
MAX_TIME=45 curl --max-time
CONNECT_TIMEOUT=40 curl --connect-timeout
OUTFILE=results.csv CSV output path
What it does:
- tests several different sites
- runs each site in normal mode and IPv4-only mode (-4)
- records DNS, connect, TLS, first-byte, and total time
- prints a short summary and writes raw rows to CSV
EOF
}
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
usage
exit 0
fi
if [[ $# -ge 1 ]]; then
REQUESTS="$1"
fi
if ! command -v curl >/dev/null 2>&1; then
echo "curl is required" >&2
exit 1
fi
if ! command -v python3 >/dev/null 2>&1; then
echo "python3 is required" >&2
exit 1
fi
targets=(
"nytimes|https://static01.nyt.com/images/2026/04/15/multimedia/15DC-SURVEILLANCE-vkgp/15DC-SURVEILLANCE-vkgp-threeByTwoMediumAt2X.jpg?format=pjpg&quality=75&auto=webp&disable=upscale"
"google|https://www.google.com/generate_204"
"cloudflare|https://www.cloudflare.com/cdn-cgi/trace"
"apple|https://www.apple.com/library/test/success.html"
"example|https://example.com/"
)
tmpfile="$(mktemp)"
trap 'rm -f "$tmpfile"' EXIT
printf 'label,mode,run,http_code,remote_ip,exit_code,dns,connect,tls,starttransfer,total,stall\n' > "$OUTFILE"
echo "Writing raw results to $OUTFILE"
echo "Requests per target/mode: $REQUESTS"
echo "Stall threshold: ${STALL_SECS}s"
echo
for entry in "${targets[@]}"; do
label="${entry%%|*}"
url="${entry#*|}"
for mode in default ipv4; do
curl_args=()
if [[ "$mode" == "ipv4" ]]; then
curl_args+=("-4")
fi
echo "== $label [$mode] =="
for run in $(seq 1 "$REQUESTS"); do
fmt='http_code=%{http_code} remote_ip=%{remote_ip} dns=%{time_namelookup} connect=%{time_connect} tls=%{time_appconnect} start=%{time_starttransfer} total=%{time_total}'
set +e
result="$(
curl -sS -o /dev/null \
--max-time "$MAX_TIME" \
--connect-timeout "$CONNECT_TIMEOUT" \
"${curl_args[@]}" \
-w "$fmt" \
"$url" 2>&1
)"
curl_exit=$?
set -e
python3 - "$label" "$mode" "$run" "$curl_exit" "$STALL_SECS" "$OUTFILE" "$result" <<'PY'
import csv
import re
import sys
label, mode, run, curl_exit, stall_secs, outfile, result = sys.argv[1:]
fields = {
"http_code": "000",
"remote_ip": "",
"dns": "",
"connect": "",
"tls": "",
"start": "",
"total": "",
}
for key in list(fields):
m = re.search(rf"{key}=([^ \n]+)", result)
if m:
fields[key] = m.group(1)
try:
total = float(fields["total"])
except Exception:
total = float("inf")
stall = "yes" if total > float(stall_secs) else "no"
with open(outfile, "a", newline="") as f:
writer = csv.writer(f)
writer.writerow([
label,
mode,
run,
fields["http_code"],
fields["remote_ip"],
curl_exit,
fields["dns"],
fields["connect"],
fields["tls"],
fields["start"],
fields["total"],
stall,
])
summary = (
f"run{run} total={fields['total']}s "
f"dns={fields['dns']} connect={fields['connect']} "
f"tls={fields['tls']} start={fields['start']} "
f"ip={fields['remote_ip'] or '-'} code={fields['http_code']} "
f"exit={curl_exit}"
)
if stall == "yes":
summary += " STALL"
print(summary)
if curl_exit != "0":
print(result.strip())
PY
done
echo
done
done
python3 - "$OUTFILE" <<'PY'
import csv
import statistics
import sys
from collections import defaultdict
rows = list(csv.DictReader(open(sys.argv[1], newline="")))
groups = defaultdict(list)
for row in rows:
groups[(row["label"], row["mode"])].append(row)
print("Summary:")
for key in sorted(groups):
bucket = groups[key]
totals = []
stalls = 0
connect_over_1 = 0
start_over_1 = 0
for row in bucket:
try:
total = float(row["total"])
totals.append(total)
if total > 0.5:
stalls += 1
except Exception:
pass
try:
if float(row["connect"]) > 1.0:
connect_over_1 += 1
except Exception:
pass
try:
if float(row["starttransfer"]) > 1.0:
start_over_1 += 1
except Exception:
pass
med = statistics.median(totals) if totals else float("nan")
worst = max(totals) if totals else float("nan")
print(
f"- {key[0]:11s} {key[1]:7s} "
f"stalls={stalls}/{len(bucket)} "
f"median={med:.3f}s worst={worst:.3f}s "
f"connect>1s={connect_over_1} start>1s={start_over_1}"
)
PY
echo
echo "Done. Raw rows are in $OUTFILE"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment