Geprüft mit EmDash 1.2.0 und 1.3.1 auf einer Demo-Seite und mit den Messdaten von theweeklydash.com, vom 11. bis 21. Oktober 2026.
Ein Wort. Mehr hatte ich im Kurztext eines einzigen Beitrags nicht geändert. Danach war zwei Stunden lang die ganze EmDash-Website auf Cloudflare langsam, von der Schweiz bis Singapur, auch jeder Artikel, den ich nie angefasst hatte. Wo eben noch 50 Millisekunden standen, standen jetzt zwei Sekunden.
Der übliche Verdächtige ist der Cold Start bei Cloudflare Workers. Er ist höchstens Komplize. Der Täter ist ein leerer Cache, und EmDash leert ihn gründlicher, als man denkt. Wie das passiert, wie lange der Cache ohne Besucher überhaupt hält und was dagegen hilft: gemessen, nicht geschätzt.
Die Website war eine Demo, die wir für eine Messreihe über mehrere EmDash-Websites absichtlich ungeschützt laufen liessen, damit am Ende brauchbare Zahlen stehen statt Bauchgefühl. Sie lief zwei Tage ganz ohne Hilfe, und Globalping hat sie alle 30 Minuten abgerufen, aus Deutschland, der Schweiz, Grossbritannien, den USA, Singapur und Brasilien. Danach lief sie mit einem Warmer, der die Seiten abruft, bevor Leser kommen. Zum Schluss habe ich sie auf EmDash 1.3.1 aktualisiert, den Cache über Deploys hinweg eingeschaltet und noch einmal zwei Tage gemessen.
Zur Einordnung: Dieser Warmer heisst warmup.rocks und ist mein eigener kommerzieller Dienst. Gebaut habe ich ihn, weil ich das Problem mit dem Cache früh gesehen habe, in erster Linie für mich und meine Kunden. Auch The Weekly Dash wird damit gewärmt. Ausserdem bin ich Maintainer bei EmDash, und alle Seiten in diesem Artikel laufen auf Cloudflare Workers, auch linguadash.dev. Das ist die Website von LinguaDash, meinem kostenlosen Plugin, das EmDash-Websites mehrsprachig macht.
Cold Start oder kalter Cache?
Die beiden Begriffe klingen ähnlich und meinen Verschiedenes. Bei einem Cold Start muss Cloudflare den Worker erst laden, kompilieren und einmal ausführen, bevor er antworten kann. Das ist selten geworden: Laut Cloudflare treffen heute 99,99 % der Anfragen einen bereits warmen Worker, gemessen an Enterprise-Verkehr. Beim kalten Cache läuft der Worker längst, aber die fertige Seite liegt nicht bereit. EmDash muss sie neu bauen und dafür die Datenbank fragen. Wer von WordPress kommt, kennt das Gefühl: Ein kalter Cache benimmt sich wie eine schlecht gecachte WordPress-Seite, die jeden Aufruf frisch aus PHP und Datenbank zusammensetzt. Nur machen hier ein Worker und D1 die Arbeit.
Auf einer wenig besuchten Seite trifft beides zusammen, und auf linguadash.dev lässt sich das auseinandernehmen. Aus dem Cache kam eine Seite in 47 bis 65 Millisekunden. Musste EmDash sie neu bauen und der Worker lief schon, waren es 326 Millisekunden. Lief er noch nicht, waren es 1,5 und 2,0 Sekunden, und rund 900 Millisekunden davon vergingen, bevor EmDash überhaupt anfing. Das ist der eigentliche Cold Start. Ein Treffer im Cache erspart beides.
Wie der Workers Cache funktioniert
EmDash nutzt auf Cloudflare den Workers Cache, und der gehört dem Worker, nicht der Domain. Deshalb wirken Cache Rules, Page Rules und alle anderen Cache-Einstellungen im Dashboard nicht darauf. Gesteuert wird er allein über die Header, die eine Seite mitschickt. Wie wir sie auf The Weekly Dash gesetzt haben, steht in Edge-Caching für EmDash auf Cloudflare. Der Cache ist gestuft: Jedes Rechenzentrum hat seinen eigenen Cache, darüber liegt eine gemeinsame Ebene.
Wer von WordPress hinter Cloudflare kommt, kennt ein Sicherheitsnetz. Mit einer Cache Rule wird das HTML cachebar, und Cache Reserve hält Seiten bis zu 30 Tage nach dem letzten Abruf in einem zentralen Speicher, auch wenn die Rechenzentren sie längst verdrängt haben. Für EmDash im Worker gibt es dieses Netz nicht. Fällt eine Seite aus dem Rechenzentrum und aus der gemeinsamen Ebene, baut der Worker sie neu.
Eine Seite landet erst im Cache, wenn sie einmal ausgeliefert wurde. Vorwärmen kann man ihn nicht, das schreibt Cloudflare ausdrücklich in die Grenzen des Dienstes. Geleert wird er auf zwei Wegen. Jeder Deploy beginnt von vorn, weil die Version des Workers zum Cache-Schlüssel gehört, ausser man schaltet cache.cross_version_cache ein. Und beim Veröffentlichen löscht EmDash Seiten über Tags. Dazu kommt, dass Cloudflare selten abgerufene Seiten früher verdrängen darf, als ihre Lebensdauer erlauben würde. Die eingestellte Zeit ist eine Obergrenze, keine Zusage.
Auf der Demo ist eine Seite fünf Minuten frisch. Danach darf Cloudflare bis zu einer Woche die alte Kopie ausliefern und sie im Hintergrund erneuern, das heisst stale-while-revalidate, und im Header steht dann UPDATING. Der Leser wartet in diesem Fall nicht.
Wann der Cache kalt wird
Drei Dinge leeren den Cache einer EmDash-Seite: ein Deploy, ein Veröffentlichen und Stille. Das erste ist zu erwarten, das zweite trifft weit mehr Seiten, als man denkt, und das dritte ist seltener als befürchtet, aber nicht vorhersehbar.
Nach dem Deploy beginnt alles von vorn
Ohne cross_version_cache bekommt jede neue Version des Workers einen leeren Cache, auch die nach einem EmDash-Update. Wie sich das anfühlt, zeigte schon der Start der Messung: Der letzte Deploy lag gut zwei Stunden zurück, Besuch hatte die Demo seit zwei Tagen kaum. Von 36 ersten Abrufen, je Seite und Land, waren 28 ein MISS. Bis zum ersten Byte vergingen im Median 1,7 Sekunden, bei jedem zehnten Abruf mehr als 5 Sekunden. Aus dem Cache wären es rund 50 Millisekunden gewesen. Beim Update der Demo auf EmDash 1.3.1 habe ich das gezielt gemessen. Kurz vor dem Deploy kamen 31 von 36 Abrufen aus sechs Ländern in unter 200 ms, im Median nach 68 ms. Zwei Sekunden nach dem Deploy waren es noch 4 von 36, im Median dauerte es 1,3 Sekunden. Auch die meisten Abrufe mit HIT warteten, weil sie auf denselben Neubau angewiesen waren.

