Zum Inhalt springen
CASOON

Cloudflare + Astro + Rust: Warum dieses Stack-Dreieck für mich das Optimum ist

Edge-Runtime, Content-Framework, Systems-Sprache – wie drei Technologien zusammenpassen, die man selten gemeinsam nennt

14 Minuten
Cloudflare + Astro + Rust: Warum dieses Stack-Dreieck für mich das Optimum ist
#Cloudflare #Astro #Rust #WebAssembly

Wenn man lange genug Webprojekte baut, entwickelt man ein Gespür dafür, wo Reibung entsteht. Nicht die offensichtliche Reibung – Build bricht, Dependency fehlt. Sondern die strukturelle: Dev und Production verhalten sich anders. Das Backend braucht einen eigenen Server. Deployment ist ein eigener Workflow. Skalierung kostet Geld, bevor ein einziger Nutzer da ist.

Seit Cloudflare Astro übernommen hat und Rust-basierte Workers produktionsreif sind, gibt es einen Stack, der diese Reibung fast vollständig eliminiert. Nicht theoretisch – in der täglichen Arbeit.

Die drei Schichten

Astro: Das Frontend-Framework, das sich zurückhält

Astro ist kein Full-Stack-Framework, das alles können will. Es ist ein Content-Framework, das HTML ausliefert – schnell, mit minimaler Client-Side-Runtime, und mit der Möglichkeit, gezielt interaktive Inseln einzubauen (React, Svelte, Vue, was auch immer).

Seit Astro 6 läuft der Dev-Server auf Cloudflares workerd-Runtime. Das heißt: astro dev und Production sind identisch. Kein “works on my machine”, kein Node.js-Shim für Cloudflare-APIs. Was lokal läuft, läuft auf dem Edge.

Was Astro in diesem Stack übernimmt:

  • SSG und SSR mit automatischer Entscheidung pro Route
  • Content Collections für strukturierte Inhalte
  • Server Islands für dynamische Fragmente in statischen Seiten
  • API-Routes als leichtgewichtige Endpunkte
  • Zugriff auf alle Cloudflare-Bindings über Astro.locals.runtime

Cloudflare Workers: Die Runtime ohne Server

Workers sind keine Container. Sie laufen auf V8-Isolates – derselben Engine wie Chrome und Node.js, aber ohne das Betriebssystem drumherum. Das Ergebnis: Cold Starts unter 50ms, Ausführung auf über 300 Edge-Locations weltweit, Abrechnung pro Request statt pro Stunde.

Dazu kommen die integrierten Services, die man bei anderen Anbietern einzeln zusammenstecken muss:

ServiceFunktionVergleichbar mit
KVKey-Value Store, global repliziertRedis (für Lesezugriffe)
D1SQLite-Datenbank auf dem EdgeManaged SQLite / PlanetScale
R2Object Storage, S3-kompatibelAWS S3
Durable ObjectsStateful Serverless, Single-ThreadedKein direktes Äquivalent
QueuesAsynchrone NachrichtenverarbeitungSQS / RabbitMQ
AIInference auf Cloudflares GPU-NetzReplicate / Hugging Face Inference

Das Entscheidende: All diese Services sind über Bindings erreichbar – kein HTTP-Call, kein SDK-Import, keine Latenz. Ein Binding ist ein In-Process-Zugriff auf dem selben Server.

Rust via WebAssembly: Das Backend ohne Docker

Hier wird es interessant. Rust kompiliert über wasm32-unknown-unknown zu WebAssembly und läuft als Worker auf Cloudflares Netz. Kein Container, kein Server, kein Deployment-Pipeline-Overhead.

Das workers-rs-Crate bietet Zugriff auf alle Cloudflare-Bindings – KV, D1, R2, Durable Objects, Queues, AI – direkt aus Rust. Über das http-Feature-Flag nutzt es Standard-http-Crate-Typen. Damit läuft axum als Router direkt auf Workers:

use axum::{routing::get, Router};
use worker::*;

async fn health() -> &'static str {
    "ok"
}

fn router() -> Router {
    Router::new().route("/health", get(health))
}

