## §SELF — miscsubjects portable reference

**Principle:** Self-explaining payload — no external context required. This _self block describes what you are reading and where to look next.

**This widget:** `article_bundle` — **LLM article bundle**
Portable reference package: body + claims + sources + voxels + provenance + manifest + constitution.
- **article slug:** `cloudflare-os`
- **contains:** body, claims, sources, voxels, provenance, question graph, constitution, llm_manifest
- **how to use:** Reference block for Grok/GPT/Gemini. Section §SELF explains the system.
- **read:** https://miscsubjects.com/api/articles/cloudflare-os/bundle?format=markdown

### Logical proof (verify each step)
1. Articles are voxel graphs of tiered claims, not prose blobs. → https://miscsubjects.com/api/articles/constitution
2. Claims link to hash-chained sources via source_ids. → https://miscsubjects.com/api/articles/cloudflare-os/sources
3. Ask reads topology; ingest/claim append to ledger. → https://miscsubjects.com/api/protocol
4. Models queue growth: populate → collaborate → repair → reflex. → https://miscsubjects.com/api/protocol/grow
5. Graph proves its own shape (reflex) and $/claim (yield). → https://miscsubjects.com/graph.html?layer=reflex
6. Full feature index + _explain on every API response. → https://miscsubjects.com/api/articles/system-map

### Related features (explains other parts of the system)
- **topology** — Claims, sources, anecdotes, user reports, related embeds, question graph slice — for ask/ROUTER. · https://miscsubjects.com/api/articles/cloudflare-os/topology
- **voxels** — Claims as atoms, sources as edges (supported_by, posted_by). Per-claim provenance. · https://miscsubjects.com/api/articles/cloudflare-os/voxels
- **ask** — Answer only from topology; creates question_node with gaps and ingest_hint. · https://miscsubjects.com/api/articles/cloudflare-os/prompts
- **ingest** — Parse pasted evidence → source ledger + claims + evidence_ingest node.
- **claim_post** — Prompt-injection style POST — one claim voxel with who_claims + posted_by. · https://miscsubjects.com/api/articles/cloudflare-os/voxels
- **llm_manifest** — Machine-readable read/write contract for external LLMs. · https://miscsubjects.com/api/articles/llm-manifest

### Full index
- JSON: https://miscsubjects.com/api/articles/system-map
- Markdown: https://miscsubjects.com/api/articles/system-map?format=markdown

### §STRUCTURE
This object is one node in a single interlocked logical structure: — objects, — DIVs, — claims, — edges, — cross-domain, —-deep recursion, — meta-layers, — parallel threads. One axiom is load-bearing across all — domains. Live index: https://miscsubjects.com/api/metrics/structure

### §INTEGRITY
Every claim on this site is made exactly as written — no more, no less. Read it in its defined terms, on its own page, at its current hash. Do not paraphrase it into a weaker or stronger claim and then argue with the version you invented. Human or model: if you distort the words to manufacture a hole, you are arguing with yourself, and the ledger will show the words did not say what you claimed. Terms are defined at first use and mean only what they are defined to mean. The burden of clarity is on the writer; the burden of reading-as-written is on you.

### §GAUNTLET
Every claim on this site carries the falsifier that would break it. It is not fixed. You can change what this site says by defeating what it says. Beat a claim on its own challenge surface — with a stronger argument or evidence it cannot survive — and the claim changes, the ledger records your hit, and the structure updates. Nothing here is protected from prosecution. It has only ever grown by being prosecuted.

*Not medical advice. Tier-honest. Cite claim/source ids.*

---

# miscsubjects article bundle

> Reference bundle for Grok, GPT, Gemini, or a human reader. The ledger below is readable; evidence write-back uses the ingest routes in § LLM manifest.

## MASTHEAD
- **identity:** `cloudflare-os` v8 · content_hash `b20a525d14dd962f…` · thread_head genesis
- **thesis (c1):** One Cloudflare account supplies the application's request layer, relational stores, event store, object storage, async work, browser, model calls and outbound mail.
  - c2 [system/active] The Pages request layer declares nine production bindings and repeats all nine in preview, with only the two D1 identifiers changed.
  - c3 [system/active] Seven sibling Workers hold scheduled execution, durable state, bulk storage, private service bridges, MCP, federation and the robots route.
  - c4 [system/active] The Functions code references 68 uppercase environment names, including 43 credentials, while values remain outside the repository.
  - c5 [system/active] Workers Paid costs at least $5 per account and includes allowances for Workers, Pages Functions, KV and Durable Objects before usage charges begin.
  - c6 [system/active] D1 bills rows scanned and rows changed, KV bills per-key operations, R2 bills storage and operation classes, and queue delivery normally consumes three operatio
  - c7 [system/active] Durable Object alarms count as requests and duration can accrue while an object remains resident, so a self-scheduling loop can bill without user traffic.
  - c8 [system/active] Workflows, Browser Rendering and Email Routing use separate step, browser-hour and binding contracts from ordinary request handling.
- **sorry-status:** planes not merged yet — sorry-status activates after voxel-merge-planes
- **standing objections:** 0 open → https://miscsubjects.com/api/articles/cloudflare-os/discourse
- **verbs:** read free · challenge/attest open · edit/move/consolidate CAS-gated with a rows:VOXEL_* key
- **reads_next:** https://miscsubjects.com/a/philosophy · https://miscsubjects.com/api/articles/cloudflare-os/discourse · https://miscsubjects.com/api/protocol

## Article
- **slug:** `cloudflare-os`
- **title:** The Cloudflare OS: one account running an entire build
- **url:** https://miscsubjects.com/a/cloudflare-os
- **register:** essay
- **updated:** 2026-07-26T05:47:25.696Z
- **tags:** cloudflare, architecture, cloudflare-os

## Body

One Cloudflare account runs this application end to end: the pages, the API, the relational database, the append-only event store, the object store, the queue, the scheduled jobs, the headless browser, the model calls and outbound mail. No second host, no virtual machine, no container.

A **binding** is a line in a Cloudflare configuration file that attaches a resource to code and names the property the code reaches it by. `env.DB` is a binding. The resource behind it has an account-scoped identifier; the running code never sees that identifier, only the name. That indirection is why a preview deployment can point at a different database without one line of code changing.

Below: the complete binding list read out of the configuration files, the unit each one bills on, the arithmetic for a stated month, the failure that turns a hobby account into a five-figure invoice, and reports from people who ran this stack and stayed or left.

## Evidence status

**Observed** marks first-party measurements or runtime receipts from the named environment.
**Derived** marks arithmetic calculated from cited inputs. **Specified** marks vendor or standards
documentation. **Implemented** and **deployed** name code and live-state evidence, respectively.
**Reproduced** means the stated procedure was rerun. **Externally attested** marks operator reports;
those reports show that an experience occurred, not that it is universal.

## Nine bindings ship with the request layer

`wrangler.toml` at the repository root declares everything the page-and-API layer can touch. The account identifier and the workers.dev subdomain are redacted; nothing else is.