Auf theweeklydash.com sieht man dasselbe in den Daten des Warmers. Nach den Deploys vom 7. und 8. Oktober 2026 kam in keinem Rechenzentrum mehr eine Kopie, die älter war als der Deploy. Viele Rechenzentren meldeten danach zwar HIT, aber mit einer Kopie, die im selben Augenblick entstanden war wie der erste MISS. Den Preis zahlt also nicht jeder, sondern der erste Abruf. Er baut die Seite, und die übrigen bekommen sie vermutlich über die gemeinsame Ebene. Dasselbe passiert bei jedem Purge: Auf scllauerz.ch, der EmDash-Seite eines Sportvereins, aktualisiert ein Cron-Job jede Nacht kurz nach Mitternacht den Kalender und löscht dabei alle Seiten. In den Daten des Warmers zeigt sich dasselbe Muster dort 30 Mal.
Ein Beitrag geändert, die ganze Seite kalt
Das ist die Szene vom Anfang. Um 08:00 Uhr Schweizer Zeit habe ich auf der Demo einen einzigen Beitrag neu veröffentlicht, mit einem geänderten Wort im Kurztext. In den zwei Stunden danach war jede der 25 Messungen in der Schweiz, in Grossbritannien, den USA, Singapur und Brasilien ein MISS, mit 0,3 bis 2,1 Sekunden bis zum ersten Byte. Nicht nur beim geänderten Beitrag, sondern auf allen gemessenen Seiten, auch auf Artikeln, die ich nicht angefasst hatte.
Die Erklärung steht im Code. Beim Veröffentlichen löscht EmDash 1.2 alles, was das Tag der Sammlung trägt, hier posts. Dieses Tag bekommt jede Seite, die eine Beitragsliste zeigt. In den offiziellen Vorlagen blog und blog-cloudflare ist das jeder einzelne Artikel, denn unter jedem stehen die neuesten Beiträge. Ein Wort im Kurztext leert so den Cache aller Artikel, in allen Sprachen und in jedem Rechenzentrum. Und der Astro-Adapter löscht hart: Statt die Kopien nur als veraltet zu markieren, sodass Leser die alte Fassung bekämen, während im Hintergrund die neue entsteht, wirft er sie weg. Daran hat auch EmDash 1.3 nichts geändert, und cross_version_cache hilft hier nicht, weil es nur Deploys betrifft. Auf 1.3.1 war am 20. Oktober nach dem Veröffentlichen in der ersten Stunde keine von 12 Messungen schnell.
Einen Tag später habe ich die Probe wiederholt. Eine halbe Minute vor dem Veröffentlichen kam die Startseite in allen sechs gemessenen Ländern aus dem Cache, in 28 bis 84 Millisekunden. Direkt danach war sie in fünf davon ein MISS, in Singapur mit 1,7 Sekunden bis zum ersten Byte.

