Idempotenz

Wie wiederholte Anfragen denselben sicheren Zustand erzeugen, statt unbeabsichtigt mehrfach zu wirken

Eine Operation ist idempotent, wenn sie beliebig oft ausgeführt werden kann und immer dasselbe Ergebnis liefert wie beim ersten Mal – entscheidend für robuste APIs und verteilte Systeme.

Fortgeschritten2 Min Lesezeit

Erklärung starten

Auf einen Blick

3 Punkte

  1. Idempotente Operationen können sicher wiederholt werden – bei Netzwerkfehlern kein Problem
  2. HTTP: GET, PUT, DELETE sind idempotent – POST in der Regel nicht
  3. Idempotency Keys ermöglichen idempotente POST-Anfragen

Sofortantwort

Idempotenz einfach erklärt

Eine Operation liefert dasselbe Ergebnis, egal wie oft sie ausgeführt wird.

Kurz gesagt
Idempotente Operationen können sicher wiederholt werden – bei Netzwerkfehlern kein Problem
Typischer Einsatz
Zahlungsabwicklung, Webhook-Verarbeitung, Retry-Logik
Wichtig zu wissen
Idempotency Keys ermöglichen idempotente POST-Anfragen

Idempotenz im Überblick

In verteilten Systemen passieren Netzwerkfehler. Eine Anfrage wird gesendet, aber die Antwort kommt nie an – war die Anfrage erfolgreich oder nicht? Die sichere Lösung: einfach nochmal senden. Aber nur, wenn die Operation idempotent ist.

Nicht idempotent: POST /orders – zweimal gesendet = zwei Bestellungen
Idempotent: PUT /orders/123/status mit {"status": "shipped"} – zehnmal gesendet = Status ist „shipped”

Das ist der Kern: Idempotente Operationen können sicher wiederholt werden, ohne unerwünschte Nebeneffekte.

At-least-once vs. Exactly-once

In verteilten Systemen gibt es drei Delivery-Garantien:

GarantieBedeutungRisiko
At-most-onceHöchstens einmal geliefertDatenverlust möglich
At-least-onceMindestens einmal geliefertDuplikate möglich
Exactly-onceGenau einmal geliefertSehr aufwändig, selten wirklich garantiert

At-least-once + Idempotenz = sicheres System: Wenn Duplikate sicher ignoriert werden, ist At-least-once ausreichend und viel einfacher als Exactly-once.

Technisch betrachtet

HTTP-Methoden im Überblick

MethodeIdempotentSicherTypische Verwendung
GETDaten lesen
PUTRessource ersetzen
DELETERessource löschen
POSTRessource erstellen
PATCH⚠️Teilweise aktualisieren

Idempotency Key implementieren

import json
import redis
from fastapi import FastAPI, Header, HTTPException

app = FastAPI()
cache = redis.Redis()

@app.post("/payments")
async def create_payment(
    payment: PaymentRequest,
    idempotency_key: str = Header(..., alias="Idempotency-Key")
):
    cache_key = f"idem:{idempotency_key}"

    # Bereits verarbeitet? → Gespeichertes Ergebnis zurückgeben
    cached = cache.get(cache_key)
    if cached:
        return json.loads(cached)

    # Noch nicht verarbeitet → Zahlung durchführen
    try:
        result = await process_payment(payment)
    except Exception as e:
        # Fehler NICHT cachen – Retry soll erneut versuchen
        raise HTTPException(status_code=500, detail=str(e))

    # Ergebnis 24h cachen (nur bei Erfolg)
    cache.setex(cache_key, 86400, json.dumps(result))
    return result

Idempotente Datenbankoperationen

-- ❌ Nicht idempotent: Jedes Mal wird ein neuer Datensatz erstellt
INSERT INTO orders (user_id, product_id, amount)
VALUES (123, 456, 99.99);

-- ✅ Idempotent: Nur einfügen wenn noch nicht vorhanden
INSERT INTO orders (id, user_id, product_id, amount)
VALUES ('ord_abc123', 123, 456, 99.99)
ON CONFLICT (id) DO NOTHING;

