Jetzt abonnieren, um Benachrichtigungen über neue Beiträge zu erhalten:

Cloudflare Workflows ist jetzt allgemein verfügbar (GA): für eine dauerhafte Ausführung im Produktivbetrieb

2025-04-07

Lesezeit: 5 Min.

Betas sind nützlich für Feedback und Iteration, doch nicht jeder will als Versuchskaninchen herhalten oder verträgt die gelegentlichen Macken, die mit Beta-Software einhergehen. Manchmal braucht es einfach das schicke „Generally Available“-Label (oder den entsprechenden Blog-Post) – und jetzt ist Workflows an der Reihe.

Workflows, unsere Serverless Durable Execution Engine, mit der Sie lang laufende, mehrstufige Anwendungen (manche nennen sie auch „Schrittfunktionen“) auf Workers erstellen können, ist jetzt allgemein verfügbar.

Kurz gesagt, bedeutet dies, dass die Lösung produktionsreif ist – was aber nicht heißt, dass Workflows jetzt zum Fossil wird. Wir werden Workflows weiter skalieren (auch durch mehr gleichzeitige Instanzen), neue Funktionen hinzufügen (wie die neue waitForEvent-API) und die Erstellung von KI-Agents mit unserem Agents SDK und Workflows vereinfachen.

Wenn Sie lieber Code lesen als Fließtext, können Sie das Workflows-Starterprojekt schnell installieren und mit einem einzigen Befehl den Code und die API erkunden:

npm create cloudflare@latest workflows-starter -- 
--template="cloudflare/workflows-starter"

Wie funktioniert Workflows? Was kann ich damit entwickeln? Wie kann ich KI-Agents mit Workflows und dem Agents SDK erstellen? Lesen Sie weiter.

Entwickeln mit Workflows

Workflows ist eine Durable Execution Engine, die auf Cloudflare Workers basiert und die Erstellung von ausfallsicheren, mehrstufigen Apps ermöglicht.

Im Kern implementiert Workflows eine schrittbasierte Architektur, bei der jeder Schritt in Ihrer App unabhängig wiederholbar ist und der Status automatisch zwischen den Schritten beibehalten wird. Das bedeutet: Selbst wenn ein Schritt aufgrund eines vorübergehenden Fehlers oder eines Netzwerkproblems fehlschlägt, kann Workflows exakt diesen Schritt wiederholen, ohne dass Sie Ihre gesamte App neu starten müssen.

Mit der Definition eines Workflows unterteilen Sie Ihre Anwendung in logische Schritte.

  • Jeder Schritt kann entweder Code ausführen (step.do), Ihren Workflow in den Ruhezustand versetzen (step.sleep oder step.sleepUntil), oder auf ein Ereignis warten (step.waitForEvent).

  • Während Ihr Workflow ausgeführt wird, wird der von jedem Schritt zurückgegebene Status automatisch beibehalten, sodass Ihre App auch nach Fehlern oder Hibernation genau dort fortgesetzt werden kann, wo sie aufgehört hat. 

  • Dieses persistente Ausführungsmodell eignet sich besonders für Apps, die mehrere Systeme koordinieren, Daten nacheinander verarbeiten oder lang andauernde Aufgaben bewältigen müssen, die sich über Minuten, Stunden oder sogar Tage erstrecken können.

Workflows sind besonders nützlich bei der Abwicklung komplexer Geschäftsprozesse, mit denen herkömmliche zustandslose Funktionen Schwierigkeiten haben.

Ein Workflow zur Auftragsabwicklung im E-Commerce könnte beispielsweise den Lagerbestand überprüfen, eine Abbuchung vornehmen, eine E-Mail-Bestätigung senden und eine Datenbank aktualisieren – alles als separate Schritte. Wenn der Schritt der Zahlungsabwicklung aufgrund eines vorübergehenden Ausfalls fehlschlägt, wird Workflows diesen Schritt automatisch erneut versuchen, sobald der Zahlungsdienst wieder verfügbar ist, ohne die Lagerbestandsprüfung zu duplizieren oder den gesamten Prozess neu zu starten. 

Im Folgenden sehen Sie, wie dies funktioniert: Jeder Aufruf eines Dienstes kann als Schritt modelliert, unabhängig wiederholt und bei Bedarf ab diesem Schritt wiederhergestellt werden:

import { WorkflowEntrypoint, WorkflowStep, WorkflowEvent } from 'cloudflare:workers';

// The params we expect when triggering this Workflow
type OrderParams = {
	orderId: string;
	customerId: string;
	items: Array<{ productId: string; quantity: number }>;
	paymentMethod: {
		type: string;
		id: string;
	};
};

// Our Workflow definition
export class OrderProcessingWorkflow extends WorkflowEntrypoint<Env, OrderParams> {
	async run(event: WorkflowEvent<OrderParams>, step: WorkflowStep) {
		// Step 1: Check inventory
		const inventoryResult = await step.do('check-inventory', async () => {
			console.log(`Checking inventory for order ${event.payload.orderId}`);

			// Mock: In a real workflow, you'd query your inventory system
			const inventoryCheck = await this.env.INVENTORY_SERVICE.checkAvailability(event.payload.items);

			// Return inventory status as state for the next step
			return {
				inStock: true,
				reservationId: 'inv-123456',
				itemsChecked: event.payload.items.length,
			};
		});

		// Exit workflow if items aren't in stock
		if (!inventoryResult.inStock) {
			return { status: 'failed', reason: 'out-of-stock' };
		}

		// Step 2: Process payment
		// Configure specific retry logic for payment processing
		const paymentResult = await step.do(
			'process-payment',
			{
				retries: {
					limit: 3,
					delay: '30 seconds',
					backoff: 'exponential',
				},
				timeout: '2 minutes',
			},
			async () => {
				console.log(`Processing payment for order ${event.payload.orderId}`);

				// Mock: In a real workflow, you'd call your payment processor
				const paymentResponse = await this.env.PAYMENT_SERVICE.processPayment({
					customerId: event.payload.customerId,
					orderId: event.payload.orderId,
					amount: calculateTotal(event.payload.items),
					paymentMethodId: event.payload.paymentMethod.id,
				});

				// If payment failed, throw an error that will trigger retry logic
				if (paymentResponse.status !== 'success') {
					throw new Error(`Payment failed: ${paymentResponse.message}`);
				}

				// Return payment info as state for the next step
				return {
					transactionId: 'txn-789012',
					amount: 129.99,
					timestamp: new Date().toISOString(),
				};
			},
		);

		// Step 3: Send email confirmation
		await step.do('send-confirmation-email', async () => {
			console.log(`Sending confirmation email for order ${event.payload.orderId}`);
			console.log(`Including payment confirmation ${paymentResult.transactionId}`);
			return await this.env.EMAIL_SERVICE.sendOrderConfirmation({ ... })
		});

		// Step 4: Update database
		const dbResult = await step.do('update-database', async () => {
			console.log(`Updating database for order ${event.payload.orderId}`);
			await this.updateOrderStatus(...)

			return { dbUpdated: true };
		});

		// Return final workflow state
		return {
			orderId: event.payload.orderId,
			processedAt: new Date().toISOString(),
		};
	}
}

Diese Kombination aus Dauerhaftigkeit, automatischen Wiederholungsversuchen und Zustandspersistenz macht Workflows zur idealen Lösung für die Entwicklung zuverlässiger verteilter Apps, die reale Ausfälle problemlos bewältigen können.

Der Mensch in der Schleife

Workflows sind nur Code, und das macht sie extrem leistungsfähig: Als Entwickler können Sie Schritte dynamisch und spontan definieren, bedingte Verzweigungen vornehmen und API-Aufrufe an jedes beliebige System senden. Manchmal muss ein Workflow aber auch warten, bis in der realen Welt etwas passiert.

Zum Beispiel:

  • Eine Genehmigung durch einen Menschen, um fortzufahren.

  • Ein eingehender Webhook, z. B. von einer Stripe-Zahlung oder einem GitHub-Event.

  • Eine Zustandsänderung, z. B. das Hochladen einer Datei zu R2, die eine Ereignisbenachrichtigung auslöst und dann einen Verweis auf die Datei an den Workflow weitergibt, damit er die Datei verarbeiten oder durch ein KI-Modell laufen lassen kann.

Die neue waitForEvent-API in Workflows ermöglicht Ihnen genau das: 

