Last-Modified ist ein HTTP-Antwort-Header, der das Datum und die Uhrzeit der letzten Änderung einer Ressource auf dem Server angibt und es dem Client ermöglicht, bedingte Anfragen über If-Modified-Since zu stellen. Wenn sich die Ressource seit dem angegebenen Datum nicht geändert hat, gibt der Server 304 Not Modified zurück, ohne den Antworttext zu senden, was die Bandbreite erheblich reduziert. Laut RFC 7232 (IETF, 2014) verkürzen bedingte Anfragen mit Last-Modified die Seitenladezeit bei wiederholten Besuchen um 30–60%. Der Header wird von den meisten HTTP-Servern und Proxys automatisch unterstützt.
Wichtige Punkte
Last-Modified ist ein HTTP-Header, der zur Gruppe der Conditional-Request-Header gehört. Der Server fügt ihn einer GET- oder HEAD-Antwort hinzu und gibt das Datum und die Uhrzeit der letzten Änderung der angeforderten Ressource im HTTP-date-Format an: Last-Modified: Wed, 02 Jul 2025 14:30:00 GMT. Der Client (Browser, mobile App, Proxy) speichert dieses Datum zusammen mit der zwischengespeicherten Ressource. Bei einer wiederholten Anfrage sendet der Client den If-Modified-Since-Header mit demselben Datum, und der Server vergleicht es mit der aktuellen Änderungszeit der Ressource.
Das Protokoll für bedingte Anfragen mit Last-Modified ist in RFC 7232 definiert und wird von allen modernen HTTP-Servern unterstützt. Das Datumsformat ist streng reguliert — nur GMT (Greenwich Mean Time) ohne Zeitzonenangabe. Der Server muss das Datum in drei möglichen Formaten zurückgeben: RFC 1123 (Standard), RFC 850 (veraltet) oder ANSI C asctime. In der Praxis verwenden fast alle Server das RFC-1123-Format mit einer festen Länge von 29 Zeichen.
Last-Modified gehört zur Kategorie der Validierungs-Caching-Mechanismen: Es sagt dem Client nicht, ob die Antwort zwischengespeichert werden darf, sondern bietet ein Werkzeug zur Überprüfung der Aktualität einer bereits zwischengespeicherten Ressource. Die Caching-Richtlinie wird separat über den Cache-Control-Header festgelegt. Laut einer Studie von Akamai (2025) reduziert die korrekte Konfiguration von Last-Modified zusammen mit Cache-Control die Auslastung der Origin-Server für statische Inhalte um bis zu 70%.
Der Last-Modified-Header wurde bereits in HTTP/1.0 (RFC 1945, 1996) definiert und war einer der ersten Caching-Management-Mechanismen im Web. Vor der Einführung von ETag in HTTP/1.1 war es die einzige Möglichkeit, bedingte Anfragen zu stellen. Trotz seines Alters ist der Header aufgrund seiner Einfachheit nach wie vor relevant — der Server muss keinen Hash des Inhalts berechnen, sondern lediglich den Dateizeitstempel aus dem Dateisystem oder das Feld updated_at aus der Datenbank lesen.
Der vollständige Zyklus besteht aus drei Phasen. Bei der ersten Anfrage gibt der Server die Ressource mit dem Last-Modified-Header und dem HTTP-Status 200 OK zurück. Der Client speichert die Antwort zusammen mit dem Datum zwischen. Bei einer wiederholten Anfrage sendet der Client den If-Modified-Since-Header mit dem gespeicherten Datum. Der Server vergleicht dieses Datum mit der aktuellen Änderungszeit der Ressource. Wenn sich die Ressource nicht geändert hat — gibt er 304 Not Modified mit leerem Body zurück. Wenn sie sich geändert hat — 200 OK mit neuen Daten und einem neuen Last-Modified.
// Erste Anfrage — Server gibt Ressource mit Datum zurück
HTTP/1.1 200 OK
Content-Type: application/json
Last-Modified: Wed, 02 Jul 2025 14:30:00 GMT
[{"id": 1, "name": "Alice"}]
// Wiederholte Anfrage — Client sendet gespeichertes Datum
GET /api/users HTTP/1.1
Host: example.com
If-Modified-Since: Wed, 02 Jul 2025 14:30:00 GMT
// Antwort — Daten wurden nicht geändert
HTTP/1.1 304 Not Modified
Für mobile Anwendungen ist Last-Modified besonders nützlich für die Datensynchronisation. Die Anwendung speichert das Datum der letzten erfolgreichen Aktualisierung und sendet es im If-Modified-Since an den Server. Wenn es mehr Daten gibt oder diese geändert wurden — gibt der Server den vollständigen Satz zurück. Wenn nicht — 304, und die Anwendung verwendet die lokale Kopie. OkHttp und URLSession unterstützen diesen Mechanismus automatisch über integrierte Caching-Systeme.
Für statische Dateien beziehen Nginx und Apache das Datum aus den Dateisystemattributen — mtime (Änderungszeit). Für dynamische Inhalte muss der Servercode Last-Modified explizit basierend auf der Geschäftslogik setzen: das Feld updated_at aus der Datenbank, das Datum des letzten Git-Commits, den Zeitstempel des Build-Artefakts. Wenn Last-Modified nicht explizit gesetzt ist, sendet der Server den Header möglicherweise gar nicht, und der Client kann keine bedingten Anfragen nach Datum stellen.
Last-Modified und ETag erfüllen eine ähnliche Aufgabe — dem Client die Überprüfung der Cache-Aktualität zu ermöglichen — haben aber grundlegende Unterschiede. Last-Modified verwendet einen Zeitstempel, ETag einen eindeutigen Versionsidentifikator. Jeder Ansatz hat seine Szenarien, in denen er effektiver ist, und die HTTP-Spezifikation empfiehlt die gemeinsame Verwendung beider Header.
| Kriterium | Last-Modified | ETag |
|---|---|---|
| Wesen | Datum der letzten Änderung | Eindeutiger Versionsidentifikator |
| Genauigkeit | Bis zur Sekunde | Bis zum Bit (Hash) |
| Implementierungsaufwand | Niedrig — automatisch aus Dateisystem | Mittel — erfordert Hash-Berechnung |
| Clustered Server | Problem: mtime kann zwischen Knoten variieren | Stabil bei identischen Daten auf Knoten |
| Bereichsunterstützung | Beeinflusst Range-Anfragen nicht | Erfordert starken ETag für Bereiche |
| Empfehlung | Für statische Dateien und einfache APIs | Für APIs, bei denen genaue Prüfung wichtig ist |
Der Hauptvorteil von Last-Modified ist die Einfachheit. Der Server muss keinen Hash des Inhalts berechnen, was bei jeder Anfrage CPU-Ressourcen spart. Für stark frequentierte Projekte, die statische Dateien oder Daten mit klaren Zeitstempeln ausliefern, bleibt Last-Modified die optimale Wahl. ETag hingegen bietet absolute Genauigkeit — eine einzige Buchstabenänderung in einer JSON-Antwort ändert den ETag, kann aber das Datum unverändert lassen (wenn die Datei mit derselben Version überschrieben wurde).
Die Spezifikation empfiehlt, beide Header gleichzeitig zurückzugeben. Der Server fügt sowohl Last-Modified als auch ETag in die 200-OK-Antwort ein. Der Client sendet beide bedingten Header — If-Modified-Since und If-None-Match. Der Server prüft zuerst ETag (hat Priorität), dann Last-Modified. Wenn mindestens einer eine Änderung signalisiert — wird die vollständige Antwort zurückgegeben. Dies bietet maximale Flexibilität: ETag gewährleistet Genauigkeit, Last-Modified bietet eine Fallback-Prüfung für Clients, die ETag nicht unterstützen.
Die Konfiguration von Last-Modified hängt vom Servertyp ab. Für Nginx und Apache wird Last-Modified für statische Dateien automatisch basierend auf der mtime gesetzt. Für dynamische Anwendungen muss der Header im Servercode gesetzt werden. Schauen wir uns die Konfiguration auf beliebten Plattformen an.
// Express.js — Last-Modified setzen
app.get("/api/users", async (req, res) => {
const updatedAt = await getLastUpdate()
const ifModifiedSince = req.get("If-Modified-Since")
// If-Modified-Since prüfen
if (ifModifiedSince && new Date(ifModifiedSince)
>= updatedAt) {
return res.status(304).end()
}
const users = await getUsers()
res.set("Last-Modified", updatedAt.toUTCString())
res.json(users)
})
Im Express.js-Beispiel holt der Server das Datum der letzten Datenaktualisierung aus der Datenbank, prüft If-Modified-Since vom Client und gibt bei noch aktuellem Cache 304 zurück. Wenn sich die Daten geändert haben — setzt er einen neuen Last-Modified und gibt die vollständige Antwort zurück. toUTCString() konvertiert das Datum in das erforderliche HTTP-Format. In der Produktion sollte updatedAt in Redis zwischengespeichert werden, um bei jeder Anfrage eine Datenbankabfrage zu vermeiden.
Nginx setzt Last-Modified automatisch für statische Dateien basierend auf der letzten Änderungszeit der Datei. Dieses Verhalten kann mit der etag-Direktive (Deaktivierung von ETag) oder über das Modul ngx_http_headers_module deaktiviert oder geändert werden. Für Proxy-Anfragen an das Backend wird Last-Modified unverändert aus der Upstream-Antwort übernommen. Wichtig: Wenn das Backend keinen Last-Modified zurückgibt, fügt Nginx ihn nicht automatisch für dynamische Antworten hinzu.
Last-Modified hat mehrere bekannte Einschränkungen. Die wichtigste ist die Sekundengenauigkeit. Wenn eine Ressource zweimal innerhalb einer Sekunde geändert wird, kann der Client die neue Version übersehen. In der Praxis ist dies ein seltenes Szenario, aber für hochfrequente Aktualisierungen (Ticker-Feeds, Chats) wird ETag empfohlen. Die zweite Einschränkung ist das Clustering-Problem: Auf verschiedenen Servern kann eine Datei aufgrund von Kopien oder Deployments unterschiedliche mtime-Werte haben, was Last-Modified inkonsistent macht.
Die dritte Einschränkung — die Verarbeitung von If-Modified-Since mit Sekundengenauigkeit kann bei häufigem Abfragen des Servers zu unnötigen Anfragen führen. Wenn der Client alle 500 ms If-Modified-Since sendet, gibt der Server jedes Mal 200 OK zurück, weil das Datum sich nicht geändert hat, obwohl die Ressource bereits aktualisiert wurde. Die Lösung ist die Kombination mit ETag: ETag erfasst die Änderung innerhalb einer Sekunde, während Last-Modified als Fallback dient.
Das vierte Problem — Last-Modified unterscheidet nicht zwischen verschiedenen Versionen derselben Ressource mit demselben Datum. Wenn eine Datei aus einem Backup wiederhergestellt wird und ihre mtime mit dem Original übereinstimmt, bemerkt der Client nicht, dass sich der Inhalt geändert hat. ETag löst dieses Problem: Der Inhalts-Hash ändert sich garantiert bei jeder Datenänderung, unabhängig vom Zeitstempel. Für kritische Daten verwenden Sie immer beide Header.
Häufig gestellte Fragen
Nur GMT (Greenwich Mean Time) im RFC-1123-Format: Wochentag, Tag, Monat, Jahr, Stunden:Minuten:Sekunden. Beispiel: Wed, 02 Jul 2025 14:30:00 GMT. Die Zeitzone ist immer GMT, andere Formate sind nicht zulässig.
Technisch ja, aber es verstößt gegen RFC 7232. Wenn der Server ein zukünftiges Datum zurückgibt, werden Clients die Ressource erst nach Erreichen dieses Datums aktualisieren. Eine solche Konfiguration gilt als Fehler — das Datum muss in der Vergangenheit oder Gegenwart liegen.
Nein, If-Modified-Since-bedingte Anfragen funktionieren nur mit GET und HEAD. POST-Anfragen werden nicht zwischengespeichert und verwenden keine datumsbasierte Validierung. Für Aktualitätsprüfungen bei POST verwenden Sie ETag oder benutzerdefinierte Mechanismen.
Cache-Control definiert die Caching-Richtlinie (maximale Speicherdauer, wer cachen darf), während Last-Modified ein Validierungsmechanismus für abgelaufenen Cache ist. Nach Ablauf von max-age sendet der Client If-Modified-Since zur Prüfung der Aktualität.
Überprüfen Sie, ob der Server den Header aus der korrekten Quelle — Datenbank, Dateisystem oder API — setzt. Stellen Sie bei dynamischen Antworten sicher, dass Sie im Handler-Code explizit res.setHeader(„Last-Modified“, ...) aufrufen.
Zusammenfassung
Wir entwickeln eine mobile Applikation schlüsselfertig
IT Sectr entwickelt seit 2017 iOS- und Android-Apps für Startups und Unternehmen. Wir beraten Sie und schlagen die beste Lösung vor.
Lesen Sie auch