ETag: wat het is, cachenmechanisme en configuratie van de header

Auteur: IT Sectr Gepubliceerd: 2026-03-09 Leestijd: 8 min

ETag (Entity Tag) — een HTTP-header die een unieke identificatie van de versie van een bron op de server toewijst, waardoor de client de actualiteit van gecachte gegevens efficiënt kan controleren. Bij een herhaald verzoek stuurt de browser of applicatie de opgeslagen ETag, en de server vergelijkt deze met de huidige: bij overeenkomst wordt status 304 Not Modified teruggegeven zonder antwoordbody. Volgens RFC 7232 (IETF, 2014) verminderen voorwaardelijke verzoeken met ETag de hoeveelheid verzonden gegevens tot 95% voor veelgevraagde bronnen. Dit maakt de header kritisch voor de prestaties van mobiele applicaties.

Belangrijkste punten

  • ETag — HTTP-header met een unieke identificatie van de bronversie voor voorwaardelijke verzoeken en caching
  • Werkingsprincipe — server genereert een hash van de inhoud of een versienummer, client stuurt deze in de If-None-Match-header
  • Sterke en zwakke ETags — sterke (inhoud identiek byte-voor-byte) en zwakke (inhoud semantisch equivalent, prefix W/)
  • 304 Not Modified — serverantwoord bij ETag-overeenkomst, bespaart bandbreedte en versnelt laden
  • ETag vs Last-Modified — ETag nauwkeuriger (inhoudshash), Last-Modified eenvoudiger (datum), samen geven ze maximale efficiëntie

Wat is ETag?

ETag (Entity Tag) — is een HTTP-antwoordheader die een unieke identificatie van een specifieke versie van een bron bevat. De server berekent ETag op basis van de bestandsinhoud, de metadata of het revisienummer en geeft deze aan de client in het antwoord op een GET-verzoek. De client slaat deze identificatie op en stuurt deze bij volgende verzoeken aan dezelfde bron in de If-None-Match-header. Als de bron niet is gewijzigd, antwoordt de server met 304 Not Modified en gebruikt de client zijn gecachte kopie.

Het formaat van ETag is gedefinieerd in RFC 7232 als een string tussen aanhalingstekens: "33a64df551425fcc55e4d42a148795d9f25f89d4". De waarde kan een SHA-1-hash van de bestandsinhoud zijn, een oplopend versienummer, een combinatie van inode-nummer-tijd voor statische bestanden of een willekeurige token gegenereerd door de server. De enige vereiste is dat de waarde verandert bij elke wijziging van de bron en niet verandert als de bron hetzelfde blijft.

ETag maakt deel uit van het mechanisme van voorwaardelijke verzoeken (conditional requests) — een van de basisoptimalisaties van het HTTP-protocol. In tegenstelling tot onvoorwaardelijke verzoeken, waarbij de server altijd een volledig antwoord teruggeeft, stelt een voorwaardelijk verzoek de client in staat de actualiteit van de cache te controleren zonder gegevens opnieuw te downloaden. Volgens gegevens van HTTP Archive (2025) is ongeveer 40% van alle HTTP-antwoorden 304 Not Modified dankzij correcte configuratie van ETag en Last-Modified.

Waar wordt ETag toegepast

ETag wordt gebruikt in REST API voor het optimaliseren van het laden van gegevensverzamelingen — als de lijst met objecten niet is gewijzigd, ontvangt de client 304 zonder de volledige JSON te verzenden. In statische bestanden (CSS, JS, afbeeldingen) stelt ETag CDN’s en browsers in staat de actualiteit van de cache efficiënt te controleren. In mobiele applicaties is ETag kritisch voor achtergrondsynchronisatie: de applicatie controleert of de gegevens op de server zijn gewijzigd en downloadt updates alleen wanneer nodig. Dit bespaart bandbreedte en de batterij van het apparaat.

Hoe werkt ETag?

De volledige werkingscyclus van ETag bestaat uit vier stappen. De server genereert ETag bij het eerste verzoek en geeft deze terug in de antwoordheader. De client slaat ETag samen met de gecachte bron op. Bij een herhaald verzoek stuurt de client de If-None-Match-header met de waarde van de opgeslagen ETag. De server vergelijkt de ontvangen waarde met de huidige ETag van de bron: bij overeenkomst geeft hij 304 Not Modified met een lege body terug, bij geen overeenkomst — 200 OK met een nieuwe bron en een nieuwe ETag.

http
// Clientverzoek met If-None-Match
GET /api/users HTTP/1.1
Host: example.com
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

// Serverantwoord — bron niet gewijzigd
HTTP/1.1 304 Not Modified
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