let event = await step.waitForEvent<IncomingStripeWebhook>("receive invoice paid webhook from Stripe", { type: "stripe-webhook", timeout: "1 hour" }) 

Sie können dann von jedem externen Dienst, der eine HTTP-Anfrage stellen kann, ein Ereignis an eine bestimmte Instanz senden:

curl -d '{"transaction":"complete","id":"1234-6789"}' \
  -H "Authorization: Bearer ${CF_TOKEN}" \
\ "https://api.cloudflare.com/client/v4/accounts/{account_id}/workflows/{workflow_name}/instances/{instance_id}/events/{event_type}"

… oder über die Workers API innerhalb eines Workers selbst:

interface Env {
  MY_WORKFLOW: Workflow;
}

interface Payload {
  transaction: string;
  id: string;
}

export default {
  async fetch(req: Request, env: Env) {
    const instanceId = new URL(req.url).searchParams.get("instanceId")
    const webhookPayload = await req.json<Payload>()

    let instance = await env.MY_WORKFLOW.get(instanceId);
    // Send our event, with `type` matching the event type defined in
    // our step.waitForEvent call
    await instance.sendEvent({type: "stripe-webhook", payload: webhookPayload})
    
    return Response.json({
      status: await instance.status(),
    });
  },
};

Sie können sogar auf mehrere Ereignisse warten, indem Sie den Parameter type verwenden, und/oder mehrere Ereignisse starten, indem Sie Promise.race nutzen, um fortzufahren – je nachdem, welches Ereignis zuerst empfangen wurde:

export class MyWorkflow extends WorkflowEntrypoint<Env, Params> {
	async run(event: WorkflowEvent<Params>, step: WorkflowStep) {
		let state = await step.do("get some data", () => { /* step call here */ })
		// Race the events, resolving the Promise based on which event
// we receive first
		let value = Promise.race([
step.waitForEvent("payment success", { type: "payment-success-webhook", timeout: "4 hours" ),
step.waitForEvent("payment failure", { type: "payment-failure-webhook", timeout: "4 hours" ),
])
// Continue on based on the value and event received
	}
}

Um waitForEvent etwas detaillierter zu veranschaulichen, nehmen wir an, dass wir einen Workflow haben, der von einem Code Review Agent ausgelöst wird, der ein GitHub-Repository überwacht.

Ohne die Möglichkeit, auf Ereignisse zu warten, kann unser Workflow nicht einfach die Genehmigung von Menschen erhalten, Vorschläge zurückzuschreiben (oder sogar einen eigenen PR einzureichen). Er könnte möglicherweise einen Status abfragen, der aktualisiert wurde, aber das bedeutet, dass wir step.sleep für beliebige Zeiträume aufrufen, einen Speicherdienst für einen aktualisierten Wert abfragen und den Vorgang wiederholen müssen, wenn er nicht vorhanden ist. Das ist eine Menge Code und Raum für Fehler:

Ohne waitForEvent ist es schwieriger, Daten an eine laufende Workflow-Instanz zu senden

Würde man dasselbe Beispiel modifizieren und die neue waitForEvent-API einbinden, könnte man damit auf die Genehmigung des Menschen warten, bevor man eine mutierende Änderung vornimmt: 

Hinzufügen von waitForEvent zu unserem Code-Review-Workflow, damit es um explizite Genehmigung bitten kann.

Man könnte sich sogar vorstellen, dass ein KI-Agent hier selbst stellvertretend für einen Menschen sendet und/oder handelt. waitForEvent bietet einfach eine Möglichkeit für einen Workflow, etwas von Außen abzurufen und anzuhalten, um es zu ändern, bevor es fortgesetzt wird (oder nicht).

Entscheidend ist, dass Sie waitForEvent wie jeden anderen Schritt in Workflows aufrufen können. Sie können ihn bedingt und/oder mehrmals und/oder in einer Schleife aufrufen. Workflows sind nur Workers. Sie haben die volle Leistungsfähigkeit einer Programmiersprache und sind nicht durch eine domainspezifische Sprache (DSL) oder Konfigurationssprache eingeschränkt.

Preise

Gute Nachrichten: Wir haben seit unserer ursprünglichen Beta-Ankündigung nicht viel verändert! Wir fügen Speicherpreise für den von Ihren Workflows gespeicherten Status hinzu und behalten unsere CPU-basierten und Anfrage-basierten (Aufrufe) Preise wie folgt bei:

Einheit

Free-Tarif für Workers

Kostenpflichtige Workers-Version

CPU-Zeit (ms)

10 ms pro Workflow

30 Millionen CPU-Millisekunden pro Monat inbegriffen

+0,02 $ pro zusätzliche Million CPU-Millisekunden

Anfragen

100.000 Workflow-Aufrufe pro Tag (geteilt mit Workers)

10 Mio. pro Monat inbegriffen

+0,30 $ pro zusätzlicher Million

Speicherplatz (GB)

1 GB

1 GB pro Monat inbegriffen + 0,20 $/ GB-Monat

Da die Preisgestaltung für Speicherplatz neu ist, werden wir den Speicherplatz erst ab dem 15. September 2025 aktiv in Rechnung stellen. Wir benachrichtigen Nutzer, die das enthaltene 1-GB-Limit überschreiten, bevor der Speicherplatz in Rechnung gestellt wird, und standardmäßig laufen Workflows im gespeicherten Zustand nach drei (3) Tagen (Free-Tarif) oder dreißig (30) Tagen (kostenpflichtiger Tarif) ab.

Falls Sie sich fragen, was „CPU-Zeit“ ist: Die Zeit, in der Ihr Workflow aktiv Rechenressourcen verbraucht. Nicht enthalten ist die Zeit, die für API-Aufrufe, LLMs oder andere E/A-Vorgänge (z. B. Schreibvorgänge in einer Datenbank) aufgewendet wird. Das hört sich vielleicht nach einer Kleinigkeit an, aber in der Praxis summiert sich das. Die meisten Apps haben eine CPU-Zeit im einstelligen Millisekundenbereich und eine Echtzeit von mehreren Sekunden: Wenn eine oder zwei APIs 100–250 ms für die Antwort benötigen, summiert sich das!

Rechnen Sie nach CPU, nicht nach Zeit, die ein Workflow im Leerlauf oder im Wartezustand verbringt.

Insbesondere Workflow-Engines verbringen viel Zeit mit Warten: Lesen von Daten aus Objektspeichern (wie Cloudflare R2), Aufrufen von Drittanbieter-APIs oder LLMs wie o3-mini oder Claude 3.7, sogar Abfragen von Datenbanken wie D1, Postgres oder MySQL. Bei Workflows gilt dasselbe wie bei Workers: Sie zahlen nicht für die Zeit, in der Ihre App nur wartet.

Jetzt entwickeln

Sie haben Workflows und ihre Funktionsweise gut im Griff und wollen mit der Entwicklung beginnen. Wie geht es weiter?

  1. Besuchen Sie die Workflows-Dokumentation, um ihre Funktionsweise zu entdecken, die Workflows-API zu verstehen und Best Practices zu erfahren

  2. Sehen Sie sich den Code im Starterprojekt an

  3. Und zu guter Letzt können Sie den Starter mit ein paar Klicks in Ihrem eigenen Cloudflare-Konto implementieren:

Bereitstellen über Cloudflare

Wir schützen komplette Firmennetzwerke, helfen Kunden dabei, Internetanwendungen effizient zu erstellen, jede Website oder Internetanwendung zu beschleunigen, DDoS-Angriffe abzuwehren, Hacker in Schach zu halten, und unterstützen Sie bei Ihrer Umstellung auf Zero Trust.

Greifen Sie von einem beliebigen Gerät auf 1.1.1.1 zu und nutzen Sie unsere kostenlose App, die Ihr Internet schneller und sicherer macht.

Wenn Sie mehr über unsere Mission, das Internet besser zu machen, erfahren möchten, beginnen Sie hier. Sie möchten sich beruflich neu orientieren? Dann werfen Sie doch einen Blick auf unsere offenen Stellen.
Developer WeekCloudflare WorkersWorkflowsEntwicklerplattform

Folgen auf X

Sid Chatterjee|@chatsidhartha
Matt Silverlock|@elithrar
Cloudflare|@cloudflare

Verwandte Beiträge