-- ✅ Idempotent: Upsert – einfügen oder aktualisieren
INSERT INTO order_status (order_id, status, updated_at)
VALUES ('ord_abc123', 'shipped', NOW())
ON CONFLICT (order_id) DO UPDATE SET
  status = EXCLUDED.status,
  updated_at = EXCLUDED.updated_at;

Idempotente Webhook-Verarbeitung

processed_events = set()  # In Production: Redis oder DB

@app.post("/webhooks/stripe")
async def handle_stripe_webhook(request: Request):
    payload = await request.body()
    sig = request.headers.get("Stripe-Signature")

    # Signatur verifizieren
    event = stripe.Webhook.construct_event(payload, sig, WEBHOOK_SECRET)

    # Bereits verarbeitet?
    if event.id in processed_events:
        return {"status": "already_processed"}

    # Verarbeiten
    if event.type == "payment_intent.succeeded":
        await fulfill_order(event.data.object)

    processed_events.add(event.id)
    return {"status": "ok"}

Stripe-Beispiel

curl https://api.stripe.com/v1/charges \
  -H "Idempotency-Key: a8f3b2c1-4d5e-6f7a-8b9c-0d1e2f3a4b5c" \
  -d amount=2000 \
  -d currency=eur
# Zweiter Aufruf mit gleichem Key → gleiche Antwort, keine zweite Zahlung

Wann ist Idempotenz besonders wichtig?

  • Zahlungen: Doppelte Abbuchungen sind kritisch
  • E-Mail-Versand: Doppelte Willkommens-Mails sind ärgerlich
  • Lagerbestand: Doppeltes Reduzieren führt zu negativem Bestand
  • Webhook-Handler: Webhooks werden oft mehrfach gesendet (Retry-Logik des Senders)
  • Message Queues: Kafka, RabbitMQ liefern At-least-once – Consumer müssen idempotent sein

Schritt für Schritt

Wie idempotente Abläufe zuverlässig entstehen

  1. Wirkung einer Anfrage definieren

    Beschreibe, welchen Zustand oder welches Ergebnis eine Operation herstellen soll. Entscheidend ist nicht, ob eine Anfrage technisch zweimal ankommt, sondern ob ihre reale Wirkung bei Wiederholung gleich bleibt.

  2. Eindeutige Kennung und Zustand wählen

    Nutze eine stabile Kennung oder einen Zielzustand, um Wiederholungen zu erkennen. Speichere ausreichend Kontext, damit das System eine erneute Anfrage sicher von einem neuen, ähnlichen Vorgang unterscheiden kann.

  3. Nebenwirkungen absichern

    Behandle Zahlungen, Nachrichten, externe Aufrufe und Statuswechsel besonders sorgfältig. Transaktionen, Outbox-Muster oder kontrollierte Reihenfolgen können verhindern, dass ein Retry dieselbe Wirkung zweimal auslöst.

  4. Störungen und Parallelität testen

    Simuliere Timeouts, doppelte Zustellung und gleichzeitige Anfragen. Beobachte, ob das System den richtigen Zustand bewahrt, verständlich antwortet und bei unklaren Fällen sicher an eine Klärung übergibt.

Konkretes Beispiel

Eine Bestellung bleibt bei Retry einmalig

Eine Kundin löst eine Bestellung aus, doch die Antwort erreicht ihren Browser nicht. Sie versucht es erneut, während die erste Anfrage möglicherweise bereits verarbeitet wurde.

Unsicherer Vorgang

Der Server kann nicht erkennen, ob die zweite Anfrage eine Wiederholung oder eine neue Bestellung ist. Ohne Schutz könnten Zahlung, Auftrag oder Bestätigung doppelt entstehen.

Eindeutige Wirkung

Beide Anfragen tragen dieselbe Idempotenzkennung. Das System liefert bei Wiederholung den ursprünglichen Status zurück, statt eine zweite Bestellung anzulegen; unklare Fälle werden protokolliert und geprüft.

Einordnung

Vorteile und Grenzen

Das spricht dafür

  • Macht Wiederholungen bei Timeouts und verteilter Zustellung sicherer und besser nachvollziehbar.
  • Reduziert doppelte Nebenwirkungen bei wichtigen Statuswechseln und externen Aufrufen.
  • Unterstützt robuste Retries und klarere Fehlerbehandlung in verteilten Systemen.