#[event(fetch)]
async fn fetch(
    req: HttpRequest,
    _env: Env,
    _ctx: Context,
) -> Result<http::Response<axum::body::Body>> {
    Ok(router().call(req).await?)
}

Das ist ein vollwertiger HTTP-Service – mit Routing, Middleware, JSON-Serialisierung via Serde – ohne Docker, ohne Server, ohne Port-Mapping.

Warum WebAssembly hier Docker ersetzt

Nicht pauschal. Nicht für alles. Aber für die typischen Backend-Services einer Webanwendung – API-Endpunkte, Datenverarbeitung, Auth-Logik – macht WASM auf Workers das Docker-Setup überflüssig.

Was wegfällt

  • Kein Dockerfile. Kein Base-Image, keine Multi-Stage-Builds, keine Image-Registry.
  • Kein Server-Management. Kein Provisioning, kein SSH, keine Uptime-Überwachung.
  • Kein Port-Mapping. Kein Nginx-Reverse-Proxy, kein Docker-Compose-Netzwerk.
  • Kein Cold-Start-Problem in der Praxis. Cloudflare parallelisiert den WASM-Start mit dem TLS-Handshake – der Nutzer merkt nichts.
  • Kein Skalierungsproblem. Workers skalieren automatisch auf Tausende gleichzeitiger Requests. Keine Replica-Sets, kein Load Balancer.

Was bleibt

Rust auf Workers hat klare Grenzen:

  • 128 MB RAM pro Invokation. Für die meisten API-Workloads irrelevant, für Bildverarbeitung oder große Datenmengen ein echtes Limit.
  • Maximal 5 Minuten CPU-Zeit (Paid Plan). Batch-Jobs, die länger laufen, brauchen eine andere Lösung.
  • Kein Dateisystem. Kein std::fs, kein temporäres Verzeichnis. Daten müssen über KV, R2 oder D1 fließen.
  • Kein Threading. Workers sind Single-Threaded. Kein Tokio, kein async_std. Das worker-Crate bringt seinen eigenen Executor mit.
  • Nicht jede Rust-Crate kompiliert. Alles, was auf std::net, std::thread oder std::fs zugreift, funktioniert nicht auf wasm32-unknown-unknown. Das betrifft reqwest, diesel, sqlx und andere.

Wann Docker trotzdem richtig ist

  • Datenbank-Server (PostgreSQL, MySQL)
  • Batch-Jobs über 5 Minuten CPU-Zeit
  • Workloads über 128 MB RAM
  • Services, die nativen OS-Zugriff brauchen
  • Legacy-Anwendungen, die nicht auf WASM portiert werden können

Seit Mitte 2025 bietet Cloudflare auch Cloudflare Containers (Public Beta) – Docker-Container, die von Workers orchestriert werden. Scale-to-Zero ist möglich, aber noch als Beta-Feature gekennzeichnet. Für die Fälle, die Workers allein nicht abdecken, bleibt man im selben Ökosystem.

Architektur: Wie die drei Schichten zusammenspielen

1
Nutzer-Request
2
Astro Worker SSR, HTML, Routing, statische Assets (Service Binding)
3
Rust Worker API-Logik, Validierung, Berechnung (Bindings)
4
D1 / KV / R2 / Durable Objects

Service Bindings: Microservices ohne Netzwerk

Der Astro Worker ruft den Rust Worker nicht über HTTP auf. Stattdessen nutzt er ein Service Binding – ein In-Process-Call auf demselben Cloudflare-Server. Keine DNS-Auflösung, kein TLS-Handshake, keine Serialisierungskosten.

In der wrangler.toml des Astro Workers:

[[services]]
binding = "API"
service = "my-rust-worker"

Im Astro API-Route:

export async function GET({ locals }) {
  const { env } = locals.runtime;

  const response = await env.API.fetch(
    new Request('https://internal/products', {
      method: 'GET',
    })
  );

  return new Response(await response.text(), {
    headers: { 'Content-Type': 'application/json' },
  });
}

Der Rust Worker braucht keine öffentliche URL. Er ist nur über das Binding erreichbar – ein internes, typsicheres Interface zwischen Frontend und Backend.

