Redirect Chain: How I Cut 3 Hops to 1 and Improved Crawl Budget
A silent configuration error affecting almost every Netlify site. The chain http://www → https://www → https://non-www was wasting crawl budget and diluting link equity. Fixed in one line.
Durante l'audit di smartweb-media.com, ho trovato un problema che probabilmente non avrei notato senza controllare i redirect manualmente. Il sito aveva tre hop invece di uno per chiunque arrivasse dall'URL con www in HTTP.
Singolarmente, ogni redirect era corretto. Il problema era la combinazione: Netlify gestisce HTTPS automaticamente, ma non elimina automaticamente la catena www → non-www + HTTP → HTTPS in un unico salto.
Il fix ha richiesto una riga. Ma prima di arrivare alla soluzione, vale la pena capire perché questo conta — e come individuarlo su qualsiasi sito.
The Problem: Three Redirects Instead of One
Here's the complete redirect chain I found on smartweb-media.com:
redirect chain — BEFORE the fix
http://www.smartweb-media.com/ → 301 → https://www.smartweb-media.com/ (hop 1: HTTP→HTTPS) → 301 → https://smartweb-media.com/ (hop 2: www→non-www) → 200 [pagina finale] http://smartweb-media.com/ → 301 → https://smartweb-media.com/ (hop 1: HTTP→HTTPS) → 200 [pagina finale] https://www.smartweb-media.com/ → 301 → https://smartweb-media.com/ (hop 1: www→non-www) → 200 [pagina finale]
The last two cases are fine — un solo hop. Il primo caso (http://www) è quello problematico: due redirect prima di arrivare alla destinazione finale.
To verify it, the most direct command is curl:
verify redirect chain
# Mostra tutti i redirect nella catena
curl -sI -L http://www.tuosito.com/ | grep -i "HTTP/\|location"
# Output atteso (catena con problemi):
# HTTP/1.1 301 Moved Permanently
# location: https://www.tuosito.com/
# HTTP/2 301
# location: https://tuosito.com/
# HTTP/2 200
# Output ideale (un solo hop):
# HTTP/1.1 301 Moved Permanently
# location: https://tuosito.com/
# HTTP/2 200
Why Redirect Chains Hurt SEO
1. Wasted Crawl Budget
Googlebot has a limited request budget per site. Each hop in a redirect chain consumes a separate request. Se hai 1000 link che puntano alla versione http://www del tuo sito (da vecchi backlink, da sitemap mal configurate, da link interni non aggiornati), stai facendo sprecare a Googlebot il doppio delle richieste necessarie.
For small sites the impact is minimal. For sites with thousands of pages, a systematic redirect chain can mean pages not crawled because the budget ran out first.
2. Link Equity Dilution
Google passes link "weight" through 301 redirects, but not at 100%. Ogni hop aggiuntivo comporta una piccola perdita di autorità del link. Con un singolo hop la perdita è trascurabile. Con catene più lunghe — o con molti link che puntano alla versione sbagliata — l'accumulo diventa rilevante.
estimated link equity impact
Link equity con 1 hop: ~99% preservato Link equity con 2 hop: ~97-98% preservato Link equity con 3 hop: ~95-96% preservato Link equity con 4+ hop: rischio penalizzazione
3. Latency for Real Users
Each redirect adds tens of milliseconds of latency. Non abbastanza da essere visibile normalmente, ma abbastanza da peggiorare le metriche di Core Web Vitals — in particolare TTFB (Time to First Byte) — per chi arriva dalla versione http://www.
The Netlify Fix: One Line in the _redirects File
Netlify automatically handles the HTTP→HTTPS redirect for the main domain. Ma non gestisce automaticamente www→non-www in un singolo hop partendo da HTTP. La soluzione è aggiungere esplicitamente questa regola nel file _redirects alla radice del progetto:
_redirects — fix completo
# Fix redirect chain: www → non-www in un hop diretto
# Il ! forza il redirect anche se esiste già una regola di matching
https://www.smartweb-media.com/* https://smartweb-media.com/:splat 301!
# Altri redirect del sito (invariati)
/index-en.html /en/ 301
/blog-en.html /en/blog.html 301
# ... ecc.
Il parametro :splat cattura tutto il path dopo il dominio e lo preserva nella destinazione. Il ! alla fine forza il redirect anche se Netlify avrebbe altrimenti dato priorità ad altre regole.
Il risultato dopo il fix:
redirect chain — AFTER the fix
http://www.smartweb-media.com/qualsiasi/path → 301 → https://smartweb-media.com/qualsiasi/path → 200 [pagina finale] ✅ Un solo hop. Crawl budget preservato. Link equity massimizzata.
How to Verify the Fix
After deploying on Netlify (automatic after push), verify with curl:
post-fix verification
# Test 1: http www (era il caso problematico)
curl -sI -L http://www.smartweb-media.com/ | grep -i "HTTP/\|location"
# Risultato atteso:
# HTTP/1.1 301
# location: https://smartweb-media.com/
# HTTP/2 200
# Test 2: https www
curl -sI -L https://www.smartweb-media.com/ | grep -i "HTTP/\|location"
# Risultato atteso:
# HTTP/2 301
# location: https://smartweb-media.com/
# HTTP/2 200
# Test 3: http non-www (deve funzionare ancora)
curl -sI -L http://smartweb-media.com/ | grep -i "HTTP/\|location"
# Risultato atteso:
# HTTP/1.1 301
# location: https://smartweb-media.com/
# HTTP/2 200
# Test 4: path specifico preservato?
curl -sI http://www.smartweb-media.com/blog/articolo.html | grep "location"
# Risultato atteso:
# location: https://smartweb-media.com/blog/articolo.html
Redirect Chains on Other Hosts: Apache and Nginx
If you don't use Netlify, the fix changes files but the logic is identical. L'obiettivo è sempre: gestire http+www → https+non-www in un singolo redirect permanente.
Apache (.htaccess)
.htaccess
RewriteEngine On
# Redirect tutto http → https (incluso www)
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# Redirect www → non-www (solo su https)
RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L]
Attenzione: queste due regole vengono eseguite in sequenza nella stessa richiesta. Quindi http://www finisce in due redirect anche con Apache, se scritto così. Per un singolo hop su Apache:
.htaccess — singolo hop
RewriteEngine On
# Caso 1: http + www → https + non-www (singolo hop)
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L]
# Caso 2: http + non-www → https + non-www
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^(?!www\.)(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L]
# Caso 3: https + www → https + non-www
RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L]
Nginx
nginx.conf
# Server block per http (entrambe le versioni)
server {
listen 80;
server_name www.tuosito.com tuosito.com;
# Redirect tutto http → https non-www in un hop
return 301 https://tuosito.com$request_uri;
}
# Server block per https www
server {
listen 443 ssl;
server_name www.tuosito.com;
# Redirect https www → https non-www
return 301 https://tuosito.com$request_uri;
}
# Server block principale
server {
listen 443 ssl;
server_name tuosito.com;
# ... configurazione normale
}
Python Script: Redirect Chain Audit for the Entire Site
If you want to automatically verify all site URLs (not just the homepage), use this script that reads the sitemap and checks each URL:
check_redirects.py
import requests
import xml.etree.ElementTree as ET
from urllib.parse import urlparse
def get_redirect_chain(url, max_hops=10):
"""Segue tutti i redirect e restituisce la catena completa."""
chain = []
current_url = url
session = requests.Session()
session.max_redirects = max_hops
for i in range(max_hops):
try:
resp = session.head(current_url, allow_redirects=False,
timeout=10, headers={'User-Agent': 'Mozilla/5.0'})
chain.append({'url': current_url, 'status': resp.status_code})
if resp.status_code in (301, 302, 307, 308):
location = resp.headers.get('Location', '')
if not location:
break
# Gestisci URL relativi
if location.startswith('/'):
parsed = urlparse(current_url)
location = f"{parsed.scheme}://{parsed.netloc}{location}"
current_url = location
else:
break
except Exception as e:
chain.append({'url': current_url, 'status': f'ERR: {e}'})
break
return chain
def audit_sitemap_redirects(sitemap_url):
"""Controlla redirect chain per ogni URL nella sitemap."""
resp = requests.get(sitemap_url, timeout=10)
root = ET.fromstring(resp.content)
ns = {'sm': 'http://www.sitemaps.org/schemas/sitemap/0.9'}
urls = [loc.text for loc in root.findall('.//sm:loc', ns)]
print(f"Audit redirect chain su {len(urls)} URL dalla sitemap\n")
problems = []
for url in urls:
chain = get_redirect_chain(url)
hops = len(chain) - 1 # -1 perché l'ultimo è la destinazione finale
if hops > 1:
problems.append({'url': url, 'hops': hops, 'chain': chain})
print(f"⚠️ {hops} hop: {url}")
for step in chain:
print(f" → {step['status']} {step['url']}")
elif hops == 1:
final = chain[-1]['url']
if final != url:
print(f"✅ 1 hop OK: {url} → {final}")
else:
print(f"✅ Diretto: {url}")
print(f"\n{'='*60}")
print(f"Problemi trovati: {len(problems)} URL con redirect chain multipla")
return problems
# Uso
if __name__ == '__main__':
problems = audit_sitemap_redirects('https://smartweb-media.com/sitemap.xml')
The Bottom Line
A 2-3 hop redirect chain won't tank your rankings by itself. Ma è un problema che si accumula silenziosamente: ogni link esterno che punta alla versione sbagliata dell'URL porta meno autorità del necessario. Ogni crawl spreca richieste. Ogni utente su connessione lenta aspetta qualche decina di millisecondi in più.
The fix takes five minutes. There's no reason to leave it there.
Want a Complete Technical Audit of Your Site?
Redirect chains, canonicals, sitemap, schema markup, crawl budget — I analyze everything and deliver a prioritized fix list with impact estimates.
Request Free Audit