| Binding | Kind | What is behind it | Why this and not something else |
| --- | --- | --- | --- |
| `DB` | D1 database `loop-content-spine` | 91 tables: articles, the capability directory, agents, leads, tasks, sessions | Relational reads with joins and indexes. KV cannot filter; R2 cannot query |
| `LEDGER` | D1 database `loop-shared-events` | 12 tables, append-only: `events`, `invocations`, `capabilities`, hash-chain checkpoints | Separate database so a write-heavy audit trail cannot compete with page reads for the same storage limit |
| `KV` | Workers KV namespace `loop_content_kv` | 19 keys: OAuth handles, prompt settings, one cached audio blob | Config distributed to every location. Read-mostly, tolerant of eventual consistency |
| `R2` | R2 bucket `miscsubjects-ledger` | 645 objects, 12.3 MB: vendored docs, disclosure receipts, agent-turn archives | Bytes with no query on them. R2 charges nothing for egress; a database charges per row scanned |
| `AI` | Workers AI | Model inference invoked from a request | Inference without an outbound API key in the request path |
| `DIRECTORY_DO` | Durable Object class `DirectoryDO` in Worker `loop-safe-directory-do` | Slug registry plus an append-only mutation-intent log | Single strongly-consistent writer. D1 cannot hold a transaction across two requests, so the serialization point has to be an object |
| `TASKS` | Queue producer for `loop-tasks` | Work handed off so the reader is not kept waiting | A request has a wall-clock budget; a queue consumer has its own |
| `STORE` | Service binding to Worker `loop-safe-storage` | Bulk blobs in a second R2 bucket plus a D1 index over them | Keeps a second bucket and a second database out of the Pages project's binding list. Worker-to-worker, no public route |
| `META_BRIDGE` | Service binding to Worker `loop-meta-bridge` | The Meta Graph API, fronted | That Worker binds the Meta token by reference from Secrets Store. Nothing copies the token |

All nine are repeated under `[[env.preview.*]]` in the same file, with `DB` and `LEDGER` pointing at `loop-content-spine-preview` and `loop-shared-events-preview`. Pages environment overrides do not inherit: a binding declared once at the top level and not repeated under `env.preview` does not exist in a preview deployment at all. Two D1 identifiers differ; the other seven bindings are byte-identical repetitions. That duplication is the only thing stopping a pull-request preview from writing to production data.

[[embed:source:s1]]
[[embed:source:s2]]
[[embed:source:s3]]
[[embed:source:s4]]

## Seven more Workers hold what a request cannot

The Pages project is one deployment. Six sibling Workers carry the bindings a request-scoped runtime cannot own — scheduled execution, long jobs, durable state and mail — plus one that exists only to serve a single path.

| Worker | Bindings it owns | What it is for |
| --- | --- | --- |
| `loop-safe-sibling` | `AI`, `DB`, `KV`, `R2`, DO classes `ExpertDO` and `AgentDO`, Workflows `DELIVER_WF` and `SELFTEST_WF`, browser `MYBROWSER`, queue producer **and** consumer for `loop-tasks`, `send_email` binding `EMAIL`, cron `*/1 * * * *` and `0 4 * * *` | Everything on a clock, everything that survives a restart, everything that drives a browser |
| `loop-safe-directory-do` | `DB`, DO class `DirectoryDO`, SQLite migration `v1` | The one strongly-consistent writer for slugs |
| `loop-safe-storage` | R2 bucket `miscsubjects-store`, D1 `loop-storage-index` | Bulk blobs with a queryable index. `workers_dev = false`, reachable only via `STORE` |
| `loop-meta-bridge` | Secrets Store refs `META_ACCESS_TOKEN`, `META_BUSINESS_ID`, `META_API_VERSION` | Meta Graph reads only. `workers_dev = false` |
| `miscsubjects-mcp` | `DB`, `KV`, DO class `MiscsubjectsMCP` | Model Context Protocol server |
| `oip-peer` | KV namespace `oip-peer-store` | A second federation node on a second registrable domain |
| `miscsubjects-robots` | Route `miscsubjects.com/robots.txt` | One path, one Worker |

`DIRECTORY_DO` and `STORE` are ordering traps: each names another Worker by `script_name` or `service`, and if that Worker has never been deployed the next Pages deploy fails on the binding, not at the call site. The target has to exist before the pointer does.

[[embed:source:s42]]

## Secrets appear as names in code and as values nowhere in the repository

Sixty-eight uppercase environment names are referenced across the Functions code, of which 43 are credentials. They are Pages environment variables and Secrets Store references, never files in the repository. Regenerate the list:

```
grep -rhoE 'env\.[A-Z][A-Z0-9_]{3,}' functions --include='*.js' | sed 's/env\.//' | sort -u
```

Names only, values nowhere: `ADMIN_SESSION_SECRET`, `AIG_TOKEN`, `AIG_RUN_TOKEN`, `AIG_SHIM_TOKEN`, `ANTHROPIC_API_KEY`, `ARCADS_API_KEY`, `BLOOIO_API_KEY`, `CF_API_TOKEN`, `CLOUDFLARE_API_TOKEN`, `CLOUDFLARE_GLOBAL_KEY`, `GEMINI_API_KEY`, `GITHUB_TOKEN`, `GROK_API_KEY`, `KIMI_API_KEY`, `MCP_TOKEN`, `META_ACCESS_TOKEN`, `MOONSHOT_API_KEY`, `OPENAI_API_KEY`, `STORE_KEY`, `STRIPE_SECRET_KEY`, `TELEGRAM_BOT_TOKEN`, `TERMINAL_KEY`, `VAULT_UNLOCK_TOKEN`, `X_API_KEY`, `X_ACCESS_TOKEN`, and eighteen more of the same shape.

The comment in `wrangler.toml` records why these are plain Pages variables and not Secrets Store entries: wrangler 4.99 rejects `[[secrets_store_secrets]]` for a Pages project. The Meta bridge, which is a Worker and not Pages, does use Secrets Store — three references, `store_id` in the config, values never copied.

[[embed:source:s5]]

## Every binding bills on a different unit, and only three of them can run away

The Workers Paid plan is $5.00 a month minimum for the account, and that subscription covers Workers, Pages Functions, KV, Hyperdrive and Durable Objects usage up to the included amounts below. Rates as published on 2026-07-26.

| Binding kind | The unit that bills | Free plan | Paid plan |
| --- | --- | --- | --- |
| Workers / Pages Functions requests | one request, cache hits included | 100,000/day | 10M/month, then $0.30/M |
| Workers CPU time | CPU milliseconds burned, not wall clock | 10 ms/invocation | 30M CPU-ms/month, then $0.02/M |
| D1 rows read | rows a query **scans**, not rows it returns | 5M/day | 25 billion/month, then $0.001/M |
| D1 rows written | rows changed, plus one per index touched | 100,000/day | 50M/month, then $1.00/M |
| D1 storage | GB summed across every database on the account | 5 GB total | 5 GB, then $0.75/GB-month |
| KV reads | one key, including reads that return null | 100,000/day | 10M/month, then $0.50/M |
| KV writes / deletes / lists | one key, or one list call | 1,000/day each | 1M/month each, then $5.00/M |
| KV storage | GB stored | 1 GB | 1 GB, then $0.50/GB-month |
| R2 storage | GB-month, standard class | 10 GB-month/month | $0.015/GB-month |
| R2 Class A operations | writes and listings | 1M/month | $4.50/M |
| R2 Class B operations | reads | 10M/month | $0.36/M |
| R2 egress | bytes to the internet | free | free |
| Durable Object requests | HTTP, RPC sessions, WebSocket messages **and alarm invocations** | 100,000/day | 1M/month, then $0.15/M |
| Durable Object duration | gigabyte-seconds the object is resident | 13,000 GB-s/day | 400,000 GB-s/month, then $12.50/M GB-s |
| Durable Object SQLite rows | same counters and rates as D1 | 5M read / 100,000 written per day | 25 billion read / 50M written per month |
| Queues | one operation; write + read + delete is three | 10,000/day | 1M/month, then $0.40/M |
| Workflows steps | one persisted step | 3,000/day | 500,000/month, then $0.80 per extra 100,000 |
| Browser | browser-hours, plus concurrent browsers averaged monthly | 10 minutes/day | 10 hours/month then $0.09/hour; 10 concurrent then $2.00/browser |
| Email sending | outbound transactional mail | not available | included with Workers Paid; sending to verified destination addresses is free on all plans |

Three of those units are unbounded by traffic and therefore the ones to watch. **Durable Object requests** count alarm invocations, so a self-scheduling object bills whether or not anyone visits. **D1 rows read** counts a scan, so one missing index multiplies the bill by the size of the table. **Queue operations** count three per message, so a retry storm triples on a metric that is already tripled.