In een mobiele applicatie kan deze cyclus worden geïmplementeerd via een HTTP-client met cache-ondersteuning. OkHttp beheert bijvoorbeeld automatisch ETag via CacheInterceptor: het slaat de ETag van het antwoord op en voegt bij een herhaald verzoek If-None-Match toe. Bij ontvangst van 304 retourneert OkHttp de gecachte gegevens. OkHttp ondersteunt ETag zonder extra configuratie — het volstaat om de cache in te schakelen via OkHttpClient.Builder.cache().

Genereren van ETag op de server

De server kan ETag op verschillende manieren berekenen: via een MD5- of SHA-hash van de inhoud, via een revisienummer uit de database (bijvoorbeeld updated_at uit MySQL), via een combinatie van inode + mtime + size voor statische bestanden (Nginx genereert ETag precies op deze manier). Voor dynamische API’s is de inhoudshash het meest betrouwbaar: als het JSON-antwoord ten minste één veld heeft gewijzigd, verandert ETag. Het berekenen van de hash bij elk verzoek belast echter de CPU — voor systemen met hoge belasting is het beter een oplopend versienummer te gebruiken.

Sterke en zwakke ETags

RFC 7232 definieert twee typen ETags: sterke (strong) en zwakke (weak). Een sterke ETag betekent dat twee representaties van de bron byte-voor-byte identiek zijn — geen enkele bit verschilt. Een zwakke ETag (prefix W/) garandeert alleen semantische equivalentie: de inhoud kan verschillen op het niveau van serialisatie (spaties, volgorde van JSON-velden), maar de gegevens worden voor de client als hetzelfde beschouwd. Zwakke ETags worden gemarkeerd met het prefix W/, bijvoorbeeld W/"1a2b3c".

De keuze van het type ETag hangt af van de vereisten voor vergelijkingsnauwkeurigheid. Voor statische bestanden (CSS, JS, afbeeldingen) hebben sterke ETags de voorkeur — als het bestand is gewijzigd, moet de client de nieuwe versie ontvangen. Voor dynamische API’s, waar dezelfde JSON met een verschillende veldvolgorde of opmaak kan worden geserialiseerd, bieden zwakke ETags meer flexibiliteit: de server genereert ETag op basis van bedrijfsgegevens, niet op basis van de tekenreeksweergave.

Type ETagFormaatGarantieToepassing
Strong (sterk)"hash"Byte-voor-byte identiteitStatische bestanden, binaire bronnen
Weak (zwak)W/"hash"Semantische equivalentieJSON API, dynamische pagina’s

Beperking van zwakke ETags: ze kunnen niet worden gebruikt met bereikverzoeken (Range requests). Als de client een deel van het bestand opvraagt, moet de server een sterke ETag retourneren om te garanderen dat het fragment overeenkomt met de volledige bron. Zwakke ETags bieden een dergelijke garantie niet. In andere scenario’s zijn zwakke ETags veilig en aanbevolen voor API’s.

ETag vs Last-Modified

ETag en Last-Modified zijn twee HTTP-headers voor voorwaardelijke verzoeken die vaak samen worden gebruikt. Last-Modified geeft de datum van de laatste wijziging van de bron aan en werkt met de If-Modified-Since-header. ETag biedt een unieke identificatie van de versie en werkt met If-None-Match. Elk heeft zijn voor- en nadelen, en de combinatie geeft maximale cachingefficiëntie.

Last-Modified is eenvoudiger te implementeren — de server haalt automatisch de datum uit het bestandssysteem of werkt het veld updated_at in de database bij. De datum heeft echter een nauwkeurigheid tot een seconde, wat onvoldoende is voor bronnen die meerdere keren per seconde veranderen. Bovendien maakt Last-Modified geen onderscheid tussen verschillende toestanden: als het bestand met dezelfde versie wordt overschreven, verandert de datum, maar de inhoud niet — de client laadt identieke gegevens opnieuw.

ETag is nauwkeuriger: het verandert alleen bij een daadwerkelijke wijziging van de inhoud. Als de server de vorige versie uit een back-up herstelt, verandert ETag. Als het bestand met dezelfde gegevens wordt overschreven — blijft ETag hetzelfde en zal de client niet opnieuw laden. Gezamenlijk gebruik wordt aanbevolen door de HTTP-specificatie: de server retourneert beide headers, de client stuurt If-None-Match en If-Modified-Since tegelijkertijd. Als ten minste één header een wijziging aangeeft — retourneert de server een nieuwe bron.

Prioriteit van headers

Volgens de specificatie heeft ETag prioriteit boven Last-Modified. Als de server If-None-Match heeft ontvangen, moet hij alleen ETag controleren en If-Modified-Since negeren. Dit voorkomt race conditions: als de bron is gewijzigd tussen het verzenden van Last-Modified door de client en de controle op de server, is ETag een versere indicator. In de praktijk controleren servers meestal beide headers, maar bij niet-overeenkomende resultaten wint ETag.

