The Laravel app stays the source of truth for forms, submissions, deliveries and the dashboard. The Worker would be an optional, thin, stateless layer in front of the public endpoints.
Why
- Bots and floods never wake Laravel. With scale-to-zero, every request wakes the app. A Worker can answer preflights, serve static assets and reject obvious junk at the edge.
- Speed for visitors.
embed.js,schema.jsonand hosted page assets served from the edge cache. - No lost submissions while Laravel scales up. Laravel Cloud scales up rather than dropping requests, so this is an extra, not a fix for a known gap.
Routes it would sit in front of
| Route | At the edge | Passed to Laravel |
|---|---|---|
OPTIONS /f/* |
Answered from a cached copy of the form’s allowed origins | No |
GET /embed.js |
Served from cache | Cache miss only |
GET /f/{form}/schema.json |
Served from cache (60 seconds), purged on publish | Cache miss only |
POST /f/{form} |
Rate limit per IP and form, honeypot check, Turnstile token present check, body size cap | Yes, with the original IP in a signed header |
POST /f/{form}/progress, /view |
Rate limit, body size cap | Yes |
POST /f/{form}/uploads |
Rate limit | Yes |
GET /f/{form} (hosted page) |
Cached HTML shell for published forms | Cache miss, or ?sandbox= and ?link= |
| Everything else (dashboard, API, MCP, docs) | Passed through untouched | Yes |
Optional buffer mode
The Worker would check the basics (size, rate limit, honeypot), put the raw request on a Cloudflare Queue and return 202 {"queued": true}, or the normal redirect for HTML posts. A queue consumer would post it to a new internal Laravel endpoint, which runs the normal submission path, retrying with backoff and sending anything that still fails to a dead letter queue.
The trade-off is that validation runs after the 202, so field errors can’t come back straight away. Buffer mode would be opt-in per form, or only kick in when Laravel is slow to answer.
What it must never do
- Store submissions or credentials.
- Make validation or delivery decisions. Schema rules, the spam filter, smart rules, double opt-in and destinations stay in Laravel.
- Trust client IPs it hasn’t seen itself. It would pass
CF-Connecting-IPto Laravel in a header Laravel only trusts with a shared secret.
What works today without it
Cloudflare Turnstile, R2 for file uploads (through the S3 disk) and Cloudflare in front for DNS and WAF.