Claude Code Performance: Code optimieren und Bottlenecks finden mit KI
Performance-Probleme sind heimtückisch: Sie erscheinen selten dort, wo man sucht. Eine Seite lädt langsam — aber liegt es am Datenbankquery, am JavaScript-Bundle, am fehlenden Index, oder am N+1-Problem im ORM? Die Antwort auf diese Frage kann Stunden dauern, wenn man sie manuell durchsucht. Mit Claude Code Performance-Analyse verkürzt sich dieser Prozess drastisch, weil das Tool den gesamten Kontext auf einmal sieht: Code, Datenbankschema, Build-Konfiguration, Profiling-Ergebnisse.
Dieser Artikel zeigt konkret, wie Claude Code bei den sechs häufigsten Performance-Themen hilft: Profiling und Bottleneck-Analyse, Algorithmus-Optimierung, Datenbankabfragen, Caching-Strategien, Frontend-Performance und asynchrone Verarbeitung. Kein theoretisches Konzept — konkrete Prompts und reale Ergebnisse.
Claude Code Mastery — Performance, Agents, Hooks auf Deutsch
Der Kurs zeigt, wie du Claude Code wirklich produktiv einsetzt — für Performance-Arbeit, autonome Agents und professionelle Workflows. Einmalig bezahlt, kein Abo.
Zum Kurs — ab €29 → Basis ab €29 · Pro ab €49 · Kein Abo · 14 Tage Rückgaberecht1. Profiling und Bottleneck-Analyse
Performance-Optimierung ohne Profiling ist Raten. Bevor man irgendetwas ändert, muss man wissen, wo die Zeit tatsächlich verloren geht — nicht wo man es vermutet. Claude Code hilft dabei auf zwei Ebenen: beim Einrichten des richtigen Profiling-Tools und beim Interpretieren der Ergebnisse.
Python: py-spy und cProfile
Für Python-Anwendungen sind py-spy und cProfile die wichtigsten Profiling-Tools. py-spy läuft ohne Code-Änderung direkt gegen einen laufenden Prozess:
py-spy record -o profile.svg --pid $(pgrep -f myapp.py) --duration 30
Das erzeugte Flamegraph-SVG zeigt sofort, welche Funktionen die meiste Zeit verbrauchen. Übergib es an Claude Code:
claude "Analysiere diesen py-spy Output und erkläre die drei größten Bottlenecks:
$(cat profile.txt)"
Claude Code liest die Profiling-Daten, identifiziert die Hot Paths und erklärt, warum diese Pfade so viel Zeit verbrauchen — meist weil sie O(n²)-Operationen in Schleifen ausführen oder Datenbankzugriffe wiederholen, die einmal reichen würden.
JVM: async-profiler
Für Java- und Kotlin-Anwendungen liefert async-profiler CPU- und Speicher-Flamegraphs ohne Overhead:
./asprof -e cpu -d 30 -f profile.html $(jps | grep MyApp | cut -d' ' -f1)
claude "Ich habe einen async-profiler HTML-Report. Welche Methoden verbrauchen
am meisten CPU und was sind mögliche Ursachen?" < profile_summary.txt
Browser: Chrome DevTools Performance Tab
Im Browser ist der Performance Tab in Chrome DevTools das Standardwerkzeug. Aufzeichnung exportieren, als JSON oder Screenshot übergeben:
claude "Dieses Performance-Trace zeigt eine lange Task-Blockade im Main Thread.
Was ist die Ursache und wie kann ich die Arbeit aufteilen?
[Performance-Trace-Daten einfügen]"
Reihenfolge bei Performance-Problemen: Erst messen, dann optimieren. Claude Code kann nicht raten, ob ein Problem im Backend, Frontend, der Datenbank oder im Netzwerk liegt — aber es kann Profiling-Daten sehr schnell interpretieren und die Ursache benennen. Das Profiling-Setup ist deshalb der erste Schritt, nicht der letzte.
2. Algorithmus-Optimierung und Komplexität
Viele Performance-Probleme entstehen nicht durch schlechte Infrastruktur, sondern durch ineffiziente Algorithmen. Eine O(n²)-Operation, die bei 100 Elementen kaum auffällt, wird bei 10.000 Elementen zum Showstopper. Claude Code erkennt diese Muster zuverlässig — auch dann, wenn der Code auf den ersten Blick harmlos aussieht.
claude "Analysiere diese Funktion auf Zeitkomplexität und schlage
eine effizientere Implementierung vor:
def find_duplicates(items):
duplicates = []
for i in range(len(items)):
for j in range(i + 1, len(items)):
if items[i] == items[j] and items[i] not in duplicates:
duplicates.append(items[i])
return duplicates"
Claude Code erkennt hier sofort drei Probleme: die verschachtelte Schleife (O(n²)), das in-Check auf einer Liste (ebenfalls O(n) statt O(1) bei einem Set), und den redundanten Duplikat-Check. Die Antwort liefert die optimierte Version:
# O(n) statt O(n³) — drei Ebenen Verbesserung
def find_duplicates(items):
seen = set()
duplicates = set()
for item in items:
if item in seen:
duplicates.add(item)
seen.add(item)
return list(duplicates)
Besonders wertvoll ist Claude Code bei Algorithmen, die über mehrere Funktionen und Dateien verteilt sind. Ein O(n)-Lookup der mitten in einer Schleife steckt, die selbst in einer anderen Funktion aufgerufen wird — das ist schwer zu sehen, wenn man nur einzelne Dateien liest. Claude Code liest die gesamte Aufrufkette und findet das Problem an der Wurzel.
Datenstrukturen gezielt wählen
Ein häufiger Fall: Eine Liste wird verwendet, wo ein Dictionary oder Set die bessere Wahl wäre. Übergib einfach die relevanten Dateien:
claude "Schau dir diese Datei an und identifiziere alle Stellen, wo
Listen für Lookup-Operationen verwendet werden, obwohl ein Set oder
Dict effizienter wäre. Zeige konkrete Umstellungen."
"In Zeile 47 verwendest duif user_id in active_users_listin einer Schleife. Daactive_users_list50.000 Einträge haben kann, ist das O(n) pro Iteration — insgesamt O(n²). Konvertiereactive_users_listeinmalig vor der Schleife in ein Set, dann ist jeder Lookup O(1)."
3. Datenbankabfragen optimieren
Datenbankprobleme sind die häufigste Ursache für langsame Webanwendungen. Drei Muster stehen dabei ganz oben: fehlende Indizes, nicht analysierte Queries, und das N+1-Problem in ORMs. Claude Code kennt alle drei und findet sie auch dann, wenn sie gut versteckt sind.
Fehlende Indizes erkennen
Übergib Schema und die langsamen Queries:
claude "Diese Query läuft auf einer Tabelle mit 2 Millionen Rows und braucht 8 Sekunden.
Welche Indizes fehlen?
Schema:
CREATE TABLE orders (
id BIGINT PRIMARY KEY,
user_id BIGINT NOT NULL,
status VARCHAR(20) NOT NULL,
created_at TIMESTAMP NOT NULL,
total_amount DECIMAL(10,2)
);
Query:
SELECT * FROM orders
WHERE user_id = 12345
AND status = 'pending'
ORDER BY created_at DESC
LIMIT 20;"
Claude Code analysiert den Ausführungsplan gedanklich, erkennt dass user_id und status zusammen gefiltert werden, und empfiehlt einen Composite-Index:
CREATE INDEX idx_orders_user_status_date
ON orders (user_id, status, created_at DESC);
Mit diesem Index sinkt die Query von einem Full-Table-Scan auf einen Index-Scan über wenige Rows.
Query-Analyse mit EXPLAIN
Noch besser: EXPLAIN-Output direkt übergeben. PostgreSQL, MySQL und SQLite haben alle einen EXPLAIN-Befehl:
psql -c "EXPLAIN ANALYZE SELECT ..." | claude "Was ist das Performance-Problem in diesem Query-Plan?"
Claude Code liest Seq Scans, Hash Joins, und Nested Loops und erklärt präzise, welcher Teil des Plans ineffizient ist und warum. Kein manuelles Interpretieren von Row-Estimates und Cost-Werten mehr.
Das N+1-Problem in ORMs
Das N+1-Problem ist das häufigste Performance-Anti-Pattern in Anwendungen mit ORM (Django ORM, ActiveRecord, Hibernate, Sequelize). Es entsteht, wenn man für eine Liste von Objekten jede verknüpfte Ressource einzeln lädt:
claude "Schau dir diesen Django-View an und identifiziere N+1-Probleme.
Zeige die optimierte Version mit select_related oder prefetch_related:
def order_list(request):
orders = Order.objects.filter(user=request.user)
result = []
for order in orders:
result.append({
'id': order.id,
'customer': order.customer.name, # N+1: 1 Query pro Order
'items': [i.name for i in order.items.all()], # N+1: 1 Query pro Order
})
return JsonResponse({'orders': result})"
Claude Code zeigt die optimierte Version, die statt N+2 Queries nur 3 ausführt:
def order_list(request):
orders = Order.objects.filter(user=request.user)\
.select_related('customer')\
.prefetch_related('items')
result = []
for order in orders:
result.append({
'id': order.id,
'customer': order.customer.name,
'items': [i.name for i in order.items.all()],
})
return JsonResponse({'orders': result})
N+1 ist schwer zu sehen: Das Problem entsteht nicht im ORM-Call selbst, sondern in der Schleife danach. Ein Tool wie Django Debug Toolbar oder das Logging von SQL-Queries hilft beim Erkennen. Frag Claude Code: "Wie aktiviere ich SQL-Logging in [Framework], damit ich N+1-Probleme sehe?"
4. Caching-Strategien
Caching ist die schnellste Performance-Verbesserung — aber nur, wenn man die richtige Ebene wählt. In-Memory-Cache, Redis, HTTP-Caching und CDN haben verschiedene Trade-offs. Claude Code hilft dabei, die richtige Strategie für den jeweiligen Use Case zu wählen und korrekt zu implementieren.
In-Memory-Caching
Für Werte die teuer zu berechnen sind und sich selten ändern, ist In-Memory-Caching die einfachste Lösung. Python hat functools.lru_cache, JavaScript Map-basierte Caches:
claude "Diese Funktion wird tausende Male pro Sekunde aufgerufen und
liefert für gleiche Inputs immer dasselbe Ergebnis. Wie implementiere
ich einen effizienten In-Memory-Cache mit TTL?
def calculate_user_tier(user_id: int) -> str:
user = db.fetch_user(user_id)
purchases = db.fetch_purchase_history(user_id, days=90)
return compute_tier(user, purchases)"
Claude Code zeigt eine Cache-Implementierung mit TTL und automatischer Invalidierung, angepasst an den konkreten Code:
from functools import lru_cache
from cachetools import TTLCache
import threading
_cache = TTLCache(maxsize=10_000, ttl=300) # 5 Minuten TTL
_lock = threading.Lock()
def calculate_user_tier(user_id: int) -> str:
with _lock:
if user_id in _cache:
return _cache[user_id]
user = db.fetch_user(user_id)
purchases = db.fetch_purchase_history(user_id, days=90)
result = compute_tier(user, purchases)
with _lock:
_cache[user_id] = result
return result
Redis für verteilte Systeme
Sobald mehrere Server-Instanzen laufen, reicht In-Memory-Cache nicht mehr — jede Instanz hat ihren eigenen, inkonsistenten Stand. Redis ist die Standardlösung für verteiltes Caching:
claude "Wir haben eine Flask-App auf 4 Pods. Die calculate_user_tier-Funktion
muss gecacht werden, aber konsistent über alle Pods. Zeig mir eine Redis-Cache-
Implementierung mit Cache-Stampede-Schutz."
Claude Code erklärt den Cache-Stampede (wenn der Cache abläuft und alle Pods gleichzeitig die teure Berechnung starten) und zeigt die Lösung mit einem Lock-Pattern:
import redis
import json
import time
r = redis.Redis(host='redis', port=6379, decode_responses=True)
CACHE_TTL = 300
LOCK_TTL = 10
def calculate_user_tier(user_id: int) -> str:
cache_key = f"user_tier:{user_id}"
lock_key = f"lock:user_tier:{user_id}"
cached = r.get(cache_key)
if cached:
return json.loads(cached)
# Cache-Stampede-Schutz: nur ein Worker berechnet neu
if r.set(lock_key, "1", nx=True, ex=LOCK_TTL):
try:
user = db.fetch_user(user_id)
purchases = db.fetch_purchase_history(user_id, days=90)
result = compute_tier(user, purchases)
r.setex(cache_key, CACHE_TTL, json.dumps(result))
return result
finally:
r.delete(lock_key)
else:
# Anderer Worker rechnet gerade — kurz warten, dann nochmal prüfen
time.sleep(0.1)
return calculate_user_tier(user_id)
HTTP-Caching und Cache-Control
Für API-Responses und statische Ressourcen ist HTTP-Caching die effizienteste Lösung, weil sie Anfragen vollständig vermeidet:
claude "Welche Cache-Control-Header sind für diese Ressourcentypen optimal?
- Produktbilder (ändern sich selten)
- API-Response /api/products (ändert sich täglich)
- Nutzerspezifische API-Response /api/user/cart (ändert sich häufig)
- Static Assets (JS/CSS mit Content-Hash im Filename)"
Claude Code gibt für jeden Typ eine begründete Empfehlung — und erklärt den Unterschied zwischen max-age, s-maxage, stale-while-revalidate und no-cache vs. no-store.
5. Frontend-Performance und Core Web Vitals
Google bewertet Seiten nach Core Web Vitals: Largest Contentful Paint (LCP), Cumulative Layout Shift (CLS) und Interaction to Next Paint (INP). Schlechte Werte kosten Ranking. Claude Code hilft dabei, Bundle-Size zu reduzieren, Lazy Loading korrekt zu implementieren und die Vitals zu verbessern.
Bundle-Size analysieren und reduzieren
npx webpack-bundle-analyzer stats.json | claude "Welche Pakete machen
den größten Teil des Bundles aus und wie kann ich sie reduzieren?"
Oder direkt mit dem Build-Output:
npm run build 2>&1 | claude "Das Bundle ist 2.4 MB. Welche Optimierungen
empfiehlst du, um es unter 500 KB zu bringen?"
Claude Code liest die Package-Größen, identifiziert die größten Kandidaten für Tree-Shaking oder Code-Splitting, und gibt konkrete Empfehlungen: welche Pakete durch kleinere Alternativen ersetzt werden können (moment.js durch date-fns, lodash durch native Methoden), und wo Dynamic Imports sinnvoll sind.
Lazy Loading und Code-Splitting
claude "Ich habe eine React-App mit 15 Routes. Nur die Home-Page ist
kritisch für den First Load. Zeig mir, wie ich React.lazy und Suspense
für die anderen Routes einsetze, um den initialen Bundle zu halbieren."
Claude Code liest die Router-Konfiguration und gibt die konkrete Umbauanleitung — nicht generisch, sondern angepasst an die vorhandenen Import-Pfade und Component-Namen.
Core Web Vitals verbessern
LCP-Probleme entstehen meist durch große, unoptimierte Bilder oder render-blockierendes JavaScript. CLS durch Elemente ohne definierte Größen. INP durch lange JavaScript-Tasks im Main Thread.
claude "PageSpeed Insights meldet LCP 4.2s (sollte unter 2.5s sein).
Der LCP-Kandidat ist das Hero-Image. Was sind die häufigsten Ursachen
und welche Optimierungen soll ich zuerst prüfen?"
Für ein vollständiges Audit kannst du die Lighthouse-JSON direkt übergeben:
lighthouse https://example.com --output json --output-path report.json
cat report.json | claude "Was sind die drei wichtigsten Findings aus diesem
Lighthouse-Report und wie behebe ich sie?"
LCP-Schnellcheck: Das häufigste LCP-Problem ist ein Bild ohne fetchpriority="high" und ohne preload-Link im <head>. Frag Claude Code: "Prüf mein HTML-Template darauf, ob das LCP-Element korrekt priorisiert wird."
6. Concurrency und asynchrone Verarbeitung
Moderner Code ist selten single-threaded. I/O-bound Operationen — API-Calls, Datenbankzugriffe, Datei-Reads — können parallel ausgeführt werden. CPU-bound Operationen können auf Worker-Threads oder Prozesse ausgelagert werden. Claude Code erkennt, wo sequenzielle Ausführung unnötig Wartezeit erzeugt.
Sequenzielle I/O parallelisieren
claude "Dieser Code ruft drei externe APIs sequenziell auf.
Wie stelle ich auf parallele Ausführung um?
async function getDashboardData(userId) {
const user = await fetchUser(userId);
const orders = await fetchOrders(userId);
const recommendations = await fetchRecommendations(userId);
return { user, orders, recommendations };
}"
Claude Code erkennt, dass die drei Calls unabhängig voneinander sind, und gibt die optimierte Version mit Promise.all:
async function getDashboardData(userId) {
const [user, orders, recommendations] = await Promise.all([
fetchUser(userId),
fetchOrders(userId),
fetchRecommendations(userId),
]);
return { user, orders, recommendations };
}
Statt dreier sequenzieller Warzeiten (z.B. 200ms + 150ms + 180ms = 530ms) reduziert sich die Gesamtwartezeit auf das Maximum der drei (180ms). Das ist ohne Code-Änderung am Ergebnis eine fast 3x-Beschleunigung.
Python: asyncio und Concurrent.futures
claude "Ich habe eine Python-Funktion die für 500 URLs jeweils einen
HTTP-Request macht. Aktuell sequenziell: ~8 Minuten. Zeig mir die
asyncio-Version mit einem sinnvollen Concurrency-Limit."
Claude Code gibt die asyncio-Implementierung mit einem Semaphor als Concurrency-Limit:
import asyncio
import aiohttp
async def fetch_urls(urls: list[str], max_concurrent: int = 50) -> list[dict]:
semaphore = asyncio.Semaphore(max_concurrent)
async def fetch_one(session: aiohttp.ClientSession, url: str) -> dict:
async with semaphore:
async with session.get(url, timeout=aiohttp.ClientTimeout(total=10)) as resp:
return {"url": url, "status": resp.status, "body": await resp.text()}
async with aiohttp.ClientSession() as session:
tasks = [fetch_one(session, url) for url in urls]
return await asyncio.gather(*tasks, return_exceptions=True)
500 sequenzielle Requests bei 1s durchschnittlicher Latenz: 8+ Minuten. 500 parallele Requests mit 50er Concurrency-Limit: unter 15 Sekunden.
Background Jobs und Queues
Für Operationen die zu lang dauern, um synchron im Request ausgeführt zu werden (E-Mails versenden, Berichte generieren, Videos verarbeiten), empfiehlt Claude Code den Übergang zu einem Queue-System:
claude "Unser API-Endpoint /api/export generiert einen Report und
braucht 20-45 Sekunden. Das führt zu Timeouts. Wie strukturiere
ich das als Background-Job mit Status-Polling? Wir nutzen FastAPI
und haben Redis verfügbar."
Claude Code zeigt das vollständige Pattern: einen Endpoint der den Job startet und eine Job-ID zurückgibt, einen Background Worker der den Job ausführt, und einen Status-Endpoint für das Frontend.
Performance-Optimierung ist ein iterativer Prozess: messen, analysieren, optimieren, messen. Claude Code beschleunigt jeden dieser Schritte — besonders die Analyse, die normalerweise am meisten Zeit kostet. Zwei verwandte Artikel:
- Claude Code Debugging — Bugs in Minuten statt Stunden finden
- Claude Code für Unternehmen — Deployment, Zugriffskontrolle und Team-Workflows
Claude Code Mastery — von Performance bis zum produktiven Agenten
Performance-Optimierung ist eine Stärke von Claude Code — aber nicht die einzige. Im Kurs lernst du Agents, MCP-Server, Hooks, Multi-Agent-Workflows und mehr. Vollständig auf Deutsch, einmalig bezahlt.
Jetzt starten — ab €29 → Basis ab €29 · Pro ab €49 · Kein Abo · 14 Tage RückgaberechtKurs · Claude Code Mastery
Von Profiling zum produktiven AI-Agenten
Performance. Debugging. Agents. MCP. Hooks. Multi-Agent-Workflows. Alles auf Deutsch, einmalig bezahlt — kein Abo, keine Plattformabhängigkeit.
Basis ab €29 · Pro ab €49 · Kein Abo · 14 Tage Rückgaberecht