Small Cloudflare products often start with a simple Worker and a few cached blobs. That is fine for a prototype, but it becomes hard to trust once the product makes decisions: which source was fetched, which item was skipped, which summary was published, and which post went to which channel.

Shipstone moved the opposite way. D1 became the system of record. KV stayed useful, but only for things that are safe to rebuild.

The rule

If a row explains behavior, it belongs in D1.

That means source attempts, failed fetches, classifications, summaries, quality rejections, budget checks, and social delivery all need durable rows. The public reader can still be fast, but the answer to “why is this on the site?” should come from a database query, not from memory or a stale cache object.

What D1 owns

For Shipstone, D1 owns:

  • topics and sources
  • pipeline runs and per-topic run rows
  • source runs, source items, and item versions
  • relevance decisions
  • summaries and AI call metadata
  • summary quality events
  • cost budgets and rollups
  • social post queue and delivery status
  • retention run evidence

This makes bugs less mysterious. If a source fails, the failure is stored. If a summary is rejected, the rejection is stored. If a social post is sent, the provider reference is stored.

What KV can still do

KV is useful for cache and sessions. It should not be the only place a business decision exists.

A practical split:

  • use D1 for canonical state
  • use KV for derived reader cache
  • make cache rebuildable from D1
  • keep public pages working without KV reads when validating the data path

That last point is important. A D1-first claim is only credible if the reader can render with KV disabled.

Why it helps solo delivery

This design is slower than throwing JSON into cache, but it pays back quickly:

  • admin pages can explain the pipeline
  • smoke tests can prove behavior
  • bad posts can be removed and marked in D1
  • costs can be paused before spend grows
  • retention can prune old data without deleting the audit trail

The product stays small, but the operating model is not fragile.

The tradeoff

D1-first does not remove product judgment. You still need source quality, readable summaries, and launch discipline. It only gives you a clean place to inspect the work.

For a small SaaS or content product, that is usually the right trade: fewer hidden states, fewer mystery bugs, and a much easier path from prototype to something people can trust.