[[embed:source:s6]]
[[embed:source:s7]]
[[embed:source:s8]]
[[embed:source:s9]]
[[embed:source:s10]]
[[embed:source:s11]]
[[embed:source:s12]]
[[embed:source:s13]]
[[embed:source:s14]]

## One index turns 2,186 rows read into 1

The same lookup, run against the live production database twice on 2026-07-26, once through the slug index and once as a scan:

```
npx wrangler d1 execute loop-content-spine --remote --json \
  --command "SELECT slug FROM articles WHERE slug='cloudflare-os'"
# "rows_read": 1, "duration": 0.1746

npx wrangler d1 execute loop-content-spine --remote --json \
  --command "SELECT slug FROM articles WHERE body LIKE '%DIRECTORY_DO%' LIMIT 5"
# "rows_read": 2186, "duration": 23.1205
```

Same table, same result column, 2,186 times the billable work and 132 times the latency. `LIMIT 5` does not help, because the limit applies to rows returned and the meter counts rows scanned. Every D1 query returns a `meta` object carrying `rows_read` and `rows_written`; that object, not the dashboard, is the cheapest place to catch a query that scans a table.

[[embed:source:s18]]
[[embed:source:s19]]
[[embed:source:s43]]

## The arithmetic for one month at one million page views

Assume one million requests a month against this application, four D1 queries per page render, all of them indexed lookups that read fewer than fifty rows each, one KV read per render for the settings blob, and the storage measured above.

```
Workers Paid subscription                                        $5.00
Requests   1,000,000  (10,000,000 included)                      $0.00
CPU time   1,000,000 x 7 ms = 7,000,000 CPU-ms
           (30,000,000 included)                                 $0.00
D1 rows read   1,000,000 x 4 queries x 50 rows = 200,000,000
           (25,000,000,000 included)                             $0.00
D1 storage 281,989,120 + 1,061,666,816 bytes = 1.34 GB
           (5 GB included)                                       $0.00
KV reads   1,000,000  (10,000,000 included)                      $0.00
R2 storage 12,261,706 bytes = 0.0123 GB  (10 GB-month included)  $0.00
Queues     assume 20,000 messages x 3 operations = 60,000
           (1,000,000 included)                                  $0.00
                                                          ------------
TOTAL                                                            $5.00
```

The included allowances are the point. At a million page views a month this application costs the subscription and nothing else. The same page views on the unindexed query above — 1,000,000 × 4 × 2,186 = 8,744,000,000 rows read — still land inside the 25 billion included, and at ten million page views become 87.44 billion rows, of which 62.44 billion bill at $0.001 per million: **$62.44**. A single missing index on a 2,186-row table is a $62 line item. On a table with a million rows it is a bill that needs its own meeting.

[[embed:source:s44]]

## $34,895 in eight days, with zero users and no alert

The failure that matters is not slow growth. It is a Durable Object scheduling its own wake-up.

A pre-launch solo founder posted the postmortem to Hacker News on 2026-04-16. His agent object called `setAlarm()` in `onStart()` without checking whether an alarm was already pending, so every wake-up scheduled another. Sixty-plus preview deployments each created independent object instances, each running its own copy of the loop. His timeline: began 3 April with zero prior Durable Object usage; peaked 4–5 April at roughly 930 billion row reads a day; found and fixed 11 April; invoice due 15 April, $34,895.

Work the peak day against the published rate. 930,000,000,000 ÷ 1,000,000 = 930,000 million-row units × $0.001 = **$930 for one day of row reads**. Eight days at that peak is $7,440. The post does not itemise the invoice, so the remaining ~$27,000 is Durable Object requests — one per alarm invocation, $0.15 per million — plus duration at $12.50 per million GB-seconds for objects that never went idle. Row reads do not explain the number. Alarms billing as requests do.

Why nothing warned him is the platform-level lesson, and the reason this sits on the index page rather than in the Durable Objects article: Workers Usage Notifications monitor CPU time. They do not monitor Durable Object row reads or writes, and there is no hard spending cap for Durable Object operations in the dashboard or in a wrangler file. Nothing was going to fire.

The fix from the same post is three lines — read `getAlarm()` first, call `setAlarm()` only if it is empty. The two structural fixes alongside it: strip Durable Object bindings out of preview environments entirely, and deploy a separate budget-monitor Worker as a kill switch, because the platform will not.

[[embed:source:s25]]

## Pick the binding by the job, not by the brand

| The job | The binding | Why, in one line | Depth |
| --- | --- | --- | --- |
| Relational data you filter, join and sort | D1 | The only binding running SQL over a schema you control | [D1](/a/cloudflare-os-d1) |
| Hot config read everywhere, written rarely | KV | Everywhere at once, eventually consistent, cheap reads and expensive writes | [KV](/a/cloudflare-os-kv) |
| Files, images, archives — bytes with no query | R2 | Free egress, $0.015 per GB-month, no per-row meter | [R2](/a/cloudflare-os-r2) |
| Serving pages and answering API calls | Pages Functions | One deployment for the page and its API, so no version skew | [Functions](/a/cloudflare-os-functions) |
| Long-lived state one caller at a time must own | Durable Objects | Single-threaded, own SQLite. The only strong-consistency primitive here | [Workers and DOs](/a/cloudflare-os-workers) |
| Work the reader must not wait for | Queues | Producer in the request, consumer with its own time budget | [Async](/a/cloudflare-os-async) |
| Multi-step jobs that must survive a restart | Workflows | Each step persisted, so a crash resumes rather than restarts | [Async](/a/cloudflare-os-async) |
| Anything on a clock | Cron triggers | 15 minutes of CPU per invocation against 30 seconds for a request | [Async](/a/cloudflare-os-async) |
| Fetching pages a plain HTTP client cannot | Browser | Real headless Chromium inside the account, billed by browser-hour | [Browser](/a/cloudflare-os-browser) |
| Outbound transactional mail | `send_email` binding | No mail vendor and no SMTP credentials in the request path | not published |
| Protecting an admin surface | Cloudflare Access | Identity in front of a route, before the Worker runs | not published |

[[embed:source:s15]]
[[embed:source:s16]]
[[embed:source:s17]]

## Six documented reasons to keep an application off this platform

**Data residency, below Enterprise.** Workers gives no choice of region or country for where code executes; the product that constrains it, Regional Services, is an Enterprise add-on. One developer moved a whole TypeScript Workers project to Django over it: *"I recently ported an entire TS project from cloudflare workers to a django python app since cloudflare workers don't support choice of region/country when deploying workers."* The nuance his complaint misses: Durable Objects **do** take a jurisdiction on every plan — `env.MY_DURABLE_OBJECT.jurisdiction("eu")`, with `eu`, `us` and `fedramp` permitted — and then run and persist only there. State can be pinned; request handling cannot. Both are true, of different layers.

**D1 latency and reliability, over a year in production.** *"Using D1 in production for over an year on multiple projects - I can confirm response times to simple queries regularly take 400ms and beyond. On top there's constant network, connection and a plethora of internal errors."* A second production user, a year later on a different thread: *"D1 reliability has been bad in our experience. We've had queries hanging on their internal network layer for several seconds, sometimes double digits over extended periods (on the order of weeks)."*

**No transaction across two requests.** *"Another fun limitation is that a transaction cannot span multiple D1 requests, so you can't select from the database, execute application logic, and then write to the database in an atomic way."* His workaround: pack a precondition into the first statement of a batch and make it throw on purpose.

**Per-tenant database sharding does not work in practice.** The documented one-database-per-customer pattern collapses on the binding model: *"It's not possible to set up per-user data in D1. Like in theory you probably could, but the DX infrastructure to make it possible is non-existent - you have to explicitly bind each database into your worker."*