Das solltest du beachten

  • Die richtige Kennung und Lebensdauer hängen stark von Fachlogik und möglicher Wiederholung ab.
  • Idempotenz verhindert nicht jede Race Condition oder fachliche Konfliktsituation.
  • Zusätzlicher Zustand und Speicherdauer bringen Datenschutz-, Kosten- und Pflegefragen mit sich.
Vertiefung · für Fortgeschrittene

Wiederholung ohne doppelte Wirkung

Wissenskarte

Gleicher Zustand bei Retry

API
Schnittstelle zur Kommunikation zwischen Softwaresystemen.
Webhook
Ein Server sendet automatisch HTTP-Anfragen bei Ereignissen.
Message Queue
Warteschlange für asynchrone Service-Kommunikation.
Error Recovery Patterns
UX-Patterns für graceful Fehlerbehandlung in KI-Systemen.
Event Sourcing
Zustand als Sequenz von Events speichern und bei Bedarf rekonstruieren.
Idempotenz verbindet eindeutige Vorgänge mit kontrollierter Wiederholung, damit eine technische Unsicherheit keine mehrfachen fachlichen Folgen erzeugt. Idempotenz gliedert sich in: API, Webhook, Message Queue, Error Recovery Patterns, Event Sourcing.

01Einsatzbereiche

Wann ist Idempotenz sinnvoll?

Geeignet für

  • ZahlungsabwicklungDoppelte Zahlungen verhindern: Gleiche Anfrage zweimal gesendet → Zahlung nur einmal ausgeführt
  • Webhook-VerarbeitungWebhooks können mehrfach gesendet werden – idempotente Handler verarbeiten sie nur einmal
  • Retry-LogikBei Netzwerkfehlern kann eine Anfrage sicher wiederholt werden, ohne Duplikate zu erzeugen

↑ Inhalt

02Werkzeuge

Womit Idempotenz umgesetzt wird

↑ Inhalt

Merksatz

Idempotenz ist wie ein Lichtschalter

Wenn das Licht an ist und du drückst zehnmal auf 'An', bleibt es an – das Ergebnis ändert sich nicht. Aber 'Licht umschalten' ist nicht idempotent: Jedes Drücken ändert den Zustand.

  1. Idempotente Operationen können sicher wiederholt werden – bei Netzwerkfehlern kein Problem
  2. HTTP: GET, PUT, DELETE sind idempotent – POST in der Regel nicht
  3. Idempotency Keys ermöglichen idempotente POST-Anfragen

04Redaktion

Herkunft und Stand

Redaktion und Aktualität

Ebenex RedaktionRedaktion

Veröffentlicht
Aktualisiert

Dieses Feld entwickelt sich schnell. Oben stehen Veröffentlichung und letzte Änderung; ein Prüfdatum kommt dazu, sobald die Erklärung nach ihrer letzten Änderung geprüft wurde.

↑ Inhalt

05FAQ

Häufige Fragen zu Idempotenz

Welche HTTP-Methoden sind idempotent?

GET: Ja (liest nur). PUT: Ja (setzt Ressource auf definierten Zustand). DELETE: Ja (Ressource ist danach weg, egal wie oft). PATCH: Nicht zwingend (hängt von der Implementierung ab). POST: Nein (erstellt jedes Mal eine neue Ressource).

Was ist ein Idempotency Key?

Eine eindeutige ID, die der Client mit einer Anfrage mitschickt. Der Server speichert das Ergebnis der ersten Anfrage mit dieser ID. Bei einer Wiederholung gibt er das gespeicherte Ergebnis zurück, ohne die Operation erneut auszuführen. Stripe und andere Payment-APIs nutzen dieses Muster.

Was ist der Unterschied zwischen idempotent und sicher (safe)?

Eine 'sichere' Operation verändert den Zustand nicht (GET, HEAD). Eine idempotente Operation kann den Zustand verändern, aber mehrfaches Ausführen hat denselben Effekt wie einmaliges (PUT, DELETE). Alle sicheren Operationen sind auch idempotent, aber nicht umgekehrt.

↑ Inhalt

06Weiterlernen

Was möchtest du als Nächstes verstehen?

↑ Inhalt