WooCommerce 503-Fehler: Wenn Bots den Shop lahmlegen

Vor Kurzem hatte ich einen Fall, der mich ein paar Stunden beschäftigt hat: Ein WooCommerce-Shop lief immer wieder in 503-Fehler. Sporadisch, ohne klares Muster – mal stundenlang stabil, dann plötzlich nicht mehr erreichbar. Der Schuldige war kein Plugin-Konflikt, kein Memory-Limit. Es waren Suchmaschinen-Bots.

Das Problem: Bots und Filter-URLs

WooCommerce-Filter-Widgets sind praktisch. Besucher filtern nach Preis, Farbe, Größe – alles fein. Das Problem: Suchmaschinen-Bots sehen diese Filter als eigenständige URLs und crawlen jede erdenkliche Kombination.

https://shop.de/produkte/?filter_farbe=rot
https://shop.de/produkte/?filter_farbe=rot&filter_groesse=xl
https://shop.de/produkte/?filter_farbe=rot&filter_groesse=xl&min_price=20
https://shop.de/produkte/?filter_farbe=rot&filter_groesse=xl&min_price=20&max_price=100

In meinem Fall waren es bis zu 8 kombinierte Parameter pro Anfrage. Jede URL löst eigene Datenbankabfragen aus – WooCommerce muss die Produktliste jedes Mal neu zusammenstellen. Kommen Googlebot und Bingbot gleichzeitig, bricht die Datenbank unter der Last zusammen. 503-Fehler am laufenden Band.

Lösung 1: robots.txt

Die schnellste Maßnahme. Gefilterte URLs einfach aussperren – Bots crawlen sie dann gar nicht erst:

User-agent: *
Disallow: /?*filter_*
Disallow: /?*orderby=*
Disallow: /?*min_price=*
Disallow: /?*max_price=*

Wirkt nicht sofort – Bots müssen die robots.txt erst neu abrufen. Bei großen Crawlern passiert das meist innerhalb weniger Tage.

Lösung 2: Yoast SEO – URL-Parameter auf noindex

Wer Yoast im Einsatz hat, kann gefilterte URLs zusätzlich mit noindex markieren. Selbst wenn ein Bot die Seite crawlt, landet sie nicht im Index.

Einzustellen unter SEO → Erscheinungsbild der Suche → URL-Parameter – alle Filter-Parameter eintragen und auf „ignorieren“ stellen.

Lösung 3: Canonical URL erzwingen

Für alle gefilterten Shop-Seiten eine Canonical URL auf die Hauptshop-Seite setzen. Google weiß dann: Das ist keine eigenständige Seite.

add_filter( 'woocommerce_product_query_tax_query', function( $tax_query ) {
	if ( is_admin() ) return $tax_query;

	if ( !empty( $_GET ) ) {
		add_action( 'wp_head', function() {
			$canonical = get_permalink( wc_get_page_id( 'shop' ) );
			echo '<link rel="canonical" href="' . esc_url( $canonical ) . '" />' . "\n";
		} );
	}

	return $tax_query;
} );

Lösung 4: Filter-Anfragen cachen

Wenn Bots trotzdem crawlen, hilft ein einfacher Transient-Cache. Die DB wird nur beim ersten Aufruf einer Kombination belastet – alle weiteren Anfragen bekommen das gecachte Ergebnis:

add_filter( 'woocommerce_product_query_meta_query', function( $meta_query ) {
	if ( empty( $_GET ) ) return $meta_query;

	$cache_key = 'wc_filter_' . md5( serialize( $_GET ) );
	$cached    = get_transient( $cache_key );

	if ( $cached !== false ) return $cached;

	set_transient( $cache_key, $meta_query, HOUR_IN_SECONDS );

	return $meta_query;
} );

Lösung 5: Rate Limiting auf Serverebene (Nginx)

Wer Root-Zugriff hat, kann Bot-Traffic direkt auf Serverebene drosseln. Anfragen mit Filter-Parametern werden auf 1 Request pro Sekunde begrenzt – für echte Nutzer kaum merkbar:

limit_req_zone $http_user_agent zone=bots:10m rate=1r/s;

location ~* \?(.*filter.*|.*orderby.*|.*min_price.*) {
    limit_req zone=bots burst=5;
}

Meine Empfehlung

Nicht alles passt zu jedem Setup. Ich würde in dieser Reihenfolge vorgehen:

  1. robots.txt anpassen – sofort umsetzbar, kein Code, kein Risiko.
  2. Yoast URL-Parameter konfigurieren – damit bereits gecrawlte URLs aus dem Index verschwinden.
  3. Canonical URLs per Code – für saubere SEO-Signale an Google.
  4. Transient-Cache – wenn die DB-Last trotzdem hoch bleibt.
  5. Nginx Rate Limiting – nur bei Root-Zugriff, als letzte Verteidigungslinie.

Fazit

WooCommerce-Filter ohne Schutzmechanismen sind eine offene Einladung für unkontrollierten Bot-Traffic. Wer sporadische 503-Fehler hat und nicht weiterkommt, sollte als erstes die Server-Logs auf Crawler-Aktivität prüfen und die robots.txt auf Filter-Parameter untersuchen. In meinem Fall war genau das die Ursache – und die Lösung war einfacher als erwartet.