Note shared via recollect.fyi

EmDash sites on Cloudflare: keeping costs low and performance high

How I keep my EmDash sites absurdly fast while costing about $5 a month in total.

Coywolf Pack plugin methods

https://github.com/coywolf-llc/coywolf-pack

Page caching

  • Workers Cache in front of every site. Cached pages are served without running the Worker, so they cost no CPU and no D1 reads. The default lifetime is 7 days, plus 1 day of serving the old copy while a fresh one is built; it can be changed under Plugins → Performance.
  • Precise purging. EmDash clears only the pages a content, menu, taxonomy or settings change affects (by cache tag). The pack clears everything after each deploy (it detects a new version through the CF_VERSION_METADATA binding) and after its own admin saves.
  • No caching of broken pages. A page built after a failed database read isn't cached. A page showing a video's temporary Stream poster is cached for only 5 minutes.
  • Cache warming. After a deploy, a full clear or content edits, the pack visits every sitemap page a few at a time, piggybacking on real traffic, so visitors and crawlers find pages already cached. A daily refresh rebuilds only the pages Cloudflare dropped. On coywolf.com it's about 10% of CPU.

Responses kept at the edge

  • Redirects: 30 days, cleared when a redirect is edited.
  • robots.txt: 1 day, whether the pack or EmDash serves it. Stray requests like /news/robots.txt get a small cached 404 instead of a full 404 page.
  • XML sitemaps: 1 day (each site's own code). Publishing clears them right away.
  • RSS feeds: 1 hour, tagged so a publish, edit or category change clears them.
  • Live search script: 1 year, since its URL changes with each release.

Fewer and cheaper database reads

  • Feature switches and settings are read in one cached query per Worker isolate (about every 30 seconds), not on every request. Redirect rules, robots rules and Discovery documents are also kept in isolate memory.
  • Live search uses a full-text search engine that needs 2 database round trips instead of about 25, with results cached by content version.
  • llms.txt and the News sitemap are stored in plugin storage and rebuilt in the background a few seconds after changes, never on a visitor's request.
  • Link Manager checks links in paced hourly steps within the Workers subrequest limits. Its queries were rewritten to avoid scanning whole tables, which used to read about 2.5 million rows per weekly run.

Images and media

  • Media host on its own subdomain: media.<domain> is an R2 custom domain with Cloudflare Image Transformations, serving AVIF and WebP.
  • Sizes stored once. The exact crop sizes each theme uses are saved to R2 the first time a page needs them, so images aren't resized again on every request and don't use up transformation quota.
  • A 1-year Cache Rule on the media host. File names never change, so this is safe.
  • Video posters are copied from Cloudflare Stream to the media host. The light video embed shows the poster and loads the player only when someone presses play.
  • Faster first image: pages send a Link: preconnect header for the media host (as a 103 Early Hint too), and the first three thumbnails in post lists load right away instead of lazily.
  • Uploads go through the site (EmDash's admin blocks direct browser uploads), in small parts within Workers' limits.

Visibility

  • Cloudflare usage card and widget:
    • this site's and the account's D1 and Workers usage;
    • the plan, detected from account entitlements;
    • the estimated bill;
    • cache warming's share, estimated from Workers Logs.
  • Read-only token: USAGE_API_TOKEN, set on all 7 Workers.

Cloudflare settings

Account

  • Workers Paid ($5/month). It covers all seven sites and their D1 databases, R2 and Workers Logs. Every zone is on the Free plan.
  • Workers Logs on for every site. Observability usage stays well inside the included amount.
  • Smart Placement on the Workers, so they run near their database.
  • A SELF service binding on the Workers that need to call their own site (link checks, cache warming), because a Worker can't fetch its own custom domain.

On all 7 zones

  • Smart Tiered Cache on. A data center that hasn't cached an image asks a nearby Cloudflare cache instead of R2.
  • Early Hints on, so the media host preconnect reaches browsers before the page does.
  • Custom security rule "Coywolf: challenge outdated browser user agents (scrapers)":
    • Managed Challenge for non-verified-bot requests claiming Chrome older than 140 or iOS 15 and earlier.
    • Scoped to the EmDash site's hostname only.
    • Scrapers like these were coywolf.com's largest single source of CPU time.

Per zone

  • Image Transformations on, with the media host's R2 custom domain and the pack's two URL rewrite rules.
  • coywolf.com: custom rule "Block WordPress probes" (.php, /wp-admin, /wp-json…), so leftover WordPress URLs never reach the Worker.
  • get.essential.support and recollect.fyi: verified AI training crawlers blocked on the marketing sites only, not the PWAs.
  • coywolf.com and others: AI training set to "disallow" (robots.txt) rather than "block". Bot Fight Mode and crawler protection stay on.

Report this note

Reports go to Recollect for review. The person who shared this note is not told who reported it.

Reason

Required: 20 to 500 characters.

0 / 500