Unabhängige Deployments

Astro und Rust Worker werden getrennt deployt. Das Frontend kann ein neues Design ausrollen, ohne das Backend anzufassen. Das Backend kann eine neue API-Version deployen, ohne den Build des Frontends auszulösen. Beide leben im selben Cloudflare-Account, nutzen dieselben Bindings, sind aber eigenständige Einheiten.

Performance: Was die Kombination bringt

Kein Origin-Server

Bei einem klassischen Setup geht jeder dynamische Request vom Edge zum Origin und zurück. Bei Cloudflare Workers gibt es keinen Origin. Astro rendert auf dem Edge. Der Rust Worker läuft auf dem Edge. D1 und KV liegen auf dem Edge. Die gesamte Kette – vom Request bis zur Antwort – findet auf dem nächstgelegenen Cloudflare-Server statt.

Cold Starts vs. Docker

MetrikDocker (klassisch)Rust Worker
Cold Start1-30 Sekundenunter 50ms
Standby-KostenJa (Server läuft immer)Nein (Pay per Request)
SkalierungManuell oder Auto-Scaling mit DelayAutomatisch, sofort
Globale Verfügbarkeit1 Region (oder Multi-Region Setup)300+ Locations

Wann Rust schneller ist als JS/TS

Nicht immer. Für I/O-lastige Aufgaben – KV-Lookups, D1-Queries, externe API-Calls – ist JavaScript auf Workers schneller, weil kein WASM-Bridge-Overhead entsteht.

Rust lohnt sich, wenn CPU-intensive Arbeit anfällt:

  • JSON-Parsing großer Payloads
  • Daten-Transformation und Validierung
  • Kryptographie und Hashing
  • Bildverarbeitung (Cloudflare hat ihr Images-Produkt in Rust auf Workers gebaut)
  • Encoding/Decoding (Base64, Protobuf, CSV)

Für reine Proxy- oder Routing-Logik ist TypeScript auf Workers die pragmatischere Wahl.

Kosten: Was das Setup kostet

Cloudflare Workers Paid Plan

PostenInklusivÜberschreitung
Grundgebühr5 USD/Monat-
Requests10 Mio/Monat0,30 USD pro Mio
CPU-Zeit30 Mio ms/Monat0,02 USD pro Mio ms
KV Reads10 Mio/Monat0,50 USD pro Mio
D1 Reads25 Mio Zeilen/Monat0,001 USD pro Mio
R2 Storage10 GB0,015 USD pro GB
EgressKostenlosKostenlos

Vergleich mit klassischem Setup

Für eine typische Content-Website mit API-Backend (500.000 Requests/Monat):

SetupMonatliche Kosten
Cloudflare Workers (Astro + Rust)ca. 5 USD
Hetzner VPS + Docker + Nginxca. 5-10 EUR
Vercel Pro + separates Backendca. 20+ USD
AWS (CloudFront + Lambda + RDS)ca. 30-100 USD

Der Kostenvorteil von Workers kommt nicht aus günstigeren Preisen pro Einheit, sondern aus drei Faktoren: kein Egress-Traffic, kein Standby-Verbrauch und keine Infrastruktur-Verwaltung.

Bei hohem Traffic (über 50 Mio Requests) oder CPU-intensiven Workloads dreht sich das Verhältnis um – dann kann ein gut ausgelasteter VPS günstiger sein.

Der Build-Workflow

Astro

# Installation
npx astro add cloudflare

# Development (läuft auf workerd)
astro dev

# Build + Deploy
astro build && wrangler deploy

Rust Worker

# wrangler.toml
name = "my-api"
main = "build/worker/shim.mjs"
compatibility_date = "2026-01-01"

[build]
command = "cargo install -q worker-build && worker-build --release"
# Cargo.toml
[lib]
crate-type = ["cdylib"]

[dependencies]
worker = "0.8"
serde = { version = "1", features = ["derive"] }
serde_json = "1"

[profile.release]
opt-level = "s"
lto = true
codegen-units = 1
# Development
wrangler dev

# Deploy
wrangler deploy

