docs / Limits
Limits
Every toolchain has a boundary. This page is the boundary written down: what the compiler refuses, what the platform cannot do, and what the verdict does not promise.
Refusals
These fail the build. Each one has a way out; none of them fails at request time in production.
| construct | why | the way out |
|---|---|---|
| Blade <x-…> components | they compile to a view runtime the edge does not carry | inline the partial, or a port |
| Queue::push(SomeJob::class) | nothing would consume the job at the edge; the binding carries JSON, not a PHP job | Cloudflare Queues with a consumer you write, or a D1 table a cron reads |
| Storage::disk('named') | each named disk needs its own bucket; R2 asks for a credit card | the default disk, or an explicit R2 binding |
| Cache::tags() | the D1 database store has no tags — Laravel throws there too | drop the tags |
| CORS config | the Access-Control-* headers would be missing | declare the routes in registry.json ignore |
| config('app.custom') | the runtime dump carries framework keys plus declared groups; without a declaration the edge would answer null where PHP answers a value | registry.json → "config": ["app"] (declare only public data) |
| a non-session auth driver (Auth::extend) | the registering closure is PHP the rung cannot run | a guard port |
| controller code outside the subset | the transpiler fails rather than mistranslate | ports/ handler, or move the logic to HTTP |
READINESS: DOES NOT RUN
the edge cannot serve this (1):
POST /queue/push dispatches a queued job, but the worker has no build-time cron trigger
-> declare the cron secret and a Cloudflare Queues consumer, or move the work to a
D1 table the schedule readsThe cause line is the compiler's own text; the block is printed after a failed build, with the route it belongs to on the left.
What the platform cannot do
| need | at the edge |
|---|---|
| image resizing (GD/Imagick) | no image library — Cloudflare Images, or resize at build time |
| processes (exec, proc_open, pcntl) | no OS process — an HTTP service from a port, or a cron-triggered job |
| WebSockets / broadcasting | a Durable Object or an external service; SSE or polling as the padanan |
| SMTP mail | impossible — the mailer is HTTP (Resend, or a provider you call) |
| Redis | KV or D1 drivers, or Upstash over REST |
| a local filesystem | no public_path/file_exists at runtime — build-time only; storage is the blob store or R2 |
The Free plan, which shapes everything
| resource | free plan | what it means |
|---|---|---|
| CPU per request | 10 ms | the compiled handler budget is p95 ≤ 5 ms; enforcement is softer than the docs (a per-isolate rollover bank) |
| requests | 100k / day | static assets do not count |
| subrequests | 50 / request | the reason eager loading and query counts matter |
| D1 writes / reads | 100k / 5M per day | cookie sessions write zero rows; throttle only where it is needed |
| objects | 1.5 MB / object | the D1 blob store, no card. R2 for bigger or many — and R2 asks for a card |
The verdict is about routes, not data
RUNS ON THE EDGE means every route has a compiled handler, a snapshot or a port; nothing is ignored by accident; no binding is missing. It does not mean your database is populated. deploy provisions D1 and applies the schema to an empty database; the rows are whoever wrote them.
It also does not mean a prerendered page reflects live data. A page that reads rows the build has never seen prerenders as it looks with an empty table — the honest consequence of rendering at build time. Run against real data after the schema apply, or decide such a route explicitly.
Known divergences
- Time: the compiled rung answers dates in UTC (the Workers timezone) while Laravel uses
config('app.timezone'). An app with a non-UTC timezone gets different dates at the edge — documented, not hidden. - Empty-database prerender: as above, snapshots are as-of-build.
- Local-only pages: 26 of the 105 Laravel documentation pages describe tooling that is not part of a deployed app (Artisan, Dusk, Sail, Telescope, Horizon dashboards). The coverage table names all of them.
Source: README.md §Fails loud, §What RUNS ON THE EDGE claims; COMPILED.md §Free-plan budget; docs/READINESS.md — repository ba1e9a5