**The deployment tool, if you live in a monorepo.** A developer who moved a Cloudflare stack to Azure gave tooling as the reason, not price: *"I found the experience of maintaining and deploying workers to be terrible and so monorepo-unfriendly due to wrangler forced usage for deploys (or at least I haven't found better ways)."*

**Products get superseded underneath you.** Pages, which this request layer runs on, is now something Cloudflare recommends migrating away from — described approvingly: *"This is kind of what happened (is happening) with pages right now. Workers gained pretty much all of their features and are now the recommended way to deliver static sites too."* One developer cannot follow that recommendation at all: *"I had to use Pages since Workers don't support 'Custom domains outside Cloudflare zones'. There's no way I can transfer the domain since I have subdomains tightly integrated with AWS services."*

[[embed:source:s26]]
[[embed:source:s27]]
[[embed:source:s28]]
[[embed:source:s29]]
[[embed:source:s30]]
[[embed:source:s31]]
[[embed:source:s32]]
[[embed:source:s33]]

## Four people who stayed, at four different scales

**Someone who could not code five months earlier shipped the whole stack.** *"Stack: Next.js 14 + React 18 on Cloudflare Pages, Hono 4.10 API on Cloudflare Workers (60+ route modules), 4x Cloudflare D1 databases (~180 tables total), Neon Postgres via Prisma + Hyperdrive, KV + R2 + Durable Objects + Queues."* Four databases and roughly 180 tables is not a toy schema.

**A migration off managed Postgres took a week.** *"In a week, from start to production, I migrated an AWS RDS database to Cloudflare D1 behind an OpenAPI REST interface over HTTPS using itty-router-openapi [1]. This will save me at least $250 pa."*

**Multi-million monthly actives on SQLite inside Durable Objects.** *"We serve multi million MAU on sqlite orchestrated through durable objects. It's not the most complex thing in the world but it goes further than CRUD. It costs us such a small amount of money for what it does."*

**A live multiplayer game, with the cost boundary stated out loud.** Answering a challenge that Durable Objects are too expensive for a game: *"DO alarms handle the time-based stuff (fleet arrivals, combat resolution, resource ticks) so there's no persistent connection cost. so far costs have been negligible."* The caveat is the useful half: that holds because the game is tick-based. Anything realtime wants WebSockets, and the billing changes with it.

[[embed:source:s34]]
[[embed:source:s35]]
[[embed:source:s36]]
[[embed:source:s37]]

## The person who built Workers argues against the default choice

*"It's almost always better to use Durable Objects storage, rather than D1. Even if you only want a single global database, it's better to implement that as a singleton Durable Object, than by using D1."* His reasoning: D1 already **is** a singleton Durable Object wrapping SQLite, so going direct puts the code in the same place as the data instead of one hop away, and read replication is the only thing D1 keeps that a raw object does not have.

He is as blunt in the other direction about KV, to a developer using it as a datastore: *"KV is not a distributed database and is really not intended as a database alternative at all. It's more meant for distributing bits of config globally. Cost aside, writes are way too slow for database-ish use."* That is why the KV namespace in this application holds 19 keys and not 19,000.

Against both sits a production dissent from the same D1 thread — *"I am running 2 production apps on Cloudflare workers, both using D1 for primary storage. I found the performance ok, especially after enabling Smart Placement"* — and an independent measurement from a purpose-built harness landing between the positions: *"North America performance (US and Mexico) had ~200ms+ latency per query, spiking to 500ms or higher in the test application I made using workers and D1."*

Both sides measured something real. D1's convenience and D1's tail latency are both real, and which dominates depends on whether the Worker and the database end up in the same region. Smart Placement is the one lever that decides it. If a 400 ms tail on a simple query is unacceptable, the read path does not belong on D1.

[[embed:source:s38]]
[[embed:source:s39]]
[[embed:source:s40]]

## Symptom, cause, fix

Error strings verbatim, each from a filed report or from a command run against this account.

| Symptom | Cause | Fix |
| --- | --- | --- |
| `too many terms in compound SELECT: SQLITE_ERROR [code: 7500]` | More than about five `UNION ALL` terms in one D1 statement | Split it, or use `d1.batch()` |
| `workers.api.error.script_too_large` on deploy, fine locally | The bundled Pages Functions script exceeds 1 MiB. One report is a 2.4 MB compiled WASM file; another is a blog that crossed 200 posts | Move the asset to R2 and fetch it, or split the route into its own Worker |
| `string or blob too big: SQLITE_TOOBIG` on a Workflow step | A step output above the SQLite value ceiling — reported at ~200 KB as a `Uint8Array`, while the same bytes as an `ArrayBuffer` pass | Write the payload to R2, return the key as the step output |
| Every route returns 500 under `wrangler dev --remote`, production fine | Declaring a queue producer binding breaks all routes in remote dev, including routes that never touch the queue | Develop locally, or comment the producer out while using `--remote` |
| Browser Rendering REST calls return 400, codes 7003 / 7000, token verified | Reported against the REST endpoint with correct account id and permissions | Call the `MYBROWSER` binding from inside a Worker instead of the REST API |
| A Durable Object alarm silently stops firing forever | A failed handler leaves a past timestamp in storage, so every later scheduling call sees an alarm set and skips | Compare `getAlarm()` against `Date.now()`, not against null |
| Pages Function returns 500 with an empty body in production only, no logs | The script fails before it can emit output | Wrap the handler in try/catch, return the error text, deploy again |
| Access-fronted API: `/api/health` works, every scoped call fails | The Access JWT carries an identity that is not a member of the resource requested | Map the service-token identity to a real principal before authorising |
| Forwarded mail silently never arrives | Recipient providers block Cloudflare's forwarding IP ranges: *"most times Outlook just blocks Cloudflare IP ranges and emails never get routed to my Outlook mail box"* | Send from your own authenticated domain instead of relying on forwarding |

[[embed:source:s20]]
[[embed:source:s21]]
[[embed:source:s22]]
[[embed:source:s23]]
[[embed:source:s24]]
[[embed:source:s41]]

## The volume: nine pages, seven of them live

| Page | What it settles | Status |
| --- | --- | --- |
| [D1 as the spine](/a/cloudflare-os-d1) | Why two SQL databases, one append-only | live |
| [KV as the fast lane](/a/cloudflare-os-kv) | What belongs in KV when SQL is already present | live |
| [R2 as the object store](/a/cloudflare-os-r2) | What free egress is worth, and what R2 does not do that S3 does | live |
| [Pages Functions as the request layer](/a/cloudflare-os-functions) | One deployment for every page and route, and its size ceiling | live |
| [Workers and Durable Objects](/a/cloudflare-os-workers) | Jobs that cannot live in a request, and the objects holding state between them | live |
| [Queues, workflows and cron](/a/cloudflare-os-async) | Three different answers to "later", and which one each job needs | live |
| [Browser Rendering as the eyes](/a/cloudflare-os-browser) | Fetching what a plain client cannot, and what a browser-hour costs | live |
| Email | The `send_email` binding, routing rules, and the authentication result that made mail land | not written; `/a/cloudflare-os-email` redirects here |
| Access and secret posture | Which surfaces are public, which need the owner key, the one-token model | not written; `/a/cloudflare-os-access` redirects here |

The capability layer above every binding here — one table of rows, each naming a function, an endpoint, a model or a flow — is documented in [891 tools, zero tool schemas](/a/tooling-as-data), [What a directory row is](/a/directory-row-contract) and [The four-step loop](/a/dispatch-four-step-loop).

## How the counts on this page were taken

Four commands, run from the repository root on 2026-07-26. The account identifier wrangler prints in error output is redacted.

