Caching-Strategien für schnellere Anwendungen

Caching speichert teure Ergebnisse zwischen und macht deine App spürbar schneller. Du lernst In-Memory-Caching, Redis, TTLs und die wichtigsten Invalidierungs-Strategien kennen.

Teilen
Caching-Strategien für schnellere Anwendungen

Wenn deine Anwendung dieselben Daten immer wieder aus der Datenbank holt oder aufwendig berechnet, verschenkst du Geschwindigkeit. Caching ist die Antwort: Du speicherst das Ergebnis einer teuren Operation zwischen und lieferst es beim nächsten Mal blitzschnell aus. In diesem Beitrag zeige ich dir die wichtigsten Caching-Strategien und wann du sie einsetzt.

Was ist Caching und warum hilft es?

Ein Cache ist ein schneller Zwischenspeicher. Statt jedes Mal die langsame Quelle (Datenbank, externe API, komplexe Berechnung) zu bemühen, schaust du erst im Cache nach. Liegt das Ergebnis dort, sparst du dir die teure Arbeit. Das nennt man einen Cache-Hit; ist nichts da, spricht man von einem Cache-Miss.

Caching reduziert Antwortzeiten und entlastet deine Datenbank. Der Preis: Die Daten im Cache können veralten, deshalb brauchst du eine Strategie, wann sie aktualisiert werden.

Einfaches In-Memory-Caching

Die simpelste Variante ist ein Cache direkt im Arbeitsspeicher deines Prozesses, etwa mit einer Map:

const cache = new Map();

async function getNutzer(id) {
  if (cache.has(id)) {
    return cache.get(id); // Cache-Hit
  }
  const nutzer = await db.nutzer.findById(id); // Cache-Miss
  cache.set(id, nutzer);
  return nutzer;
}

Das ist schnell und einfach, hat aber Grenzen: Der Cache ist weg, sobald der Prozess neu startet, und er wird nicht zwischen mehreren Servern geteilt.

Ablaufzeit mit TTL

Damit Daten nicht ewig im Cache bleiben, gibst du ihnen eine TTL (Time To Live). Nach Ablauf wird der Eintrag als ungültig betrachtet:

function setMitTTL(key, wert, ttlMs) {
  const ablauf = Date.now() + ttlMs;
  cache.set(key, { wert, ablauf });
}

function getMitTTL(key) {
  const eintrag = cache.get(key);
  if (!eintrag) return null;
  if (Date.now() > eintrag.ablauf) {
    cache.delete(key); // abgelaufen
    return null;
  }
  return eintrag.wert;
}

Mit der TTL findest du eine Balance zwischen Aktualität und Geschwindigkeit. Häufig geänderte Daten bekommen eine kurze, selten geänderte eine lange TTL.

Verteiltes Caching mit Redis

Sobald deine App auf mehreren Servern läuft, brauchst du einen gemeinsamen Cache. Redis ist dafür der Klassiker: ein schneller, externer Schlüssel-Wert-Speicher.

const { createClient } = require("redis");
const redis = createClient();
await redis.connect();

async function getProdukt(id) {
  const cached = await redis.get(`produkt:${id}`);
  if (cached) return JSON.parse(cached);

  const produkt = await db.produkt.findById(id);
  // 60 Sekunden cachen
  await redis.set(`produkt:${id}`, JSON.stringify(produkt), { EX: 60 });
  return produkt;
}

Mit der Option EX legst du die TTL in Sekunden direkt fest. Alle Server greifen auf denselben Redis-Cache zu, sodass die Daten konsistent bleiben.

Cache-Invalidierung

Das schwierigste Thema beim Caching ist die Invalidierung: Wann muss ein Eintrag gelöscht oder erneuert werden? Eine bewährte Regel: Wenn sich die Originaldaten ändern, lösche den passenden Cache-Eintrag.

async function aktualisiereProdukt(id, daten) {
  await db.produkt.update(id, daten);
  // Cache fuer dieses Produkt verwerfen
  await redis.del(`produkt:${id}`);
}

So stellst du sicher, dass beim nächsten Lesen die frischen Daten geladen und neu gecacht werden. Achte darauf, wirklich alle betroffenen Schlüssel zu invalidieren.

Wann du cachen solltest

Caching ist kein Allheilmittel. Es lohnt sich besonders, wenn:

  • Daten oft gelesen, aber selten geändert werden,
  • die Quelle langsam oder teuer ist (Datenbank, externe API),
  • kurze Verzögerungen bei der Aktualität tolerierbar sind.

Für Daten, die sich ständig ändern und bei denen jede Verzögerung kritisch ist, kann Caching mehr schaden als nutzen. Miss immer nach, ob der Cache wirklich etwas bringt.

Fazit

Caching ist eines der wirksamsten Mittel, um Anwendungen schneller zu machen. Beginne mit einfachem In-Memory-Caching, ergänze TTLs für die Aktualität und greife zu Redis, sobald mehrere Server im Spiel sind. Das Wichtigste bleibt die saubere Invalidierung, damit deine Nutzer keine veralteten Daten sehen. Setze Caching gezielt dort ein, wo es den größten Hebel hat.