Was niemand abruft, hält länger als gedacht, aber nicht sicher
Die dritte Ursache ist die leiseste. Cloudflare darf selten abgerufene Seiten verdrängen, lange bevor ihre eingestellte Lebensdauer abläuft, und sagt nicht, wann. Also habe ich es gemessen: Eine Seite der Demo wurde einmal aus 47 Standorten abgerufen und danach nicht mehr angefasst. Später kam aus jedem Standort genau ein Kontrollabruf, nach 10 Minuten, 1, 3, 6, 12 und 24 Stunden, jeweils mit einer eigenen Adresse.
Das Ergebnis ist besser als befürchtet. Nach 24 Stunden ohne Besuch lag die Kopie in 40 von 42 Rechenzentren noch da und kam sofort. Frankfurt und Mailand hielten sie in einer zweiten Messreihe ebenfalls einen ganzen Tag, und in Genf lieferte linguadash.dev eine Kopie sogar nach rund 44 Stunden noch aus.
Wirklich verschwunden war die Kopie in der ganzen Messung nur einmal, nach 24 Stunden in San José. Sicher schnell war es trotzdem nicht, aus einem anderen Grund. Sechsmal kam ein Kontrollabruf langsam, obwohl die Kopie da war. Jedes Mal waren zwei Standorte zur selben Sekunde im selben Rechenzentrum gelandet, etwa Bangkok und Singapur in Singapur. Der eine bekam sofort die alte Kopie, und damit begann der Neubau. Der andere bekam erst die neue Fassung und wartete dafür knapp 1 bis 14,8 Sekunden. Wer also gleichzeitig mit einem anderen Besucher auf eine abgelaufene Kopie trifft, kann warten wie bei einem MISS. So lese ich die Daten, gezielt geprüft habe ich es nicht. Dazu gehört eine Einschränkung: Die Seite wurde aus 47 Standorten gefüllt, die gemeinsamen Ebenen waren also voll. Eine Seite, die nur ein einzelner Leser aufgerufen hat, fällt vermutlich eher heraus, und die Demo hat sieben Artikel und kaum Verkehr.
Und wenn die Kopie noch da ist
Wurde eine Seite einmal besucht, hilft stale-while-revalidate. Von 101 Wiederbesuchen im Abstand von drei Stunden kamen 84 sofort aus dem Cache, im Median nach 48 Millisekunden, obwohl die Kopie längst nicht mehr frisch war. 13 kamen als EXPIRED, im Median nach 1,6 Sekunden. Die Kopie lag also bereit, und trotzdem liess Cloudflare den Leser warten, bis die neue Fassung gebaut war. Warum es in diesen Fällen nicht UPDATING wählt, konnte ich nicht klären. Ein Muster gibt es aber: Von den 34 EXPIRED ohne Warmer kamen 22 aus den USA, 8 aus der Schweiz und 4 aus Grossbritannien, keines aus Deutschland, Singapur oder Brasilien. In den USA und der Schweiz landeten die Messungen abwechselnd in verschiedenen Rechenzentren, in den anderen drei Ländern fast immer im selben. EXPIRED traf also vor allem Rechenzentren, die die Seite nicht selbst geladen hatten.
Was das für Google und ChatGPT heisst
Leser sind nicht die Einzigen, die auf kalte Seiten treffen. Suchmaschinen und KI-Dienste rufen regelmässig ab, und zwar gerade die Seiten, die sonst kaum jemand besucht: alte Artikel, Rubriken, die dritte Seite einer Liste. Genau die bleiben nach einem Deploy oder Veröffentlichen kalt, bis jemand vorbeikommt, und oft ist das der Crawler. Er wartet dann so lange wie ein Leser, also ein bis zwei Sekunden, im ungünstigen Fall fünf.
Google sagt offen, was daraus folgt. Bleiben Antwortzeiten und Time to First Byte stabil, öffnet Googlebot mehr Verbindungen. Wird eine Seite langsamer, crawlt er weniger (Crawl-Budget). Kümmern muss man sich darum laut Google aber erst bei grossen Seiten, etwa ab 10'000 Seiten mit täglich neuem Inhalt. Ein Blog mit ein paar Dutzend Artikeln betrifft das kaum. Ins Ranking fliesst die Geschwindigkeit ohnehin nicht über den Crawler ein, sondern über die Core Web Vitals, und die misst Chrome bei echten Besuchern. Dort zählt jeder Leser, der auf einen MISS trifft.
Bei KI-Diensten weiss man weniger. OpenAI unterscheidet drei Bots: GPTBot sammelt Trainingsdaten, OAI-SearchBot baut die Suche auf, und ChatGPT-User ruft eine Seite ab, wenn jemand in ChatGPT danach fragt. Wie lange diese Bots auf eine Antwort warten, bevor sie aufgeben, dokumentiert OpenAI nicht, und gemessen habe ich es nicht. In der Theorie braucht eine kalte Seite ihre zwei Sekunden also genau dann, wenn ChatGPT sie für eine Antwort holt.
Was ein Warmer bringt
Je zwei Tage auf der Demo, ohne die Stunden nach dem Veröffentlichen | Ohne Warmer, EmDash 1.2 | Mit Warmer, EmDash 1.2 | Mit Warmer, EmDash 1.3.1 und |
|---|---|---|---|
Erstes Byte in unter 200 ms | 370 von 478 (77 %) | 435 von 466 (93 %) | 449 von 478 (94 %) |
Länger als eine Sekunde | 87 | 11 | 12 |
Median | 66 ms | 66 ms | 59 ms |
- Mehr schnelle Antworten: Je zwei Tage ohne und mit Warmer, gleiche sechs Standorte, gleiche sechs Seiten. Die Stunden nach dem Veröffentlichen um 06:00 UTC lasse ich hier weg. Ohne Warmer kam das erste Byte bei 370 von 478 Messungen in unter 200 ms (77 %), mit Warmer bei 435 von 466 (93 %). Am meisten gewannen die USA: 45 von 80 ohne, 71 von 84 mit Warmer.
- Weniger Ausreisser: Der Median lag in beiden Phasen bei 66 ms. Den Unterschied machen die langsamen Abrufe: Ohne Warmer dauerten 87 Messungen länger als eine Sekunde, die langsamste 5,3 Sekunden. Mit Warmer waren es 11, die langsamste 2,3 Sekunden.
- Veröffentlichen mit Warmer: Das Veröffentlichen leerte die gemessenen Seiten, fast jeder erste Abruf danach war ein MISS. Der Warmer lief im Zwei-Stunden-Takt und kam erst rund 90 Minuten später wieder vorbei. Bis dahin waren am 15. Oktober 0 von 24 Messungen schnell, am 16. Oktober 4 von 24. Nach seinem Durchlauf waren es 8 von 12 und 10 von 12. Ein Warmer nach Zeitplan hilft beim Veröffentlichen also erst mit dem nächsten Durchlauf. Wie sehr es auf diesen Abstand ankommt, zeigten zwei Tage später zwei Morgen hintereinander. Am 20. Oktober kam der Warmer 102 Minuten nach dem Veröffentlichen, und bis dahin war keine von 24 Messungen schnell. Am 21. Oktober kam er schon nach vier Minuten, und in derselben Zeit waren 16 von 24 schnell. Besser wäre also ein Warmer, den das Veröffentlichen selbst auslöst. Das habe ich nicht gemessen.
- Auch auf EmDash 1.3: Zwei weitere Tage mit Warmer, jetzt auf 1.3.1 und mit
cross_version_cache, brachten dasselbe Bild wie mit 1.2, siehe die letzte Spalte. In diesen zwei Tagen gab es keinen Deploy, die Einstellung konnte hier also nichts beitragen. - Bei echten Lesern: Auf theweeklydash.com kamen in den zwei Tagen vor dem Start von warmup.rocks 443 von 894 Seitenaufrufen aus dem Cache (50 %), in den zwei Tagen danach 768 von 968 (79 %). Gezählt habe ich nur HTML mit Status 200, ohne Bots und ohne den Warmer. Ein sauberer Vergleich ist das nicht, weil wir in derselben Zeit mehrmals deployt und veröffentlicht haben.
- Was die Wärme kostet: Im selben Vergleich stiegen die Leseabfragen an D1 von 215'000 auf 482'000 in zwei Tagen und die CPU-Zeit pro Aufruf im Median von 13 auf 43 ms. Fast jedes zusätzliche Rendern passiert für den Warmer, nicht für Leser.
Fazit: Was gegen den kalten Cache hilft
Langsam ist eine EmDash-Seite auf Cloudflare fast nur dann, wenn eine Seite nicht im Cache liegt. Das passiert nach jedem Deploy, nach jedem Veröffentlichen und bei Seiten, die eine Weile niemand aufgerufen hat. Liegt sie im Cache, kommt sie in unter 100 ms, auch wenn die Kopie veraltet ist. Daraus folgen fünf Tipps, die ersten vier ohne Warmer.
1. Lange stale-while-revalidate setzen. Bei uns heisst das fünf Minuten frisch und eine Woche die alte Kopie ausliefern. In Astro ist das eine Zeile pro Route: { maxAge: 300, swr: 604800 }. Damit kamen auf der Demo 84 von 101 Wiederbesuchen sofort. Wichtig: kein must-revalidate im CDN-Header, sonst wartet jeder Leser nach Ablauf.
2. Den Cache über Deploys retten. Mit "cache": { "enabled": true, "cross_version_cache": true } in der Wrangler-Konfiguration startet ein Deploy nicht mehr mit leerem Cache (Cross-version caching). Der Preis: Eine Änderung am Layout erscheint erst, wenn die Seiten ablaufen oder du sie löschst. Auf der Demo hat es gewirkt: Nach einem Deploy mit dieser Einstellung kamen 29 von 30 Abrufen weiter aus dem Cache, 28 davon in unter 200 ms, im Median nach 66 ms. Ohne die Einstellung waren es nach dem Update 4 von 36. Der erste Deploy, der die Einstellung einschaltet, startet allerdings selbst noch leer. Erst ab dem nächsten teilen sich die Versionen den Cache. Gegen das Leeren beim Veröffentlichen hilft die Einstellung nicht.
3. Beitragslisten nur dort zeigen, wo sie nötig sind. Jede Seite mit einer Beitragsliste wird beim Veröffentlichen gelöscht. Eine Box «Neueste Beiträge» unter jedem Artikel heisst: Jedes Veröffentlichen leert alle Artikel. Das gilt auch für Korrekturen an einem bestehenden Beitrag und fürs Einplanen. In EmDash 1.2 leeren sogar ein neuer Entwurf und das Duplizieren eines Beitrags alle Listen, obwohl Leser davon nichts sehen. Das habe ich bei der Recherche zu diesem Artikel gefunden und behoben, der Fix steckt in EmDash 1.3. Wer viel korrigiert, sammelt die Korrekturen und speichert einmal.
4. Einen Miss billiger machen. Ein Miss kostet ein Rendern mit Datenbankabfragen. Jede Abfrage, die nacheinander statt gleichzeitig läuft, verlängert ihn. Auf linguadash.dev dauerte ein Rendern mit laufendem Worker 326 ms, mit kaltem Worker 1,5 bis 2 Sekunden. Weniger Abfragen und ein Worker nahe bei der Datenbank (Placement) drücken beides. Und die Datenbank gehört in die Nähe der Leser: Steht D1 in Nordamerika und lesen die meisten in Europa, kostet jede Abfrage rund 140 ms.
5. Einen Warmer einsetzen. Cloudflare kann den Cache nicht vorwärmen, eine Seite liegt erst im Cache, nachdem jemand sie abgerufen hat. Ein Warmer ruft die Seiten nach jedem Deploy und Veröffentlichen ab, bevor es ein Leser tut, und hält selten besuchte Seiten im Cache. In WordPress kennt man das als Preload eines Cache-Plugins, nur dass es hier jedes Rechenzentrum einzeln braucht. Auf der Demo kamen mit Warmer 93 statt 77 Prozent der Abrufe in unter 200 ms, und Abrufe über einer Sekunde gab es noch 11 statt 87. Das kostet: mehr Datenbankabfragen und mehr Rechenzeit, auf theweeklydash.com rund doppelt so viele Leseabfragen. Und ein Warmer hilft fast nur den Rechenzentren, aus denen er abruft. Im Versuch habe ich eine neue Adresse einmal aus Zürich abgerufen und eine Minute später aus 19 Ländern: Die gewärmte Kopie lag danach nur in Mailand, wo der Abruf gelandet war, und in Frankfurt. Beim selben Versuch aus Singapur half sie keinem anderen Rechenzentrum, auch Tokio, Sydney und Mumbai nicht. Das ist weniger, als Cloudflare verspricht: Laut Doku füllt der erste Abruf irgendwo auf der Welt die gemeinsame Ebene, und danach kann jedes Rechenzentrum von dort bedient werden. In meinen zwei Durchgängen half die Kopie höchstens einem Nachbarn. warmup.rocks ruft deshalb aus 38 Ländern und direkt aus der Schweiz ab und erreichte damit auf der Demo pro Durchlauf 29 bis 36 Rechenzentren, über eine Woche zusammen 55. Cloudflare ist in 348 Städten präsent. Wo der Warmer nicht hinkommt, zahlt der erste Leser.
Was nicht hilft: Cache Rules, Page Rules, Cache Reserve und der Smart Tiered Cache im Cloudflare-Dashboard. Sie gelten für den Cache der Domain, nicht für den Cache des Workers, das listet Cloudflare in den Grenzen des Workers Cache ausdrücklich auf. Gestuft ist der Workers Cache trotzdem, automatisch und ohne Schalter.
Am Ende ist es weniger eine Frage der Technik als der Gewohnheit. Wer weiss, dass jedes Veröffentlichen und jeder Deploy den Cache leert, plant beides anders, und dann ist eine EmDash-Seite auf Cloudflare fast immer so schnell, wie sie sein kann.

Kommentare
Erstkommentare erscheinen nach unserer Freigabe. Was mit deinen Angaben passiert