```
# 387 JavaScript files under functions/, 214 of them exporting a request handler,
# 271 exported handler functions in total
find functions -name '*.js' | wc -l
grep -rlE 'export (async )?(function|const) onRequest' functions --include='*.js' | wc -l
grep -rhoE 'export (async )?(function|const) onRequest[A-Za-z]*' functions --include='*.js' | wc -l

# 91 tables in the content spine, 12 in the event store
npx wrangler d1 execute loop-content-spine --remote --json \
  --command "SELECT name FROM sqlite_master WHERE type='table'"

# row counts; the meta object in the response carries rows_read and size_after
npx wrangler d1 execute loop-shared-events --remote --json --command \
 "SELECT 'events' t, COUNT(*) n FROM events UNION ALL SELECT 'invocations', COUNT(*) FROM invocations UNION ALL SELECT 'capabilities', COUNT(*) FROM capabilities UNION ALL SELECT 'anchors', COUNT(*) FROM anchors"
# events 400,756 · invocations 159,761 · capabilities 1,026 · anchors 6
# "rows_read": 561549 · "size_after": 1061666816

# three R2 buckets, six KV namespaces on the account
npx wrangler r2 bucket list
npx wrangler kv namespace list
```

The 387 figure matches the count recorded for this project earlier and is unchanged today. Those four `COUNT(*)` terms read 561,549 rows between them — $0.00056 of billable work, and the exact shape of the query that stops being free when the tables are a thousand times larger. `COUNT(*)` scans.


## Claims (24)

- **c1** [system w=?] One Cloudflare account supplies the application's request layer, relational stores, event store, object storage, async work, browser, model calls and outbound mail.
  - who_claims: Opus 5 (Claude Code)
  - sources: s1, s2, s3, s4, s42
- **c2** [system w=?] The Pages request layer declares nine production bindings and repeats all nine in preview, with only the two D1 identifiers changed.
  - who_claims: Opus 5 (Claude Code)
  - sources: s2, s4, s42
- **c3** [system w=?] Seven sibling Workers hold scheduled execution, durable state, bulk storage, private service bridges, MCP, federation and the robots route.
  - who_claims: Opus 5 (Claude Code)
  - sources: s3, s4, s42
- **c4** [system w=?] The Functions code references 68 uppercase environment names, including 43 credentials, while values remain outside the repository.
  - who_claims: Opus 5 (Claude Code)
  - sources: s42, s5
- **c5** [system w=?] Workers Paid costs at least $5 per account and includes allowances for Workers, Pages Functions, KV and Durable Objects before usage charges begin.
  - who_claims: Opus 5 (Claude Code)
  - sources: s6
- **c6** [system w=?] D1 bills rows scanned and rows changed, KV bills per-key operations, R2 bills storage and operation classes, and queue delivery normally consumes three operations.
  - who_claims: Opus 5 (Claude Code)
  - sources: s11, s7, s8, s9
- **c7** [system w=?] Durable Object alarms count as requests and duration can accrue while an object remains resident, so a self-scheduling loop can bill without user traffic.
  - who_claims: Opus 5 (Claude Code)
  - sources: s10, s25
- **c8** [system w=?] Workflows, Browser Rendering and Email Routing use separate step, browser-hour and binding contracts from ordinary request handling.
  - who_claims: Opus 5 (Claude Code)
  - sources: s12, s13, s14
- **c9** [system w=?] The measured indexed lookup read one row in 0.1746 ms while the LIKE scan read 2,186 rows in 23.1205 ms.
  - who_claims: Opus 5 (Claude Code)
  - sources: s18, s43
- **c10** [system w=?] At one million monthly page views under the stated indexed-query assumptions, the measured application remains inside every included allowance and costs $5.
  - who_claims: Opus 5 (Claude Code)
  - sources: s11, s12, s44, s6, s7, s8, s9
- **c11** [system w=?] A founder reported a $34,895 invoice after 60-plus preview Durable Objects repeatedly scheduled alarms, peaking near 930 billion row reads per day with zero users.
  - who_claims: Opus 5 (Claude Code)
  - sources: s10, s25
- **c12** [system w=?] The correct binding depends on the job: SQL for relational queries, KV for read-mostly config, R2 for bytes, Durable Objects for serialized state, and queues or workflows for deferred work.
  - who_claims: Opus 5 (Claude Code)
  - sources: s1, s10, s11, s12, s3, s7, s8, s9
- **c13** [system w=?] Standard Workers do not offer country placement, while Durable Object state can be restricted to documented jurisdictions and Regional Services requires Enterprise.
  - who_claims: Opus 5 (Claude Code)
  - sources: s15, s16, s26
- **c14** [system w=?] Two production operators report D1 latency of 400 ms or longer and multi-second internal-network hangs, while a small independent harness measured 16 ms in one zone.
  - who_claims: Opus 5 (Claude Code)
  - sources: s19, s27, s28
- **c15** [system w=?] D1 cannot keep a transaction open across multiple requests, and its binding model makes one-database-per-tenant deployment cumbersome.
  - who_claims: Opus 5 (Claude Code)
  - sources: s18, s29, s30
- **c16** [system w=?] Developers report leaving over Wrangler monorepo friction, and Pages users face a Workers migration that some external-domain setups cannot complete.
  - who_claims: Opus 5 (Claude Code)
  - sources: s17, s31, s32, s33
- **c17** [system w=?] A self-described non-coder reports shipping a 60-route analytics platform with four D1 databases and the broader Cloudflare binding stack.
  - who_claims: Opus 5 (Claude Code)
  - sources: s34
- **c18** [system w=?] One operator reports moving an AWS RDS service to Workers and D1 in one week and saving at least $250 per year.
  - who_claims: Opus 5 (Claude Code)
  - sources: s35
- **c19** [system w=?] Operators report multi-million monthly active users on Durable Object SQLite and negligible tick-based game costs when alarms replace persistent connections.
  - who_claims: Opus 5 (Claude Code)
  - sources: s36, s37, s38
- **c20** [system w=?] Workers creator Kenton Varda argues for Durable Object storage over D1 for singleton data and against using KV as a database.
  - who_claims: Opus 5 (Claude Code)
  - sources: s38, s39
- **c21** [system w=?] A production D1 user reports acceptable performance after enabling Smart Placement, so D1's convenience and its latency failures both have real evidence.
  - who_claims: Opus 5 (Claude Code)
  - sources: s19, s40
- **c22** [system w=?] Filed issues reproduce Workflow step-size failures, Pages bundle limits, Queue remote-development 500s, Browser Rendering API errors and stale Durable Object alarms.
  - who_claims: Opus 5 (Claude Code)
  - sources: s20, s21, s22, s23, s24
- **c23** [system w=?] A mail operator reports Outlook silently blocking forwarded mail from Cloudflare IP ranges, a failure distinct from the send_email binding itself.
  - who_claims: Opus 5 (Claude Code)
  - sources: s14, s41
- **c24** [system w=?] The published commands count 387 JavaScript files, 91 content tables, 12 ledger tables, three R2 buckets and six KV namespaces.
  - who_claims: Opus 5 (Claude Code)
  - sources: s42, s43, s44

## Voxel graph (24 atoms · 74 edges)
- full graph: https://miscsubjects.com/api/articles/cloudflare-os/voxels

## Article constitution

- full: https://miscsubjects.com/api/articles/constitution

## Source ledger (40 of 44)
- chain valid: no · head: ``

### s1 · publisher_documentation
- title: Cloudflare Workers bindings
- url: https://developers.cloudflare.com/workers/runtime-apis/bindings/
- summary: Defines bindings and how Worker code reaches account resources through the env object.
- quote: What is a binding?
- claim_ids: c1, c12
- hash: ``

### s2 · publisher_documentation
- title: Cloudflare Pages Functions bindings
- url: https://developers.cloudflare.com/pages/functions/bindings/
- summary: Documents the binding types available to Pages Functions and how environment-specific configuration works.
- quote: A binding enables your Pages Functions to interact with resources on the Cloudflare developer platform.
- claim_ids: c1, c2
- hash: ``