Beide Workflows sind wrangler-basiert. Kein separater CI/CD-Prozess nötig – obwohl man natürlich einen haben kann.

Binary-Größe optimieren

Rust-WASM-Binaries können groß werden. Über 1 MB komprimiert verschlechtert sich die Cold-Start-Performance spürbar. Die wichtigsten Stellschrauben:

  • opt-level = "s" statt "3" – optimiert auf Größe statt Geschwindigkeit
  • lto = true – Link-Time-Optimization entfernt ungenutzten Code
  • codegen-units = 1 – bessere Optimierung, längerer Build
  • Abhängigkeiten minimieren – jede Crate, die mitkompiliert wird, vergrößert das Binary
  • wasm-opt läuft automatisch über worker-build

Das Bundle-Limit liegt bei 10 MB komprimiert (Paid Plan). In der Praxis sollte man unter 1 MB bleiben.

Datenschutz und Datenlokalisierung

Für deutsche und europäische Projekte ist die DSGVO-Frage nicht optional. Cloudflare hat hier in den letzten Jahren nachgelegt:

  • Workers laufen in EU-Rechenzentren. Cloudflare betreibt Server unter anderem in Frankfurt, Amsterdam, Paris und Dublin. Über die Data Localization Suite lässt sich erzwingen, dass Daten nur in EU-Regionen verarbeitet werden.
  • D1, KV und R2 sind standardmäßig global verteilt. Für DSGVO-sensible Daten muss man die Datenlokalisierung explizit konfigurieren – bei R2 über die Region-Wahl beim Erstellen des Buckets, bei D1 über den Location Hint.
  • Kein US-Cloud-Act-Problem im klassischen Sinn. Cloudflare ist ein US-Unternehmen, aber die Verarbeitung personenbezogener Daten kann über die Lokalisierungsoptionen in der EU gehalten werden. Das DPA (Data Processing Agreement) von Cloudflare deckt die EU-Standardvertragsklauseln ab.

In der Praxis: Für Content-Websites ohne personenbezogene Daten (kein Login, keine Formulare mit PII) ist das unproblematisch. Sobald Nutzerdaten ins Spiel kommen – Kontaktformulare, Kundenkonten, Analytics – muss man die Lokalisierung aktiv konfigurieren. Das ist kein Showstopper, aber es ist kein Automatismus.

Lokale Entwicklung: Was wirklich offline läuft

Astro 6 mit dem Cloudflare-Adapter nutzt im Dev-Modus workerd lokal – die gleiche Runtime wie in Production. Das funktioniert ohne Cloudflare-Account für reine Astro-Features, Content Collections und SSR.

Für den Rust Worker sieht es anders aus: wrangler dev startet eine lokale Instanz über Miniflare, das die Workers-Umgebung simuliert. KV, D1 und R2 laufen dabei als lokale SQLite- bzw. Datei-basierte Backends – kein Cloudflare-Account nötig für die Entwicklung.

# Astro Dev-Server (workerd-basiert, lokal)
astro dev

# Rust Worker Dev-Server (Miniflare-basiert, lokal)
wrangler dev

# Beide zusammen: Astro ruft Rust Worker via Service Binding auf
# → Aktuell noch getrennte Prozesse, kein Hot-Reload über die Grenze

Die Einschränkung: Service Bindings zwischen Astro und Rust Worker funktionieren lokal nur, wenn beide Prozesse laufen und korrekt verlinkt sind. Das Setup ist etwas umständlicher als ein einzelner docker-compose up, dafür ist jeder Teil unabhängig testbar.

Was diese Kombination nicht kann

Kein Stack ist universell. Cloudflare + Astro + Rust passt nicht für:

  • SPAs mit komplexem Client-State. Astro ist ein Content-Framework. Für eine Figma-artige Anwendung nimmt man React oder Svelte als Haupt-Framework.
  • Schwere Datenbank-Workloads. D1 ist SQLite auf dem Edge – für einfache Queries hervorragend, für komplexe Joins oder Volltextsuche über Millionen Zeilen nicht gedacht. Wer PostgreSQL braucht, braucht einen echten Datenbankserver.
  • Langläufer. Batch-Verarbeitung, Video-Encoding, ML-Training – alles über 5 Minuten CPU-Zeit gehört nicht auf Workers.
  • Teams ohne Rust-Erfahrung. Der Rust-Layer ist optional. Wer TypeScript bevorzugt, baut das Backend als normalen Worker in TS. Die Astro-Cloudflare-Kombination funktioniert auch ohne Rust.

