Limits

Cloudflare ceilings you should keep in your head.

Last updated:

Lunora's design choices are driven by Cloudflare's per-primitive limits. Knowing these numbers helps you predict when to opt into .shardBy() or .global().

Durable Objects

LimitValueImplication
SQLite size / DO10 GBPlan to shard before you cross 1 GB
Sustained req/s / DO~1 000Hot DO = sharding signal
CPU per request30 sLong tasks → action + scheduler, not mutation
WebSockets / DO~32 000Hibernated, this is generous; pre-hibernate, less so
DOs / accountUnlimitedSharding is free of administrative overhead
Storage tx128 KB / opBatch large writes via ctx.db.insertMany

D1

LimitValueImplication
Database size10 GBUse for global indexes, not bulk data
Databases / account50 000 (1 TB total Paid)Each app gets its own
Queries per Worker invocation1 000Watch your query fan-out in fan-out reads
Bookmark window~24 hSessions API consistency window

R2

LimitValueImplication
Object size5 TBPractically unlimited
EgressFreeCritical — design around direct downloads
Class A opsmeteredBulk-list judiciously

Workers

LimitValueImplication
Bundle size10 MBLazy-load big deps; avoid bundling unused providers
CPU per request30 sSame envelope as DO
Subrequests50 (Free) / 1000 (Paid)Fan-out reads are a Paid-plan optimisation
Env var size5 KB totalUse D1 or KV for config above that

Containers

Requires the Workers Paid plan. Images must be linux/amd64.

LimitValueImplication
Instance typeslitestandard-4Or custom up to 4 vCPU / 12 GiB / 20 GB disk
DiskephemeralPersist to R2 (@lunora/storage), not local disk
Concurrent / account1 500 vCPU / 6 TiB mem / 30 TB diskRaisable via support
Registry storage50 GB / accountPrune old images with lunora containers images delete
Autoscalingnone yetFixed pools; .any() picks uniformly

Billing is active-CPU based: instances scale to zero on sleepAfter and cost nothing idle. Egress is billed (~$0.025/GB NA+EU, more elsewhere), unlike R2, which is free. See the Containers pricing docs.

When Lunora warns you

The runtime emits warnings (and the dev overlay shows a banner) when:

  • the __root__ DO crosses 1 GB of SQLite
  • a single DO is sustaining >700 req/s
  • a fan-out query touches more than 100 shards in one invocation

These warnings fire well below the hard ceiling, so you have time to react.

See also