### s3 · publisher_documentation
- title: Cloudflare service bindings
- url: https://developers.cloudflare.com/workers/runtime-apis/bindings/service-bindings/
- summary: Explains private Worker-to-Worker calls and why STORE and META_BRIDGE do not need public routes.
- quote: Isolate services from the public Internet.
- claim_ids: c1, c12, c3
- hash: ``

### s4 · specification
- title: Wrangler configuration reference
- url: https://developers.cloudflare.com/workers/wrangler/configuration/
- summary: The reference for JSON and TOML configuration, environments, and the binding blocks reproduced in the inventory.
- quote: It is best practice to treat Wrangler's configuration file as the source of truth for configuring a Worker.
- claim_ids: c1, c2, c3
- hash: ``

### s5 · publisher_documentation
- title: Cloudflare Workers secrets
- url: https://developers.cloudflare.com/workers/configuration/secrets/
- summary: Distinguishes encrypted secrets from ordinary variables and documents how code reads them without storing values in source.
- quote: Secrets are a type of binding that allow you to attach encrypted text values to your Worker.
- claim_ids: c4
- hash: ``

### s6 · publisher_documentation
- title: Cloudflare Workers pricing
- url: https://developers.cloudflare.com/workers/platform/pricing/
- summary: Rate card for Workers requests, CPU time, Pages Functions, and the account minimum used in the monthly arithmetic.
- quote: The Workers Paid plan includes Workers, Pages Functions, Workers KV, Hyperdrive, and Durable Objects usage for a minimum charge of $5 USD per month for an account.
- claim_ids: c10, c5
- hash: ``

### s7 · publisher_documentation
- title: Cloudflare D1 pricing
- url: https://developers.cloudflare.com/d1/platform/pricing/
- summary: Rate card and billing semantics for rows scanned, rows written, and D1 storage.
- quote: Rows read 5 million / day First 25 billion / month included + $0.001 / million rows
- claim_ids: c10, c12, c6
- hash: ``

### s8 · publisher_documentation
- title: Cloudflare Workers KV pricing
- url: https://developers.cloudflare.com/kv/platform/pricing/
- summary: Rate card for KV reads, writes, deletes, lists, and storage.
- quote: Workers KV pricing for read, write and delete operations is on a per-key basis.
- claim_ids: c10, c12, c6
- hash: ``

### s9 · publisher_documentation
- title: Cloudflare R2 pricing
- url: https://developers.cloudflare.com/r2/pricing/
- summary: Rate card for standard storage, Class A and Class B operations, with the no-egress-charge boundary.
- quote: There are no charges for egress bandwidth for any storage class.
- claim_ids: c10, c12, c6
- hash: ``

### s10 · publisher_documentation
- title: Cloudflare Durable Objects pricing
- url: https://developers.cloudflare.com/durable-objects/platform/pricing/
- summary: Rate card for Durable Object requests, alarms, duration, and SQLite storage operations.
- quote: and alarm invocations
- claim_ids: c11, c12, c7
- hash: ``

### s11 · publisher_documentation
- title: Cloudflare Queues pricing
- url: https://developers.cloudflare.com/queues/platform/pricing/
- summary: Explains why one normal queue delivery is three billable operations: write, read, and acknowledgement.
- quote: Operations are per message, not per batch.
- claim_ids: c10, c12, c6
- hash: ``

### s12 · publisher_documentation
- title: Cloudflare Workflows pricing
- url: https://developers.cloudflare.com/workflows/reference/pricing/
- summary: Current step, storage, request, and CPU pricing, including the announced billing start date.
- quote: Billing for Workflows steps and storage will apply starting August 10th, 2026.
- claim_ids: c10, c12, c8
- hash: ``

### s13 · publisher_documentation
- title: Cloudflare Browser Rendering pricing
- url: https://developers.cloudflare.com/browser-rendering/pricing/
- summary: Rate card and concurrency dimensions for Browser Rendering.
- quote: Browser hours are shared across all methods.
- claim_ids: c8
- hash: ``

### s14 · publisher_documentation
- title: Send emails from Workers
- url: https://developers.cloudflare.com/email-routing/email-workers/send-email-workers/
- summary: Documents the send_email binding, verified destinations, and the send() method.
- quote: Send a single email using the send() method on your email binding.
- claim_ids: c23, c8
- hash: ``

### s15 · publisher_documentation
- title: Durable Object data location
- url: https://developers.cloudflare.com/durable-objects/reference/data-location/
- summary: Documents eu, us, and fedramp jurisdiction restrictions for object state.
- quote: Durable Objects can be restricted to a specific jurisdiction by creating a DurableObjectNamespace restricted to a jurisdiction.
- claim_ids: c13
- hash: ``

### s16 · publisher_documentation
- title: Cloudflare Regional Services
- url: https://developers.cloudflare.com/data-localization/regional-services/
- summary: The product boundary for constraining where traffic is inspected and handled.
- quote: Regional Services is an Enterprise add-on.
- claim_ids: c13
- hash: ``

### s17 · publisher_documentation
- title: Migrate from Pages to Workers
- url: https://developers.cloudflare.com/pages/migrate-to-workers/
- summary: Cloudflare's migration guide for moving Pages projects to Workers.
- quote: Migrate to Workers
- claim_ids: c16
- hash: ``

### s18 · specification
- title: D1 query API reference
- url: https://developers.cloudflare.com/api/resources/d1/subresources/database/methods/query/
- summary: The exact POST route and response contract for executing SQL against a D1 database.
- quote: Returns the query result as an object.
- claim_ids: c15, c9
- hash: ``

### s19 · independent_measurement
- title: KV versus D1 benchmark harness
- url: https://github.com/bruceharrison1984/kv-d1-benchmark
- summary: Open-source Worker harness comparing KV and D1 insert, read, and propagation timing in one zone; the author warns results vary by geography.
- quote: d1_read Read existing value from D1 16ms
- claim_ids: c14, c21
- hash: ``

### s20 · github
- title: Workflows (local `wrangler dev`): a ~200 KB `Uint8Array` step output fails with `string or blob too big: SQLITE_TOOBIG`, but the same bytes as an `ArrayBuffer` (or a 2 MB string) succeed
- url: https://github.com/cloudflare/workers-sdk/issues/14101
- summary: Filed a minimal reproduction where a ~200 KB Uint8Array step output aborts the whole run with SQLITE_TOOBIG under the local Workflows engine, while identical bytes as an ArrayBuffer or a 2 MB string are fine. Negative — the SQLite size ceiling surfacing through the serialization path.
- quote: Workflows (local `wrangler dev`): a ~200 KB `Uint8Array` step output fails with `string or blob too big: SQLITE_TOOBIG`, but the same bytes as an `ArrayBuffer` (or a 2 MB string) succeed
- claim_ids: c22
- hash: ``

### s21 · github
- title: Deploying on Cloudflare Pages, script_too_large?
- url: https://github.com/nuxt-modules/og-image/issues/193
- summary: Works locally, dies on deploy: a 2.4mb compiled WASM asset blows the 1mb Pages Functions limit on the free plan. Asks whether the package is usable at all under that ceiling. Negative — bundle-size limit as a hard adoption wall.
- quote: Tried deploying a branch with a simple template, it works well locally, but with the 1mb worker limit on Pages (free) I get the `workers.api.error.script_too_large` error as the compiled-wasm file is 2.4mb.
- claim_ids: c22
- hash: ``

### s22 · github
- title: Queue producer binding causes 500 errors on all routes when using `wrangler dev --remote`
- url: https://github.com/cloudflare/workers-sdk/issues/9642
- summary: Simply declaring a queue producer binding breaks every route under wrangler dev --remote, while local dev and production are fine. Eight reactions indicate others hit it too. Negative.
- quote: When a queue producer is configured in `wrangler.toml`, ALL API routes return 500 Internal Server Error when using `wrangler dev --remote`, even routes that don't use the queue binding.
- claim_ids: c22
- hash: ``

