Workers PHP

Laravel, running inside Cloudflare Workers.
PHP 8.5.2 in a V8 isolate, in every Cloudflare location.

Laravel v13.25.0 on PHP 8.5.2, rendered inside a V8 isolate

How Laravel maps to Cloudflare

Standard Laravel calls on the left. What actually runs them on the right.

Database

Eloquent works unchanged. Queries run on D1, where writes are serialized.

$chirp = Chirp::create(['message' => $text]);

Cache

The kv store reads from Workers KV at the edge. The do store runs on Durable Object shards for atomic counters and locks.

Cache::store('kv')->remember('stats', 60, fn () => ...);
Cache::store('do')->increment('clicks');

Files

Uploads store to R2. Downloads are served from the bucket without waking PHP. Try it: attach a photo to a chirp below.

$path = $request->file('photo')->store('photos', 'r2');

Queues

Jobs dispatch into Cloudflare Queues and run on a consumer, with native retries.

ProcessUpload::dispatch($chirp);

Realtime

Events broadcast through a Durable Object speaking the Pusher protocol. Stock Laravel Echo connects to it.

broadcast(new ChirpCreated($chirp));

Echo.channel('chirps').listen('.chirp.created', ...);

Scheduler

Closures and queued jobs run on Cron Triggers.

Schedule::call(fn () => ...)->everyFifteenMinutes();

Global counter

48
Laravel
Cache::store('do')->increment()
Cloudflare
one Durable Object shard holds this number
Guarantee
atomic. Every click from every tab lands exactly once, and every open tab updates live.
Observed
click to measure the round trip

Queue round trip

Laravel
dispatch(new DemoJob)
Path
request, Cloudflare Queue, consumer, WebSocket, this page
Guarantee
durable, at least once. About 2 seconds for the whole loop.
Observed
idle

Rate limiting

Laravel
throttle:5,1 middleware
Cloudflare
the counter behind it is a Durable Object shard
Guarantee
atomic across every isolate. Five requests a minute, then a real 429, no matter how the traffic spreads.
Observed
5 of 5 remaining this minute

KV cache and the scheduler

Laravel
Cache::store('kv')->remember(..., 60)
Value
computed 1 second ago by PHP 8.5.2, served from KV since
Scheduler
scheduled housekeeping ran 8 minutes ago via Schedule::call()

Live chirps

rows from D1, delivered by broadcast()

New posts appear without a refresh. Register and post one from another tab.

yer mom 15 minutes ago

:0

yer mom 15 minutes ago

yo

Zach 1 hour ago

PHP <3 V8

Under the hood

InterpreterPHP 8.5.2 compiled to wasm with JSPI and native wasm exceptions. Cold start is about 1 second.
Filesystemlazy zip-backed. The app is never extracted; files hydrate on first read.
Compile stepOPcache and Blade are pre-compiled at build time and shipped in the bundle.
Bindingsa single C function bridges PHP to KV, R2 and Durable Objects.
WebSocketsa Durable Object speaks the Pusher protocol, so stock Laravel Echo connects.

Workers PHP is a community project. It is not affiliated with or endorsed by Cloudflare or Laravel. Everything on this page, including the HTML itself, was produced by PHP running in a V8 isolate.