Warum nicht Next.js + Vercel?

Die Frage kommt unweigerlich. Kurz:

  • Vercel ist teurer. Egress kostet, Pro-Plan kostet, Bandwidth-Limits existieren.
  • Next.js ist schwerer. Mehr Client-Side JavaScript, längere Ladezeiten für Content-Sites.
  • Vendor Lock-in ist stärker. Next.js auf Nicht-Vercel-Plattformen zu deployen erfordert Workarounds. Astro auf Nicht-Cloudflare-Plattformen funktioniert out of the box.
  • Runtime-Overhead. Next.js braucht eine Node.js-Runtime oder Edge Runtime mit Einschränkungen. Astro auf Cloudflare läuft nativ auf V8-Isolates.

Für komplexe React-Anwendungen mit viel Interaktion ist Next.js nach wie vor die bessere Wahl. Für Content-getriebene Websites, Marketing-Seiten, Blogs, Dokumentation und hybride Sites mit punktueller Interaktion ist Astro auf Cloudflare performanter, günstiger und einfacher zu betreiben.

Migration: Wie man aus einem bestehenden Setup kommt

Wer aktuell auf Next.js + Vercel, Netlify oder einem VPS mit Docker sitzt, kann schrittweise umsteigen.

Von Next.js zu Astro

Astro kann React-Komponenten direkt einbinden – als Islands mit client:load oder client:visible. Das bedeutet: Man muss nicht alle Komponenten neu schreiben. Seiten lassen sich Stück für Stück migrieren, während bestehende React-Logik als interaktive Inseln weiterlebt.

Die größte Umstellung ist das Routing: Next.js nutzt Dateibasiertes App-Router-Routing mit Layouts und Loading-States. Astro hat ebenfalls dateibasiertes Routing, aber ohne das verschachtelte Layout-System. Für Content-Sites ist das einfacher, für komplexe App-Flows muss man umdenken.

Von S3 zu R2

R2 ist S3-kompatibel. In vielen Fällen reicht es, die Endpoint-URL und die Credentials zu tauschen. AWS SDK und s3cmd funktionieren mit R2 – die Migration ist oft ein Konfigurationswechsel, kein Code-Umbau.

Von Docker-Backend zu Rust Worker

Das ist der aufwändigste Schritt und nicht immer nötig. Wer ein Express- oder Fastify-Backend hat, kann es als TypeScript Worker deployen – ohne Rust. Die Workers-Plattform unterstützt JS/TS als First-Class-Citizen. Rust lohnt sich erst, wenn man CPU-intensive Logik hat oder die Typsicherheit und Performance-Garantien von Rust bewusst nutzen will.

Der pragmatische Pfad: Erst Astro auf Cloudflare deployen (Frontend). Dann schrittweise API-Endpunkte als Workers aufbauen (TS oder Rust). Zuletzt den alten Server abschalten.

Einordnung

Cloudflare + Astro + Rust ist kein Hype-Stack. Es ist die konsequente Kombination aus drei Technologien, die jeweils in ihrer Kategorie das Beste liefern: Astro für Content-Sites, Cloudflare für Edge-Runtime, Rust für performante Backend-Logik.

Was das Dreieck zusammenhält, ist nicht ein einzelnes Feature, sondern die Abwesenheit von Reibung. Dev und Production sind identisch. Frontend und Backend kommunizieren ohne Netzwerk. Deployment ist ein einzelner Befehl. Skalierung passiert automatisch. Kosten entstehen nur bei Nutzung.

Kein Docker. Kein Nginx. Kein Load Balancer. Kein Origin-Server. Für Content-getriebene Webprojekte mit API-Backend ist das aktuell die schlankeste Architektur, die ich kenne.