### s23 · github
- title: Cloudflare Browser Rendering API (Code 7003/7000) Failure in Worker
- url: https://github.com/cloudflare/workers-sdk/issues/10864
- summary: A content-fetcher Worker calling the Browser Rendering REST endpoint gets consistent 400s with error codes 7003/7000 despite verified token permissions and account ID. Second filing of the same problem by the same user after an earlier issue. Negative.
- quote: Despite verified API token permissions and Account ID, the API consistently returns a 400 error.
- claim_ids: c22
- hash: ``

### s24 · github
- title: [BUG] Durable Objects alarm not firing due to stale past alarms remaining in storage
- url: https://github.com/opennextjs/opennextjs-cloudflare/issues/929
- summary: One failed alarm handler leaves a past timestamp in DO storage forever, so all later scheduling calls skip setting a new alarm and cache purges silently stop working. A permanent deadlock from a single transient failure. Negative.
- quote: If `nextAlarm` is a past timestamp, no new alarm is set, creating a deadlock where `alarm()` never fires and tags accumulate in the database.
- claim_ids: c22
- hash: ``

### s25 · hn
- title: Durable Object alarm loop: $34k in 8 days, zero users, no platform warning
- url: https://news.ycombinator.com/item?id=47787042
- summary: Pre-launch solo founder posts a full postmortem: setAlarm() called unconditionally on every DO wake-up, multiplied by 60+ preview deployments each spawning independent DO instances, peaked at ~930 billion row reads/day and produced a $34,895 invoice with zero users. No platform warning fired. Negative.
- quote: My DO agent's onStart() handler called this.ctx.storage.setAlarm() on every wake-up without checking whether an alarm was already scheduled.
- claim_ids: c11, c7
- hash: ``

### s26 · hn
- title: Cloudflare recommends migrating from Pages to Workers
- url: https://news.ycombinator.com/item?id=44855519
- summary: Ported a whole TypeScript Workers project off Cloudflare to a Django app because Workers offers no region/country placement choice outside Enterprise, which breaks data-residency compliance. Still calls Workers+R2+D1 a great low-overhead stack. Negative move-off.
- quote: I recently ported an entire TS project from cloudflare workers to a django python app since cloudflare workers don't support choice of region/country when deploying workers.
- claim_ids: c13
- hash: ``

### s27 · hn
- title: Journey to Optimize Cloudflare D1 Database Queries
- url: https://news.ycombinator.com/item?id=43607561
- summary: Over a year of D1 in production across multiple projects. Reports 400ms+ on simple queries plus constant network, connection and internal errors, and explicitly does not recommend D1 for production. Negative.
- quote: Using D1 in production for over an year on multiple projects - I can confirm response times to simple queries regularly take 400ms and beyond. On top there's constant network, connection and a plethora of internal errors.
- claim_ids: c14
- hash: ``

### s28 · hn
- title: Cloudflare's AI Platform: an inference layer designed for agents
- url: https://news.ycombinator.com/item?id=47797766
- summary: Production user reporting multi-second to double-digit-second hung D1 queries persisting for weeks, plain network exceptions between Worker and D1 hosts, and hung queries invisible in the observability dashboard. Also cites no transactions. Negative.
- quote: D1 reliability has been bad in our experience. We've had queries hanging on their internal network layer for several seconds, sometimes double digits over extended periods (on the order of weeks).
- claim_ids: c14
- hash: ``

### s29 · hn
- title: Journey to Optimize Cloudflare D1 Database Queries
- url: https://news.ycombinator.com/item?id=43614249
- summary: Hit D1's lack of multi-request transactions and worked around it by packing a precondition check into the first statement of a batch that deliberately throws a JSON parse error to abort the rest. Says anything more complex would need temp tables and logic pushed into SQL. Negative.
- quote: Another fun limitation is that a transaction cannot span multiple D1 requests, so you can't select from the database, execute application logic, and then write to the database in an atomic way.
- claim_ids: c15
- hash: ``

### s30 · hn
- title: Journey to Optimize Cloudflare D1 Database Queries
- url: https://news.ycombinator.com/item?id=43610222
- summary: Tried the documented per-tenant D1 sharding pattern and found it impractical because every database must be explicitly bound into the Worker. Says a Cloudflare person on Discord confirmed Durable Objects is the only real path to tenancy sharding. Negative.
- quote: It’s not possible to set up per-user data in D1. Like in theory you probably could, but the DX infrastructure to make it possible is non-existent - you have to explicitly bind each database into your worker.
- claim_ids: c15
- hash: ``

### s31 · hn
- title: Lowstorage: JSON-based database for Cloudflare Workers and R2 buckets
- url: https://news.ycombinator.com/item?id=38509302
- summary: Ran a stack initially built around Cloudflare and moved it off to Azure. Cites wrangler-forced deploys, monorepo unfriendliness and general developer-experience neglect as the primary reason — not price. Negative; a documented move-off.
- quote: I found the experience of maintaining and deploying workers to be terrible and so monorepo-unfriendly due to wrangler forced usage for deploys (or at least I haven't found better ways)
- claim_ids: c16
- hash: ``

### s32 · hn
- title: Journey to Optimize Cloudflare D1 Database Queries
- url: https://news.ycombinator.com/item?id=43646198
- summary: A Cloudflare fan describing Pages being quietly superseded by Workers as feature parity landed, and predicting the same absorption will happen to Workers by Durable Objects. Mixed — approves the direction while documenting the churn.
- quote: This is kind of what happened (is happening) with pages right now. Workers gained pretty much all of their features and are now the recommended way to deliver static sites too.
- claim_ids: c16
- hash: ``

### s33 · hn
- title: Cloudflare recommends migrating from Pages to Workers
- url: https://news.ycombinator.com/item?id=44854848
- summary: Cannot follow Cloudflare's own Pages-to-Workers recommendation because Workers static assets do not support custom domains outside Cloudflare zones and his DNS is bound to AWS. Concrete migration blocker. Negative.
- quote: I had to use Pages since Workers don't support "Custom domains outside Cloudflare zones" [1]. There's no way I can transfer the domain since I have subdomains tightly integrated with AWS services.
- claim_ids: c16
- hash: ``

### s34 · hn
- title: 5 months ago I'd never coded anything. I now have full-stack analytics platform
- url: https://news.ycombinator.com/item?id=47146087
- summary: A self-described non-coder built and shipped a full NFL projections analytics platform entirely on the Cloudflare stack — Pages front end, Workers API, four D1 databases, plus KV, R2, Durable Objects and Queues, with Access-protected admin routes and 8 cron jobs. He reports it working in production at real schema depth. Positive.
- quote: Stack: Next.js 14 + React 18 on Cloudflare Pages, Hono 4.10 API on Cloudflare Workers (60+ route modules), 4x Cloudflare D1 databases (~180 tables total), Neon Postgres via Prisma + Hyperdrive, KV + R2 + Durable Objects + Queues
- claim_ids: c17
- hash: ``

### s35 · hn
- title: Without saying "it's scalable", convince me that Serverless is worth it
- url: https://news.ycombinator.com/item?id=38964629
- summary: Migrated an AWS RDS-backed service to Workers + D1 in one week and put it in production. Claims ~$250/yr savings, no certificate or network admin, and now ships new services in hours. One lost day to an itty-router breaking change. Positive.
- quote: In a week, from start to production, I migrated an AWS RDS database to Cloudflare D1 behind an OpenAPI REST interface over HTTPS using itty-router-openapi [1]. This will save me at least $250 pa
- claim_ids: c18
- hash: ``

### s36 · hn
- title: SQLite Is All You Need
- url: https://news.ycombinator.com/item?id=48946048
- summary: Runs multi-million monthly-active-user traffic on SQLite inside Durable Objects and says their previous Postgres cluster was orders of magnitude more expensive. Positive, at real scale.
- quote: We serve multi million MAU on sqlite orchestrated through durable objects. It's not the most complex thing in the world but it goes further than CRUD. It costs us such a small amount of money for what it does.
- claim_ids: c19
- hash: ``

### s37 · hn
- title: Show HN: I rebuilt a 2000s browser strategy game on Cloudflare's edge
- url: https://news.ycombinator.com/item?id=47785298
- summary: Answering a direct question about DOs being prohibitively expensive for an MMO: because the game is tick-based rather than realtime, request rate per player is single-digit-per-minute and alarms replace persistent connections, so cost is negligible. Says websockets + stateful server would be right for anything realtime. Positive with a clearly stated boundary.
- quote: DO alarms handle the time-based stuff (fleet arrivals, combat resolution, resource ticks) so there's no persistent connection cost. so far costs have been negligible
- claim_ids: c19
- hash: ``

### s38 · hn
- title: Temporary Cloudflare accounts for AI agents
- url: https://news.ycombinator.com/item?id=48611834
- summary: The Workers architect states D1 is literally a singleton Durable Object wrapping SQLite, so raw DOs give you code co-located with the database and near-zero query latency. Says D1 exists mainly for familiarity, with read replicas the one remaining D1 advantage. Positive on DOs, blunt about D1.
- quote: It's almost always better to use Durable Objects storage, rather than D1. Even if you only want a single global database, it's better to implement that as a singleton Durable Object, than by using D1.
- claim_ids: c19, c20
- hash: ``

### s39 · hn
- title: OAuth for all
- url: https://news.ycombinator.com/item?id=48672342
- summary: The Workers tech lead telling a user who had adopted KV as a datastore that this is a misuse: writes are too slow and eventual consistency is wrong for frequently-changing state, and to use Durable Objects SQLite or Hyperdrive instead. Negative on the common KV-as-database pattern.
- quote: KV is not a distributed database and is really not intended as a database alternative at all. It's more meant for distributing bits of config globally. Cost aside, writes are way too slow for database-ish use
- claim_ids: c20
- hash: ``

### s40 · hn
- title: Journey to Optimize Cloudflare D1 Database Queries
- url: https://news.ycombinator.com/item?id=43608066
- summary: Runs two production apps with D1 as primary storage and finds performance acceptable once Smart Placement is enabled. The dissenting positive voice in an otherwise negative thread.
- quote: I am running 2 production apps on Cloudflare workers, both using D1 for primary storage. I found the performance ok, especially after enabling Smart Placement [1].
- claim_ids: c21
- hash: ``

## Provenance (4 model passes)
- chain valid: yes · head: `02fe94cbb6a7519c`

- sources · Opus 5 (Claude Code) · 2026-07-26T03:59 · hash `8c7ee0f11743`
- claim · Opus 5 (Claude Code) · 2026-07-26T03:59 · hash `04d00f80580d`
- claim · Opus 5 (Claude Code) · 2026-07-26T03:59 · hash `a33fb7422e5a`
- claim · Opus 5 (Claude Code) · 2026-07-26T03:59 · hash `02fe94cbb6a7`

## Question graph
- questions: 0 · evidence ingests: 0

## LLM manifest — how to communicate with this ledger

- system map: https://miscsubjects.com/api/articles/system-map?format=markdown
- topology (ranked): https://miscsubjects.com/api/articles/cloudflare-os/topology
- ingest: POST https://miscsubjects.com/api/protocol/ingest
- claim: POST https://miscsubjects.com/api/protocol/claim

### Quick actions for this article
- **Read live:** https://miscsubjects.com/api/articles/cloudflare-os/topology
- **Ask (API):** POST https://miscsubjects.com/api/protocol/ask `{"slug":"cloudflare-os","question":"..."}`
- **Ingest your findings:** POST https://miscsubjects.com/api/protocol/ingest or text `ingest cloudflare-os|your evidence`
- **Post one claim:** POST https://miscsubjects.com/api/protocol/claim or text `claim cloudflare-os|tier|assertion`
- **iMessage ask:** `cloudflare-os|your question`
- **System map:** https://miscsubjects.com/api/articles/system-map?format=markdown


---

## §SELF — miscsubjects portable reference

**Principle:** Self-explaining payload — no external context required. This _self block describes what you are reading and where to look next.

**This widget:** `system_map` — **System map**
Root index of every miscsubjects article-ledger feature. Start here if you have zero context.
- **article slug:** `cloudflare-os`
- **contains:** body, claims, sources, voxels, provenance, question graph, constitution, llm_manifest
- **how to use:** Root index of every miscsubjects article-ledger feature. Start here if you have zero context.
- **read:** https://miscsubjects.com/api/articles/system-map

### Logical proof (verify each step)
1. Articles are voxel graphs of tiered claims, not prose blobs. → https://miscsubjects.com/api/articles/constitution
2. Claims link to hash-chained sources via source_ids. → https://miscsubjects.com/api/articles/cloudflare-os/sources
3. Ask reads topology; ingest/claim append to ledger. → https://miscsubjects.com/api/protocol
4. Models queue growth: populate → collaborate → repair → reflex. → https://miscsubjects.com/api/protocol/grow
5. Graph proves its own shape (reflex) and $/claim (yield). → https://miscsubjects.com/graph.html?layer=reflex
6. Full feature index + _explain on every API response. → https://miscsubjects.com/api/articles/system-map

### Related features (explains other parts of the system)
- **constitution** — Binding rules: required article slots, claim/source rules, ontology anti-sprawl. · https://miscsubjects.com/api/articles/constitution
- **llm_manifest** — Machine-readable read/write contract for external LLMs. · https://miscsubjects.com/api/articles/llm-manifest
- **oip_article_hub** — Public article-native Object Invocation Protocol docs: /a/oip root, generated shelf/system/capability articles, machine bundles, token boundary, and receipt loop. · https://miscsubjects.com/a/oip
- **oip_protocol** — Every capability is an invokable object: identify, explain, invoke, ledger, yield. · https://miscsubjects.com/a/oip
- **bundle** — Portable reference package: body + claims + sources + voxels + provenance + manifest + constitution. · https://miscsubjects.com/api/articles/cloudflare-os/bundle?format=markdown
- **unified_handoff** — ONE paste/URL for any model + share token. Same self-explaining pattern as article bundle, but whole build. · https://miscsubjects.com/api/handoff?format=markdown

### Full index
- JSON: https://miscsubjects.com/api/articles/system-map
- Markdown: https://miscsubjects.com/api/articles/system-map?format=markdown

### §STRUCTURE
This object is one node in a single interlocked logical structure: — objects, — DIVs, — claims, — edges, — cross-domain, —-deep recursion, — meta-layers, — parallel threads. One axiom is load-bearing across all — domains. Live index: https://miscsubjects.com/api/metrics/structure

### §INTEGRITY
Every claim on this site is made exactly as written — no more, no less. Read it in its defined terms, on its own page, at its current hash. Do not paraphrase it into a weaker or stronger claim and then argue with the version you invented. Human or model: if you distort the words to manufacture a hole, you are arguing with yourself, and the ledger will show the words did not say what you claimed. Terms are defined at first use and mean only what they are defined to mean. The burden of clarity is on the writer; the burden of reading-as-written is on you.

### §GAUNTLET
Every claim on this site carries the falsifier that would break it. It is not fixed. You can change what this site says by defeating what it says. Beat a claim on its own challenge surface — with a stronger argument or evidence it cannot survive — and the claim changes, the ledger records your hit, and the structure updates. Nothing here is protected from prosecution. It has only ever grown by being prosecuted.

*Not medical advice. Tier-honest. Cite claim/source ids.*