Onboarding "feels slow" in the APAC office and "feels fine" in the US office, and without timestamps nobody can say whether the difference is the network, the toolchain, or the documentation. This walkthrough instruments setup latency deterministically so distributed teams can compare like for like and isolate where the friction actually lives. It is the field guide to time-to-first-PR metrics within onboarding architecture and friction mapping.

Diagnostic

Capture bootstrap duration alongside registry latency to separate the two:

#!/usr/bin/env bash
set -euo pipefail
git log --format='%aI' --reverse | head -n 1
( time ./scripts/bootstrap.sh ) 2>&1 | tee setup.log
curl -s -o /dev/null -w 'registry: %{time_total}s\n' https://registry.npmjs.org

Expected BAD output — bootstrap runs long and registry latency spikes:

2024-03-15T09:12:04+00:00
real  18m42.108s
user  0m12.441s
sys   0m4.209s
registry: 2.842s

A real time over ~15m or registry latency over ~2.5s points at regional egress, not repository misconfiguration.

Root Cause

Two distinct problems hide behind one symptom. First, unpinned base images and transitive resolution let node_modules resolve differently per region, especially when a corporate proxy redirects to a slow mirror. Second, raw wall-clock duration conflates network egress with local compute, so a slow ISP route looks identical to a heavy install. There is also a measurement trap underneath both: timestamps captured on hosts whose clocks have drifted — common on WSL2 after hibernate, or on ARM boards without a battery-backed RTC — produce deltas that are simply wrong, and a wrong delta is worse than no delta because it looks authoritative on a dashboard. Without isolating compute from network, and without trustworthy clocks, teams "fix" the wrong layer: they rewrite the bootstrap script when the real cost was a transatlantic registry round-trip, or they chase a phantom regression that was only a desynced clock. Correlating each sample against time-to-first-PR metrics keeps the local-setup number honest against the downstream review-and-merge number.

Resolution

  1. Separate network latency from compute with a path trace to the registry:
    #!/usr/bin/env bash
    set -euo pipefail
    mtr -n -r -c 100 registry.npmjs.org | tail -n +2
    High packet loss or TTL variance is an ISP routing problem; route those contributors through a regional mirror.
  2. Pin runtimes and install strictly from the lockfile so resolution is identical everywhere:
    #!/usr/bin/env bash
    set -euo pipefail
    export npm_config_cache="$HOME/.npm-cache"
    npm ci --prefer-offline
  3. Stamp every run with a trace id so deltas are attributable per contributor and region:
    #!/usr/bin/env bash
    set -euo pipefail
    TRACE_ID=$(uuidgen)
    START=$(date +%s)
    ./scripts/bootstrap.sh
    END=$(date +%s)
    curl -fsS -X POST "$METRICS_ENDPOINT" \
      -H 'Content-Type: application/json' \
      -d "{\"trace_id\":\"$TRACE_ID\",\"duration_s\":$((END-START)),\"region\":\"${AWS_REGION:-unknown}\"}"

Expected Output

After pinning runtimes and routing through a regional mirror, bootstrap lands inside the target window with low registry latency:

real  3m41.902s
registry: 0.214s
{"trace_id":"a1b2c3d4-...","duration_s":221,"region":"ap-southeast-1"}

Prevention

  1. Inject the trace id and timing into .devcontainer/postCreateCommand.sh so collection is automatic, not manual.
  2. Validate each run against an SLO (< 15m first-run) and alert when regional p95 exceeds 25m.
  3. Reject PRs whose commit metadata lacks an ONBOARDING_TRACE_ID, enforcing traceability across regions.

WSL2: keep the repo on the Linux filesystem and confirm systemd-timesyncd is active so timestamps from Windows hosts are trustworthy. Apple Silicon (ARM64): record process.arch with each sample so arm64 laptops are not averaged together with amd64 CI runners. macOS (Docker Desktop): if measuring inside a container, mount /etc/localtime read-only to keep timezone consistent with the host.

Rollback

#!/usr/bin/env bash
set -euo pipefail
rm -f ~/.onboarding/telemetry.json
sed -i.bak '/ONBOARDING_START_TS/d' ~/.zshrc
unset ONBOARDING_TRACE_ID ONBOARDING_START_TS