Cloudflare Workers haben sich 2026 zu einer der leistungsfaehigsten serverlosen Plattformen entwickelt.
Mit V8-Isolates statt Container-Starts, globalem Netzwerk in ueber 300 Rechenzentren und einer
vollstaendigen Datenschicht aus KV, D1, R2 und Durable Objects ist die Plattform weit mehr als
nur ein einfacher Proxy. Claude Code beschleunigt die Entwicklung dramatisch — von der
Worker-Initialisierung bis zum Produktions-Deployment in Minuten statt Stunden.
In diesem Leitfaden bauen wir Schritt fuer Schritt eine vollstaendige Edge-Anwendung auf
Cloudflare Workers — mit TypeScript, dem Hono-Framework, persistenten Daten in KV und D1,
Dateiablage in R2, zustandsbehafteten Verbindungen via Durable Objects und KI-Inferenz
ueber Workers AI und AI Gateway.
Voraussetzungen: Node.js 20+, ein kostenloses Cloudflare-Konto und Claude Code.
Wrangler (CLI) wird im ersten Abschnitt installiert. Alle Beispiele sind in TypeScript geschrieben
und laufen lokal via wrangler dev bevor sie auf die Edge deployed werden.
1. Workers Setup mit Wrangler & TypeScript
Der schnellste Einstieg in Cloudflare Workers laeuft ueber das offizielle Create-Script.
Es richtet Wrangler, TypeScript und die Projektstruktur automatisch ein:
bash
# Neues Workers-Projekt erstellen
npm create cloudflare@latest mein-worker
# Optionen im interaktiven Prompt:
# ? What type of application? -> "Hello World" Worker
# ? Do you want to use TypeScript? -> Yes
# ? Do you want to deploy immediately? -> No
cd mein-worker
npm install
Die generierte Projektstruktur enthaelt alles Noetige. Claude Code kann direkt in das
Verzeichnis navigieren und den Worker weiterentwickeln:
text
mein-worker/
├── src/
│ └── index.ts # Haupt-Worker-Entrypoint
├── wrangler.toml # Cloudflare-Konfiguration
├── tsconfig.json
└── package.json
Die wrangler.toml steuert alle Cloudflare-spezifischen Einstellungen —
Bindings fuer KV, D1, R2, Durable Objects und Umgebungsvariablen werden hier deklariert:
toml
name = "mein-worker"
main = "src/index.ts"
compatibility_date = "2026-01-01"
compatibility_flags = ["nodejs_compat"]
# KV Namespace
[[kv_namespaces]]
binding = "CACHE"
id = "abc123def456"
preview_id = "xyz789preview"
# D1 Datenbank
[[d1_databases]]
binding = "DB"
database_name = "meine-db"
database_id = "d1-uuid-hier"
# R2 Bucket
[[r2_buckets]]
binding = "STORAGE"
bucket_name = "mein-bucket"
# Umgebungsvariablen
[vars]
ENVIRONMENT = "production"
APP_VERSION = "2.0.0"
# Secrets via: wrangler secret put SECRET_KEY
Der minimale TypeScript-Entrypoint mit typisiertem Env-Interface.
Der fetch-Handler ist das Herzstuck jedes Workers — er empfaengt alle HTTP-Requests:
typescript
export interface Env {
CACHE: KVNamespace;
DB: D1Database;
STORAGE: R2Bucket;
ENVIRONMENT: string;
API_KEY: string;
}
export default {
async fetch(
request: Request,
env: Env,
ctx: ExecutionContext
): Promise<Response> {
const url = new URL(request.url);
if (url.pathname === '/health') {
return Response.json({
status: 'ok',
env: env.ENVIRONMENT,
timestamp: new Date().toISOString()
});
}
return new Response('Hello from the Edge!', {
headers: { 'Content-Type': 'text/plain; charset=utf-8' }
});
}
} satisfies ExportedHandler<Env>;
Lokale Entwicklung startet mit einem einzigen Befehl — Wrangler laedt automatisch alle Bindings:
bash
# Lokaler Dev-Server mit Hot-Reload
npx wrangler dev
# Mit Remote-Bindings (echter KV/D1 im Preview)
npx wrangler dev --remote
# Deployment in Produktion
npx wrangler deploy
# Logs aus dem Edge-Netzwerk streamen
npx wrangler tail
Tipp
Claude Code als Wrangler-Assistent
Frag Claude Code: "Erstelle einen Cloudflare Worker mit Hono, KV-Caching und D1 fuer User-Auth — inkl. vollstaendiger wrangler.toml."
Claude generiert die komplette Konfiguration, alle TypeScript-Types und Migrations-SQL in einem Schritt.
2. Hono auf Cloudflare Workers
Hono ist das de-facto Standard-Framework fuer Cloudflare Workers 2026.
Ultra-leichtgewichtig (<15 KB), vollstaendig typisiert und mit erstklassigem
Workers-Support. Das Routing und die Middleware-API erinnern an Express, laeuft aber
direkt in V8-Isolates ohne Node.js-Overhead:
bash
npm install hono
npm install --save-dev @hono/zod-validator zod
typescript
import { Hono } from 'hono'
import { cors } from 'hono/cors'
import { logger } from 'hono/logger'
import { prettyJSON } from 'hono/pretty-json'
import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'
type Bindings = {
CACHE: KVNamespace
DB: D1Database
API_KEY: string
}
const app = new Hono<{ Bindings: Bindings }>()
// Globale Middleware
app.use('*', logger())
app.use('*', prettyJSON())
app.use('/api/*', cors({
origin: ['https://agentic-movers.com', 'http://localhost:3000'],
allowMethods: ['GET', 'POST', 'PUT', 'DELETE'],
allowHeaders: ['Content-Type', 'Authorization'],
credentials: true
}))
typescript
// API-Key Middleware
const authMiddleware = async (c: Context, next: Next) => {
const key = c.req.header('X-API-Key')
if (key !== c.env.API_KEY) {
return c.json({ error: 'Unauthorized' }, 401)
}
await next()
}
// Zod-Schema fuer Request-Validation
const userSchema = z.object({
name: z.string().min(2).max(100),
email: z.string().email(),
plan: z.enum(['free', 'pro', 'enterprise']).default('free')
})
app.get('/', (c) => c.json({ message: 'SpockyMagicAI Edge API v2' }))
app.get('/api/users/:id', authMiddleware, async (c) => {
const id = c.req.param('id')
// Aus KV-Cache laden (schnell)
const cached = await c.env.CACHE.get(`user:${id}`, 'json')
if (cached) return c.json({ data: cached, source: 'cache' })
// Sonst aus D1 laden
const user = await c.env.DB
.prepare('SELECT * FROM users WHERE id = ? LIMIT 1')
.bind(id)
.first()
if (!user) return c.json({ error: 'User nicht gefunden' }, 404)
// In KV cachen (5 Minuten TTL)
await c.env.CACHE.put(`user:${id}`, JSON.stringify(user), {
expirationTtl: 300
})
return c.json({ data: user, source: 'database' })
})
app.post('/api/users', zValidator('json', userSchema), async (c) => {
const body = c.req.valid('json')
const id = crypto.randomUUID()
await c.env.DB
.prepare('INSERT INTO users (id, name, email, plan) VALUES (?, ?, ?, ?)')
.bind(id, body.name, body.email, body.plan)
.run()
return c.json({ id, ...body }, 201)
})
app.onError((err, c) => {
console.error(err)
return c.json({ error: 'Interner Fehler', details: err.message }, 500)
})
app.notFound((c) => c.json({ error: 'Route nicht gefunden' }, 404))
export default app
Hono
Hono-Features 2026
- RPC-Mode: Typsichere Client-Server-Kommunikation ohne Code-Generierung
- JSX-Support: Server-Side Rendering direkt im Worker
- Streaming: ReadableStream fuer Echtzeit-Responses
- Middleware-Oekosystem: Rate-Limiting, JWT, Bearer, Cache und mehr
Hono RPC — Typsicherer API-Client
typescript
// server: src/routes/api.ts
import { Hono } from 'hono'
const api = new Hono()
.get('/status', (c) => c.json({ online: true, ts: Date.now() }))
export type AppType = typeof api
// client: vollstaendig typisiert!
import { hc } from 'hono/client'
import type { AppType } from './server'
const client = hc<AppType>('https://mein-worker.example.workers.dev')
const res = await client.api.status.$get()
const data = await res.json() // { online: boolean, ts: number }
3. KV Storage & D1 SQLite
Cloudflare bietet zwei komplementaere Datenspeicher: KV fuer schnellen,
global replizierten Key-Value-Zugriff und D1 fuer relationale SQLite-Daten
mit vollstaendigem SQL-Support.
| Feature |
KV Storage |
D1 SQLite |
| Datenmodell |
Key-Value (Strings, Blobs, JSON) |
Relationale Tabellen (SQL) |
| Leslatenz |
<1ms (Edge-Cache) |
~1-5ms (Edge-Replica) |
| Schreiblatenz |
~60ms (eventual consistent) |
~10ms (strong consistent) |
| Max Wertgroesse |
25 MB |
Zeilen bis 1 MB |
| Abfragen |
Nur per Key |
Vollstaendiges SQL |
| Transaktionen |
Nein |
Ja (ACID) |
KV Storage — Lesen, Schreiben, Loeschen
typescript
// KV: Grundoperationen
async function kvBeispiele(kv: KVNamespace) {
// Schreiben (optional mit TTL)
await kv.put('session:abc', JSON.stringify({ userId: 'u1', role: 'admin' }), {
expirationTtl: 3600 // 1 Stunde
})
// Lesen als JSON (typisiert)
const session = await kv.get<{ userId: string; role: string }>('session:abc', 'json')
console.log(session?.role) // 'admin'
// Lesen als ArrayBuffer (fuer Binaerdaten)
const binary = await kv.get('image:thumb', 'arrayBuffer')
// Mit Metadaten lesen
const { value, metadata } = await kv.getWithMetadata<string, { createdAt: number }>('doc:1')
// Loeschen
await kv.delete('session:abc')
// Liste (max 1000 Keys)
const { keys } = await kv.list({ prefix: 'session:', limit: 100 })
for (const key of keys) {
console.log(key.name, key.expiration)
}
}
D1 — SQL-Abfragen und Migrations
bash
# D1 Datenbank erstellen
npx wrangler d1 create meine-db
# Migration erstellen
npx wrangler d1 migrations create meine-db create_users_table
# Migration ausfuehren (lokal)
npx wrangler d1 migrations apply meine-db --local
# Migration ausfuehren (Produktion)
npx wrangler d1 migrations apply meine-db --remote
sql
-- migrations/0001_create_users_table.sql
CREATE TABLE users (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL,
plan TEXT DEFAULT 'free' CHECK (plan IN ('free', 'pro', 'enterprise')),
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
updated_at INTEGER NOT NULL DEFAULT (unixepoch())
);
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_plan ON users(plan);
CREATE TABLE api_keys (
id TEXT PRIMARY KEY,
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
key_hash TEXT UNIQUE NOT NULL,
name TEXT NOT NULL,
last_used INTEGER,
created_at INTEGER NOT NULL DEFAULT (unixepoch())
);
typescript
// D1: Queries, Batch, Transaktionen
async function d1Beispiele(db: D1Database) {
// Einzelne Zeile
const user = await db
.prepare('SELECT * FROM users WHERE email = ?')
.bind('max@example.com')
.first<{ id: string; name: string; plan: string }>()
// Mehrere Zeilen
const { results } = await db
.prepare('SELECT id, name, email FROM users WHERE plan = ? ORDER BY created_at DESC LIMIT ?')
.bind('pro', 20)
.all<{ id: string; name: string; email: string }>()
// Batch-Queries (eine Round-Trip fuer mehrere Statements)
const [usersResult, statsResult] = await db.batch([
db.prepare('SELECT COUNT(*) as total FROM users'),
db.prepare('SELECT plan, COUNT(*) as count FROM users GROUP BY plan')
])
// Insert mit RETURNING
const newUser = await db
.prepare('INSERT INTO users (id, name, email) VALUES (?, ?, ?) RETURNING *')
.bind(crypto.randomUUID(), 'Anna Mueller', 'anna@example.com')
.first()
return { user, results, newUser }
}
Drizzle ORM auf D1
bash
npm install drizzle-orm
npm install --save-dev drizzle-kit
typescript
import { drizzle } from 'drizzle-orm/d1'
import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core'
import { eq, desc, sql } from 'drizzle-orm'
export const users = sqliteTable('users', {
id: text('id').primaryKey(),
name: text('name').notNull(),
email: text('email').unique().notNull(),
plan: text('plan', { enum: ['free', 'pro', 'enterprise'] }).default('free'),
createdAt: integer('created_at').default(sql`(unixepoch())`)
})
const db = drizzle(env.DB, { schema: { users } })
// Typsichere Query
const proUsers = await db.select()
.from(users)
.where(eq(users.plan, 'pro'))
.orderBy(desc(users.createdAt))
.limit(10)
KV
D1
Best Practice: KV als D1-Cache
Kombiniere beide Speicher: D1 fuer zuverlaessige Datenhaltung, KV als Edge-Cache.
Lies zuerst aus KV (Mikrosekunden), falle auf D1 zurueck, schreibe Ergebnis zurueck in KV mit TTL.
Cache-Invalidierung: Bei Writes in D1 sofort den KV-Key loeschen.
4. R2 Object Storage
Cloudflare R2 ist S3-kompatibel, hat aber einen entscheidenden Vorteil:
keine Egress-Gebuehren. Ideal fuer User-Uploads, generierte Bilder,
PDF-Reports oder statische Assets. Workers koennen als Proxy vor R2 schalten und
so Zugriffskontrolle, Caching und Transformationen ergaenzen.
bash
# R2 Bucket erstellen
npx wrangler r2 bucket create mein-bucket
# Lokale Entwicklung: R2 simulieren
npx wrangler dev --local
# Datei hochladen (fuer Tests)
npx wrangler r2 object put mein-bucket/test.txt --file ./test.txt
R2 Grundoperationen im Worker
typescript
async function r2Beispiele(storage: R2Bucket) {
// Upload: Text/JSON
await storage.put('reports/2026-05.json', JSON.stringify({ revenue: 42000 }), {
httpMetadata: { contentType: 'application/json' },
customMetadata: { generatedBy: 'billing-worker', version: '2' }
})
// Upload: Binary vom Request-Body
async function handleUpload(request: Request) {
const key = `uploads/${crypto.randomUUID()}`
await storage.put(key, request.body!, {
httpMetadata: {
contentType: request.headers.get('content-type') ?? 'application/octet-stream'
}
})
return { key, url: `/files/${key}` }
}
// Abrufen
const obj = await storage.get('reports/2026-05.json')
if (!obj) return null
// Als Response zurueckgeben (effizient)
return new Response(obj.body, {
headers: {
'Content-Type': obj.httpMetadata?.contentType ?? 'application/octet-stream',
'Cache-Control': 'public, max-age=86400',
'ETag': obj.etag
}
})
}
Worker als R2-Proxy mit Zugriffskontrolle
typescript
// Sicherer Datei-Download ueber Worker
app.get('/files/:key{.+}', authMiddleware, async (c) => {
const key = c.req.param('key')
// Conditional GET: ETag-Support
const ifNoneMatch = c.req.header('If-None-Match')
const obj = await c.env.STORAGE.get(key, {
onlyIf: ifNoneMatch ? { etagDoesNotMatch: ifNoneMatch } : undefined
})
if (obj === null) return c.json({ error: 'Datei nicht gefunden' }, 404)
if (!(obj instanceof R2ObjectBody)) {
return new Response(null, { status: 304 })
}
return new Response(obj.body, {
headers: {
'Content-Type': obj.httpMetadata?.contentType ?? 'application/octet-stream',
'Content-Length': String(obj.size),
'ETag': obj.etag,
'Cache-Control': 'private, max-age=3600'
}
})
})
// Multipart Upload fuer grosse Dateien (>5 MB)
app.post('/files/multipart-start', async (c) => {
const { filename, contentType } = await c.req.json()
const upload = await c.env.STORAGE.createMultipartUpload(
`uploads/${filename}`,
{ httpMetadata: { contentType } }
)
return c.json({ uploadId: upload.uploadId, key: upload.key })
})
R2
Presigned URLs ueber Workers
Da R2 keine nativen Presigned URLs wie S3 kennt, nutze Workers als signierende Middleware:
Generiere ein HMAC-Token mit Web Crypto API, validiere es im Worker vor dem R2-Zugriff.
Alternativ: R2 Public Bucket mit Custom Domain direkt auf den Bucket routen.
5. Durable Objects
Durable Objects sind das Geheimnis hinter zustandsbehafteten Edge-Anwendungen.
Jede DO-Instanz ist ein einzelner JavaScript-Prozess mit persistentem Speicher, der genau in
einem Rechenzentrum laeuft — garantiert. Perfekt fuer Echtzeit-Kollaboration, verteilte Locks,
WebSocket-Verbindungsmanagement und Rate-Limiting.
toml
# wrangler.toml
[[durable_objects.bindings]]
name = "COUNTER"
class_name = "CounterObject"
[[durable_objects.bindings]]
name = "ROOM"
class_name = "ChatRoom"
[[migrations]]
tag = "v1"
new_classes = ["CounterObject", "ChatRoom"]
Counter — Einfachstes Durable Object
typescript
export class CounterObject implements DurableObject {
private state: DurableObjectState
private count: number = 0
constructor(state: DurableObjectState, env: Env) {
this.state = state
this.state.blockConcurrencyWhile(async () => {
this.count = (await this.state.storage.get<number>('count')) ?? 0
})
}
async fetch(request: Request): Promise<Response> {
const url = new URL(request.url)
switch (url.pathname) {
case '/increment':
this.count++
await this.state.storage.put('count', this.count)
return Response.json({ count: this.count })
case '/decrement':
this.count = Math.max(0, this.count - 1)
await this.state.storage.put('count', this.count)
return Response.json({ count: this.count })
case '/value':
return Response.json({ count: this.count })
default:
return new Response('Not Found', { status: 404 })
}
}
}
WebSocket mit Hibernation API
Die WebSocket Hibernation API ist ein Game-Changer: Durable Objects
"schlafen", wenn keine Nachrichten aktiv sind — und wachen bei eingehenden Nachrichten auf.
Drastisch niedrigere Kosten bei WebSocket-intensiven Anwendungen:
typescript
export class ChatRoom implements DurableObject {
constructor(private state: DurableObjectState, private env: Env) {}
async fetch(request: Request): Promise<Response> {
if (request.headers.get('Upgrade') !== 'websocket') {
return new Response('WebSocket erwartet', { status: 426 })
}
const { 0: client, 1: server } = new WebSocketPair()
this.state.acceptWebSocket(server)
return new Response(null, { status: 101, webSocket: client })
}
// Aufgerufen wenn Nachricht ankommt (auch nach Hibernation)
async webSocketMessage(ws: WebSocket, message: string | ArrayBuffer) {
const data = typeof message === 'string' ? JSON.parse(message) : message
// Broadcast an alle verbundenen Clients in diesem Room
const sessions = this.state.getWebSockets()
for (const session of sessions) {
if (session !== ws) {
session.send(JSON.stringify({ ...data, relayed: true }))
}
}
}
async webSocketClose(ws: WebSocket, code: number, reason: string) {
console.log(`WebSocket geschlossen: ${code} ${reason}`)
}
}
// Im Haupt-Worker: Durable Object aufrufen
app.get('/chat/:roomId/ws', async (c) => {
const roomId = c.req.param('roomId')
const id = c.env.ROOM.idFromName(roomId)
const room = c.env.ROOM.get(id)
return room.fetch(c.req.raw)
})
DO
Durable Objects — Anwendungsfaelle
- Rate Limiting: Pro User/IP in einer DO-Instanz — kein externes Redis noetig
- Distributed Locks: Verhindert Race Conditions bei parallelen Writes
- Multiplayer: Echtzeit-Kollaboration (Figma-aehnlich) auf der Edge
- Queues: Persistente Job-Queues mit garantierter Reihenfolge
6. AI Gateway & Workers AI
Cloudflare bietet zwei KI-Dienste: Workers AI fuer Inferenz direkt im
Cloudflare-Netzwerk (Llama, Mistral, DALL-E-aehnliche Modelle) und AI Gateway
als Caching- und Rate-Limiting-Proxy vor externen APIs wie OpenAI, Anthropic oder Replicate.
AI Gateway: Einheitlicher Endpunkt fuer alle LLM-Anbieter. Cached identische
Anfragen, loggt Kosten und Usage, ermoeglicht Fallback zwischen Anbietern — ohne Codeaenderung.
Workers AI — On-Edge Inferenz
toml
# wrangler.toml: AI-Binding aktivieren
[ai]
binding = "AI"
typescript
interface Env { AI: Ai }
// Text-Generierung mit Llama auf der Edge
app.post('/api/generate', async (c) => {
const { prompt, system } = await c.req.json()
const response = await c.env.AI.run('@cf/meta/llama-3.1-8b-instruct', {
messages: [
{ role: 'system', content: system ?? 'Du bist ein hilfreicher KI-Assistent.' },
{ role: 'user', content: prompt }
],
max_tokens: 1024,
temperature: 0.7
})
return c.json({ text: response.response })
})
// Streaming-Response fuer Chat-UIs
app.post('/api/stream', async (c) => {
const { prompt } = await c.req.json()
const stream = await c.env.AI.run('@cf/meta/llama-3.1-8b-instruct', {
messages: [{ role: 'user', content: prompt }],
stream: true
})
return new Response(stream, {
headers: {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Transfer-Encoding': 'chunked'
}
})
})
// Embeddings fuer Semantic Search
app.post('/api/embed', async (c) => {
const { texts } = await c.req.json<{ texts: string[] }>()
const result = await c.env.AI.run('@cf/baai/bge-base-en-v1.5', {
text: texts
})
return c.json({ embeddings: result.data, shape: result.shape })
})
AI Gateway — Caching und Rate Limiting
typescript
// AI Gateway: Externer LLM ueber Cloudflare-Proxy mit Caching
const GATEWAY_URL = `https://gateway.ai.cloudflare.com/v1/${ACCOUNT_ID}/mein-gateway`
async function callClaude(prompt: string, apiKey: string) {
const response = await fetch(`${GATEWAY_URL}/anthropic/v1/messages`, {
method: 'POST',
headers: {
'x-api-key': apiKey,
'anthropic-version': '2023-06-01',
'content-type': 'application/json',
'cf-aig-cache-ttl': '3600',
'cf-aig-skip-cache': 'false'
},
body: JSON.stringify({
model: 'claude-opus-4-5',
max_tokens: 1024,
messages: [{ role: 'user', content: prompt }]
})
})
if (!response.ok) throw new Error(`Claude API Fehler: ${response.status}`)
return response.json()
}
// Multi-Provider Fallback ueber AI Gateway
async function callWithFallback(prompt: string) {
const providers = [
{ url: `${GATEWAY_URL}/anthropic/v1/messages`, model: 'claude-haiku-4-5' },
{ url: `${GATEWAY_URL}/openai/v1/chat/completions`, model: 'gpt-4o-mini' }
]
for (const provider of providers) {
try {
return await fetch(provider.url, { /* headers + body */ })
} catch (e) {
console.warn(`Provider ${provider.model} fehlgeschlagen, naechster...`)
}
}
throw new Error('Alle Provider fehlgeschlagen')
}
Deployment und Monitoring
bash
# Produktions-Deployment
npx wrangler deploy
# Custom Domain hinzufuegen
npx wrangler domains add api.meinedomain.de
# Logs in Echtzeit streamen
npx wrangler tail --format pretty
# Secret setzen (nie in wrangler.toml!)
npx wrangler secret put CLAUDE_API_KEY
# KV-Werte inspizieren
npx wrangler kv key list --binding CACHE --remote
npx wrangler kv key get "session:abc" --binding CACHE --remote
# D1 in Produktion abfragen
npx wrangler d1 execute meine-db --command "SELECT COUNT(*) FROM users" --remote
AI
Claude Code + Workers AI Workflow
Nutze Claude Code um deinen Worker-Code zu generieren, dann Workers AI im Worker selbst
fuer Nutzer-facing KI-Features. Claude Code schreibt den Code auf deinem Rechner,
Workers AI laeuft auf der Edge fuer deine Endnutzer — zwei Ebenen der KI-Automatisierung.
Achtung CPU-Limits: Cloudflare Workers haben ein CPU-Limit von
30ms pro Request im Free-Plan und 30s im Paid Plan. Lange LLM-Inferenz ueber Workers AI
kann dieses Limit ueberschreiten — nutze ctx.waitUntil() fuer Hintergrundarbeit
oder streame die Response direkt zum Client.
Vollstaendige Deployment-Checkliste
- wrangler.toml geprueft: Alle Bindings deklariert, korrekte compatibility_date
- TypeScript-Fehler behoben:
npx tsc --noEmit ohne Ausgabe
- Secrets gesetzt:
wrangler secret put fuer alle API-Keys
- D1-Migrations applied: Schema im Remote-Bereich aktuell
- Lokale Tests bestanden:
wrangler dev --local alle Routen OK
- Bundle-Groesse geprueft: Wrangler warnt bei >1 MB (Worker-Limit: 10 MB)
- Custom Domain konfiguriert: SSL-Zertifikat automatisch von Cloudflare
- Durable Object Migrations deklariert: Neue Klassen in
[[migrations]]
Pro-Tipp: Nutze wrangler dev --test-scheduled um Cron-Trigger
lokal zu testen. Cloudflare Workers unterstuetzen scheduled-Handler fuer regelmaessige
Hintergrundaufgaben — ideal fuer Cleanup-Jobs, Report-Generierung oder Cache-Warming.
Cloudflare Workers
TypeScript
Hono
Wrangler
KV Storage
D1 SQLite
R2
Durable Objects
AI Gateway
Edge Computing
Serverless
Claude Code
Mit Claude Code zur Edge-App in Minuten
Du hast gesehen wie viel Cloudflare Workers bieten. Mit Claude Code generierst du
Hono-Routen, D1-Schemas, R2-Handler und Durable Objects in Sekunden statt Stunden.
Teste es kostenlos — keine Kreditkarte, kein Setup.
Kostenlos ausprobieren →