Implementatie van ETag op de server

De configuratie van ETag hangt af van het type server. Nginx genereert ETag voor statische bestanden automatisch op basis van inode, mtime en grootte. Apache gebruikt het FileETag-mechanisme. Voor dynamische applicaties in Node.js, PHP, Python, Ruby moet ETag programmatisch worden gegenereerd — via een hash van het antwoord, een versienummer van de gegevens of een combinatie van verzoekparameters.

go
func etagMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter,
        r *http.Request) {
        // Genereren van ETag op basis van gegevens
        etag := generateETag(r.URL.Path)
        w.Header().Set("ETag", etag)

        // Controleren van If-None-Match
        if r.Header.Get("If-None-Match") == etag {
            w.WriteHeader(http.StatusNotModified)
            return
        }
        next.ServeHTTP(w, r)
    })
}

Middleware in Go onderschept het verzoek, genereert ETag voor de aangevraagde URL (bijvoorbeeld berekent het een hash van gegevens uit de cache of database) en stelt de antwoordheader in. Als de client If-None-Match heeft verzonden en deze overeenkomt met de huidige ETag, retourneert de server onmiddellijk 304 Not Modified, zonder de hoofdhandler aan te roepen. In een productieomgeving is het raadzaam om caching van berekende ETags op basis van URL en parameters toe te voegen om de serverbelasting te verminderen.

Problemen en valkuilen

In een multi-serverconfiguratie (round-robin of anycast) moet ETag hetzelfde zijn op alle knooppunten voor dezelfde bron. Als ETag wordt gegenereerd op basis van de inode van het bestand en de site op meerdere servers draait, zullen de waarden verschillen. Oplossing — gebruik van een inhoudshash of gecentraliseerde versieopslag (Redis, etcd). Het tweede probleem — gzip-compressie: Nginx wijzigt ETag wanneer compressie is ingeschakeld, wat overmatige 304-reacties kan veroorzaken. Configuratie van gzip_vary on is vereist voor synchronisatie van ETag met gecomprimeerde inhoud.

Veelgestelde vragen

Kan ETag hetzelfde zijn voor verschillende bronnen?

Ja, als de server dit niet expliciet heeft voorkomen. ETag hoeft niet globaal uniek te zijn — het is uniek binnen een specifieke URL. Voor statische bestanden zijn botsingen onwaarschijnlijk bij gebruik van een SHA-hash, maar voor zelfgemaakte generatoren zijn duplicaten mogelijk.

Moet ETag voor elke bron worden geconfigureerd?

ETag is het meest effectief voor bronnen die herhaaldelijk worden opgevraagd en zelden veranderen: statische bestanden, API-lijsten, configuraties. Voor unieke pagina’s die één keer worden geladen (bijvoorbeeld een bestelbevestigingspagina), biedt ETag geen voordeel.

Hoe werkt ETag met CDN?

CDN houdt rekening met ETag in origin-verzoeken om de actualiteit van de cache te controleren. Als de ETag van een bron op origin is gewijzigd, downloadt CDN de nieuwe versie. Cloudflare en Fastly ondersteunen ETag als standaardmechanisme voor cache-invalidatie op origin-niveau.

Kan ETag langer zijn dan 255 tekens?

RFC 7232 beperkt de lengte van ETag niet, maar servers en proxy’s kunnen te lange waarden afkappen of negeren. Het wordt aanbevolen een hash met een lengte van 20–40 tekens of een combinatie van een versie-id met een controlesom te gebruiken.

Wat kiezen: ETag of Cache-Control?

Dit zijn geen elkaar uitsluitende mechanismen. Cache-Control bepaalt het cachebeleid (hoe lang bewaren, wie toegestaan), en ETag is een validatiemechanisme van de gecachte bron. De optimale configuratie omvat beide headers samen.

Samenvatting

  • ETag — HTTP-header met een unieke identificatie van de bronversie voor voorwaardelijke verzoeken en efficiënte caching
  • Principe — client stuurt If-None-Match met opgeslagen ETag, server antwoordt 304 bij overeenkomst
  • Sterke ETags — byte-voor-byte identiteit voor statische bestanden, zwakke — semantische equivalentie voor API’s
  • ETag nauwkeuriger dan Last-Modified — volgt inhoud, niet datum, en verandert alleen bij echte wijzigingen
  • Gezamenlijk gebruik met Last-Modified geeft maximale cachingefficiëntie
  • Server-side — genereren via inhoudshash, gegevensversienummer of parametercombinatie
  • Aanbeveling — gebruik ETag voor alle API-eindpunten en statische bronnen in mobiele applicaties

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook