1const o="ai-price-war-july-2026",r="The AI price war went nuclear this week: DeepSeek V4 Flash at $0.14/M tokens and GPT-5.6 Luna down 80%, in the same 24 hours",s="OpenAI cut GPT-5.6 Luna 80% on July 30; DeepSeek shipped V4 Flash to public beta July 31 from $0.14/M tokens. We track 45 AI providers. Here's what changed, with numbers.",i="2026-07-31",n="2026-08-23",l="Dracon Research Team",h="Dracon Editorial",c="ai-providers",d=["ai","pricing","deepseek","openai","price-war"];const u=[{label:"ai-providers-catalog.json: 45 providers, verified 2026-08-16",href:"/ai-hub/providers"},{label:"OpenAI GPT-5.6 Luna pricing announcement (July 30, 2026), provider docs",href:"https://openai.com/api/pricing"},{label:"DeepSeek V4 Flash 0731 public beta release notes (July 31, 2026)",href:"https://api-docs.deepseek.com/"},{label:"Third-party price tracker cross-check (Artificial Analysis), July 31, 2026 snapshot",href:"https://artificialanalysis.ai/models"}],p=[{type:"p",text:"If you blinked this week you missed the cheapest frontier-class AI has ever been. On July 30, OpenAI cut GPT-5.6 Luna prices by 80%. Less than a day later, DeepSeek's V4 Flash graduated from preview to an official public beta (the '0731' build) at prices starting from $0.14 per million input tokens. We maintain a structured catalog of [45 AI providers](/ai-hub/providers) with real prices, free tiers, and rate limits, and weeks like this are exactly why. This article is not a rewrite of press releases. It is what changed in numbers, where each number came from, how we re-verified it against our catalog, and what it means if you actually pay for tokens. Prices below are per million tokens (input / output) unless noted."},{type:"h2",text:"What OpenAI announced on July 30, with provenance"},{type:"p",text:"GPT-5.6 Luna dropped from $1.00 to $0.20 per million input tokens and from $6.00 to $1.20 per million output tokens: an 80% cut on both sides, effective immediately. GPT-5.6 Terra got a smaller 20% cut, and the flagship Sol kept its pricing but gained a new Fast mode. That is the OpenAI announcement itself (July 30, 2026). Per reporting around the announcement, Sol autonomously rewrote parts of its own production inference stack (GPU kernels and speculative-decoding paths), and the efficiency gains funded the price drop. We flag that last sentence as reporting, not as a provider price fact, because it is a narrative about how the cut became possible rather than a number you can invoice against. What is invoiceable is the table in [our provider directory](/ai-hub/providers): the Luna entry was updated July 30 to $0.20 / $1.20, with the long-context surcharge preserved. If you push long contexts, prompts over ~272K input tokens bill at 2x input and 1.5x output, and cache writes run 1.25x the uncached rate. Third-party trackers listed the same new Luna price within hours, which is our cross-check that we are not looking at a cached page."},{type:"h2",text:"What DeepSeek shipped on July 31, and what 'from $0.14' means"},{type:"p",text:"DeepSeek V4 Flash is now an official public-beta release. The architecture is unchanged from the preview. This is DeepSeek's efficie
1ncy model, not a new flagship, but the pricing is the point. DeepSeek's own docs for the 0731 build list the entry price as $0.14 input / $0.28 output per million tokens, and third-party trackers we cross-checked July 31 show the same floor. That undercuts even the newly-cut Luna on the input side by $0.06/M. One thing to watch, because it will bite you if you miss it: DeepSeek has announced a peak-hours pricing policy that is not yet active as of July 31. The docs describe higher peak pricing in a future window, but no active surcharge is in effect today. If you build on V4 Flash, build with that in mind: pin a price alert or keep a fallback model in your router. We've added V4 Flash to [our DeepSeek provider entry](/ai-hub/providers/deepseek) today, and the [free-tier hub](/ai-hub/free) notes where DeepSeek's free lane sits, because at $0.14/M the free tier versus paid math is closer than ever."},{type:"table",caption:"The last three weeks of the price war, as tracked in our catalog and public announcements. Prices are per million tokens (input/output).",headers:["Date","Provider","Move","New price"],rows:[["Jul 9â10","Meta","Muse Spark 1.1: Meta's first paid model API, then the cheapest paid frontier","$1.25 / $4.25"],["Jul 12","OpenAI","GPT-5.6 Sol usage limits temporarily relaxed","â"],["Jul 30","OpenAI","GPT-5.6 Luna cut 80%; Terra cut 20%; Sol gains Fast mode","$0.20 / $1.20 (Luna)"],["Jul 31","DeepSeek","V4 Flash '0731' official public beta","from $0.14 / $0.28"]]},{type:"h2",text:"The math: what 80% actually saves you"},{type:"p",text:"Percentages sound dramatic; token bills are arithmetic. Take a real workload. A small app that processes 5 million input tokens and 2 million output tokens per day paid $17/day for Luna at the old $1/$6. At the new $0.20/$1.20 it pays $3.40/day. That is $13.60/day left on the table, or about $408/month. Even a light personal workload of 1M input / 0.5M output per month goes from $4/month to $0.80/month. The table below is not a forecast. It is today's catalog price times your volume. If you pinned Luna at $1/$6 in a budget spreadsheet, your projections are now wrong by 5x in your favor. Re-run them, and re-run any per-request cost you baked into pricing for your own users."},{type:"table",caption:"Example monthly bills on Luna before and after the July 30 cut. V4 Flash shown at its entry price, before any future peak surcharge.",headers:["Monthly volume (in / out)","Luna at old $1 / $6","Luna at new $0.20 / $1.20","DeepSeek V4 Flash at $0.14 / $0.28"],rows:[["1M / 0.5M (heavy personal chat)","$4.00","$0.80","$0.28"],["5M / 2M (small app, ~170K in / 67K out per day)","$17.00","$3.40","$1.26"],["50M / 20M (growing product)","$170.00","$34.00","$12.60"],["500M / 200M (scale)","$1,700.00","$340.00","$126.00"]]},{type:"h2",text:"How we track this so you don't have to trust a blog post"},{type:"p",text:"We keep [the provider directory](/ai-hub/providers) as data, not as a blog post someone wrote once. Each of the 45 entries carries a verified_at timestamp, source_url, and structured fields for free-tier terms, rate limits, and subscription plans. For this story we touched two entries. OpenAI: source_url is the provider pricing page, verified_at set to 2026-07-30, payg_rates updated to Luna $0.20/$1.20 and Terra's 20% cut, rate-limit note preserved for the 272K-token long-context surcharge. DeepSeek: added V4 Flash to models_available, verified_at 2026-07-31, free_tier note unchanged, rate_limits note updated to mention the not-yet-active peak policy. Third-party trackers are our second pair of eyes, not our source of truth. When Artificial Analysis and our catalog agree within hours, we publish. When they disagree, we re-fetch the provider page and hold the post. That discipline is the whole point of the [free-tier hub](/ai-hub/free) and the [plans table](/ai-hub/plans): the article is a snapshot, the catalog is live. Methodology limits: provider pages can cache, exchange rates can confuse, and 'from $0.14' in DeepSeek's docs is a floor tied to cache-hit and context specifics. Your effective price will be a little higher whenever you miss the cache. We note that explicitly here so you do not budget on the floor alone."},{type:"h2",text:"What to do this week if you pay for tokens"},{type:"ul",items:["Re-run your unit economics. Any price you derived from Lun
1a $1/$6 is stale. Update the per-request cost in your pricing page, your [pricing model](/pricing) docs, and your customer-facing estimates before you undercharge yourself for another month.","Don't re-platform on one day's floor. V4 Flash at $0.14 is the cheapest input price we have ever recorded, but 'from $0.14' plus a dormant peak policy means the number has an asterisk. Use Luna at $0.20 as your planning anchor and treat V4 Flash as upside.","Keep two keys warm. This is the exact week where bring-your-own-key pays off: hold both OpenAI and DeepSeek keys, route chat and summarization to V4 Flash, keep reasoning on Luna or Sol, and switch in config rather than in code. Our own [/chat](/chat) runs entirely in your browser with your keys for exactly this test: put DeepSeek in one column and Luna in the other and compare them on your actual prompts today, not on someone's benchmark.","Rate limits are the new price. At $0.14/M, a free tier with 1,000 requests/day is worth more than a 10% cheaper token. Check the [free-tier comparison](/ai-hub/free) before you chase another $0.02 of price.","Watch the floor, not the flagship. Sol's new Fast mode is a speed story more than a price story; the market-moving numbers this week were on the efficiency models, not the frontier one."]},{type:"p",text:"If you'd rather not re-platform every time the market sneezes, this is the case for the tooling shape we run ourselves: keep accounts at multiple providers, and switch models per task rather than per quarter. Our [plans table](/ai-hub/plans) shows what a paid commitment looks like once you outgrow free tiers, and the [provider directory](/ai-hub/providers) carries the live price for every entry on this page. When prices change again (and they will), the directory reflects it first. That is not a slogan; it is how the catalog is built: capture, cross-check, timestamp, publish."},{type:"callout",text:"Provenance as of 2026-07-31, updated 2026-08-23: OpenAI Luna new price ($0.20/$1.20) from OpenAI's July 30 pricing announcement and provider pricing page; DeepSeek V4 Flash $0.14/$0.28 entry price from DeepSeek's 0731 public-beta docs and confirmed against a third-party price tracker (Artificial Analysis) July 31. Catalog entries re-verified July 30â31. Prices are per million tokens; long-context and cache multipliers noted above apply."}],m={text:"The price war isn't over. Provider pages are updated as cuts land, so the comparison stays honest after publication.",links:[{label:"Current provider pricing",href:"/ai-hub/providers"},{label:"Discuss in Discord",href:"https://discord.gg/gAjfKwRbtQ?ref=blog&utm_source=article&utm_medium=cta",external:!0}]},y={slug:o,title:r,description:s,date:i,updatedAt:n,author:l,reviewedBy:h,family:c,tags:d,affiliateDisclosure:!1,sources:u,sections:p,cta:m},f="free-ai-apis-ranked",g="22 of the 45 AI providers we track have a free tier. Only 7 are actually useful.",b="We maintain rate-limit data on 45 AI providers. Most 'free tiers' are demo taps. These 7 hold up for real work, with actual limits and how to mix them via BYOK.",w="2026-07-31",v="2026-08-23",k="Dracon Research Team",x="Dracon Editorial",$="ai-providers",T=["ai","free-tier","apis","byok"],A=!1,S=[{label:"ai-providers-catalog.json: 45 providers, verified 2026-08-16",href:"/ai-hub/providers"},{label:"Provider rate-limit and free-tier fields, methodology note in catalog",href:"/ai-hub/free"}],P=[{type:"p",text:"Every AI provider's landing page says 'free tier'. What they don't say is whether you can do anything real with it. We maintain a [structured catalog of 45 providers](/ai-hub/providers) (prices, rate limits, free-tier terms, the works), and one of the fields we track is whether a free tier is *meaningful*: usable for genuine day-to-day work, not a 100-credit demo tap that dies the moment you point a script at it. As of our 2026-08-16 verification, 22 providers list a free tier. Seven pass the meaningful bar. This article shows the list, the real limits, exactly how we decide 'meaningful', what we exclude and why, and how to actually use these tiers without building a fragile dependency on any single one. If you just want the live filter, the [free-tier hub](/ai-
1hub/free) is the maintained view of the same data; this post is the snapshot plus the methodology you can audit."},{type:"h2",text:"Methodology: what 'meaningful' means and how we test it"},{type:"p",text:"We get asked whether 'meaningful' is a vibe. It is not. It is a structured boolean in the catalog (free_tier_meaningful) with a free_tier_meaningful_rationale string per provider. The rule is: can a single developer do sustained real work for at least a month on the published free limits without hitting a hard paywall, buying a plan, or hitting a one-time credit that expires? That means a recurring allowance (requests per minute, per hour, per day, or per month) that refreshes, not a pile of trial credits that evaporates after a weekend of use. We also require that the free tier be documented on the provider's own pricing or docs page at verification time, not just in a launch tweet. We captured 45 provider pages in August 2026, stored the advertised limit verbatim in rate_limits and free_tier_summary, set free_tier=true only where the provider claims a free lane, and then set free_tier_meaningful=true only where the limit is a recurring allowance large enough for continuous use. A free lane that is free only inside a consumer chat product (e.g., Mistral Le Chat) can still count as meaningful if its allowance is a daily habit, but we note that the API is a separate paid lane."},{type:"p",text:"Limits of this method. We count what providers publish. If a provider advertises no hard numbers (DeepSeek's free lane, GitHub Models' free tier), we leave rate_limits empty and exclude the provider from the rate-limit table rather than inventing a number. Our honest-absence rule. If a provider rotates its free-model set (OpenRouter, OpenCode, NVIDIA NIM, Cline), we record the rotation note in rate_limits and link the [provider entry](/ai-hub/providers) so you can check today's list. And 'meaningful' is an editorial classification, not a guarantee of service. A provider can change its limits tomorrow. The [free-tier hub](/ai-hub/free) carries the current classification for all 22, and the [plans table](/ai-hub/plans) shows what each lane costs once it stops being free."},{type:"h2",text:"The 7 that hold up"},{type:"table",caption:"Free tiers we classify as 'meaningful' in the catalog, August 2026 (verified 2026-08-16). Terms rotate. The linked provider pages carry the current state.",headers:["Provider","What you actually get","Why it counts as meaningful"],rows:[["[OpenRouter](/ai-hub/providers/openrouter)","50 requests/day across free-tier models with no card; adding $10 in PAYG credits unlocks 1,000/day of free models","Recurring daily allowance, no card for the base tier, and the model pool is genuinely usable for scripting"],["[Google AI Studio](/ai-hub/providers/google-ai-studio)","Hosted free endpoint with a rotating proprietary model lineup; free daily quota","Daily quota that refreshes: you can do real work every day, not just once"],["[NVIDIA NIM](/ai-hub/providers/nvidia-nim)","~40 requests/min, no daily cap, no credit card; featured models rotate","Per-minute rate with no daily ceiling: the only tier on this list with that shape"],["[Mistral (Le Chat Free)](/ai-hub/providers/mistral)","Base-tier allowances on messages, web search, libraries, and image generation","Daily-driver chat allowance inside a consumer product; not an API trial"],["[OpenCode](/ai-hub/providers/opencode)","5 free models on OpenCode Zen for a limited time; per-model limits rotate","Structured free access to multiple models in one account, even though the set is promotional"],["[Cline](/ai-hub/providers/cline)","Open-source; the Cline provider offers hosted free models with per-model limits","Free models inside the editor with a refresh. Fits the 'continuous work' rule"],["[Kilo](/ai-hub/providers/kilo-ai)","Free plan with sign-in; 200 requests/hour, BYOK beyond it","Hourly refresh that survives a full workday of coding assistance"]]},{type:"h2",text:"Why these 7 and not the other 15"},{type:"p",text:"The other 15 free tiers are not scams. They are just scoped differently. Four patterns keep appearing. One-time grants: Hyperbolic hands you $1, Alibaba gives 1M free tokens per model for 90 days (plus 70M+ tokens for new accounts), BytePlus ModelArk offers 500K free tokens per LLM and 2M for vision models, and OVHcloud's $200 public-cloud trial credit can be pointed at AI Endpoints. These are excellent for benchmarking a provider you might pay later, but they are not recurring. Rate-limited to evaluation: SiliconFlow gives 100 requests/day plus $1 in credit, Cline-style per-model limits that rotate. Useful for testing a specific model, not for a daily driver. Consumer-c
1hat-only: Le Chat counts, but many 'free' lanes elsewhere are consumer apps with no API, so they do not help a script. And metering that is too small: Hugging Face's free inference allowance is ~$0.10/month ($2 on PRO), the smallest we track, demo-only by design. We track all 22 in the directory regardless, because 'evaluation-only' is still valuable when you are evaluating. Just don't architect a side project to depend on an allowance that expires."},{type:"p",text:"Two edge cases we handle explicitly. First, providers that list a free tier but publish no hard numbers (GitHub Models, DeepSeek) are left out of the ranked table rather than ranked on vibes. You will find them on the [free-tier hub](/ai-hub/free) with a note that says 'no hard numbers published', not a guessed number. Second, free tiers that require a credit card (Mistral, OpenCode) still count if the recurring allowance is real; we store requires_credit_card as a separate boolean so you can filter by it. The [provider directory](/ai-hub/providers) lets you sort by both fields."},{type:"h2",text:"The pattern that actually works: mix them"},{type:"p",text:"No single free tier is a strategy. The limits differ per provider precisely so you will eventually pay one of them. The working pattern in 2026 is bring-your-own-key: hold free accounts at several of these, and route tasks to whichever has headroom. In practice that looks like: drafts on OpenRouter's 50 free requests/day, fast interactive pulls on NVIDIA NIM at 40 requests/min, long-context reasoning on Google AI Studio's daily quota, and editor work inside Kilo or Cline. When one lane throttles, you switch in config, not in architecture. That's why our [chat page](/chat) is BYOK and browser-direct: your keys live in your own vault, the page calls providers straight from your browser (we relay nothing; you can watch it in devtools), and a split view lets you run the same prompt through two providers side by side. The [pricing page](/pricing) tracks what happens when you outgrow all of them, because free tiers are a runway, not a destination."},{type:"p",text:"A concrete setup that has survived months of real use: put OpenRouter, Google AI Studio, and NVIDIA NIM in your free account trio. OpenRouter covers the scratch work, Google covers the heavy reasoning, NVIDIA covers the bursty interactive loop. Add Kilo's [200 requests/hour lane](/ai-hub/providers/kilo-ai) inside your editor and you have four independent free quotas before you spend a dollar. When you do spend, the [plans table](/ai-hub/plans) shows the cheapest paid step for each provider without the marketing gloss. Free tiers stop being a trap when you can leave any of them in one click. And that portability is more valuable than any single allowance."},{type:"h2",text:"Limitations and when to re-check"},{type:"p",text:"Provider pages cache, model sets rotate, and rate limits can change without a blog post. A '50 requests/day' tomorrow can be '25' or can gain a new model that makes the old limit irrelevant. We re-verify the catalog monthly and timestamp each entry; the free-tier hub reflects the live value. This article is accurate as of the 2026-08-16 verification, editorially refreshed 2026-08-23. If a number here disagrees with the provider page, the provider page is right. And we want the correction on the [provider directory](/ai-hub/providers) bug report."},{type:"callout",text:"Methodology: 'meaningful' is our editorial classification in the catalog (free_tier_meaningful boolean) based on whether sustained real use for at least a month is plausible under the published recurring limits, not on marketing copy. Captured August 2026 across 45 providers; re-checked monthly. Provider pages always carry the newest terms; this article is a dated snapshot."}],I={text:"Free tiers shift monthly. Providers change terms without announcement. The live catalog is kept current; this article is a dated snapshot.",links:[{label:"Live free-tier catalog",href:"/ai-hub/free"},{label:"Compare notes in Discord",href:"https://discord.gg/gAjfKwRbtQ?ref=blog&utm_source=article&utm_medium=cta",external:!0}]},D={slug:f,title:g,description:b,date:w,updatedAt:v,author:k,reviewedBy:x,family:$,tags:T,affiliateDisclosure:A,sources:S,sections:P,cta:I},C="dracon-arcade-state",O="18 games in the pipeline, 1 playable today: an honest state of the Dracon arca
1de",B="Our games catalog tracks 18 projects from released to experimental. What each status means, what's playable now, and why we publish the pipeline honestly.",M="2026-07-31",E="2026-08-23",N="Dracon Games Team",R="Dracon Editorial",W="games",F=["games","dev-diary","arcade"],L=!1,j=[{label:"games-catalog.json: 18 entries (1 released, 14 wip, 3 experimental, updated 2026-07-29)",href:"/games"},{label:"OVH bucket: live playable builds at /games/{slug}/{version}/",href:"/games/one-mil-girls/play"},{label:"Blog: ship notes and field notes",href:"/blog"}],H=[{type:"p",text:"Most indie game pages show you a wall of logos and let you discover the emptiness yourself. We would rather show you the pipeline. Our [games catalog](/games) is a data file with 18 entries and an honest status field. This article is just what the data says today, plus why we run it this way. If you came looking for a wall of 'Play Now' buttons, you will find one honest one and seventeen notes about what it takes to earn the others. That is the point."},{type:"h2",text:"The status ladder, defined"},{type:"ul",items:["Released: a real game you can open and play to a win/lose state right now, hosted and smoking. Today that is exactly one: [One Million Girlfriends](/games/one-mil-girls/play) at 0.2.15, a branching anime visual novel with 5 heroines, 5 days, and 10 endings.","WIP: actively being built. Fourteen live here. Five are hosted on the OVH bucket and playable via iframe but still gated by a quality call: [Junk Runner](/games/junk-runner/play) at 0.8.0, [Darklord](/games/darklord/play) at 1.0.0, [Hellhunter](/games/hellhunter/play) at 1.0.0, [Neonbreak](/games/neonbreak/play) at 0.10.4, and [Polis](/games/polis/play) at 1.0.0. Nine more WIP have no hosted build yet: Hegemon, the three engine templates (canvas2d 0.0.1, isometric 0.0.1, birds-eye 0.1.0), Doomtap, Football Forever, Hooked Forever, Forever Mulligan, and Forever Feast.","Experimental: a real concept with real source, queued behind the active work, not yet on the WIP ladder's critical path. Three: Capture Anime Girls (0.1.0), Deathrun (2.0.0), and Endless Tower Defense (0.1.0). They build, they run locally, they are not yet candidates for bucket publish.","What we no longer use: the old four-way of playable/demo/WIP/candidate. That vocabulary was honest at 16 games; at 18 we simplified to the three you see above because demo, candidate, and placeholder were really just shades of WIP and they confused more than they clarified. The catalog's status field is now released | wip | experimental, and the hosted_path + play_url fields tell you whether a WIP is bucket-hosted."]},{type:"p",text:"A word on canLaunch, the predicate that actually gates the Play button. A game is launchable when its catalog entry has a hosted_path, a play_url, an iframe_src that names index.html explicitly, and screenshots at games/{slug}/{version}/screenshots/. The SvelteKit games additionally require a built base path (JR_BASE, HH_BASE, NB_BASE) so the client router can match. If canLaunch is false, the [game page](/games) shows the concept, art, and status but no iframe. No dead link, no 403, no sitemap entry that promises a game that is not there."},{type:"h2",text:"The catalog today, honestly"},{type:"table",caption:"Live counts from web/games/libs/data/games-catalog.json (18 entries, updated 2026-07-29).",headers:["Status","Count","Who lives there","Hosted + playable?"],rows:[["Released","1","One Million Girlfriends 0.2.15","yes: [play](/games/one-mil-girls/play), OVH bucket at games/one-mil-girls/0.2.15/"],["WIP: hosted (bucket)","5","Junk Runner 0.8.0, Darklord 1.0.0, Hellhunter 1.0.0, Neonbreak 0.10.4, Polis 1.0.0","yes, but gated: iframe renders, catalog still WIP by quality call"],["WIP: not yet hosted","9","Hegemon, template-canvas2d 0.0.1, template-isometric 0.0.1, template-birds-eye 0.1.0, Doomtap 1.0.0, Football Forever 0.1.0, Hooked Forever 0.1.0, Forever Mulligan 0.1.0, Forever Feast 0.1.0","no: local builds only, no play_url"],["Experimental","3","Capture Anime Girls 0.1.0, Deathrun 2.0.0, Endless Tower Defense 0.1.0","no: concepts with source, not yet publish candidates"],["Total","18","Every entry desktop-only, DRM-free, no account","6 have a live iframe_src, 1 is released"]]},{type:"p",text:"That table is the whole honesty pitch in one place. Five of the WIP games already pass the pipeline's live smoke: they are on the bucket, their iframe_src names index.html explicitly (the bucket serves n
1o directory index, so /games/{slug}/{version}/ is a 403), every object has a per-object public-read ACL (OVH does not implement PutBucketPolicy), and a headless Chromium probe boots each one with zero responses at 400 or above. We wrote up that pipeline in [how a game ships to the Dracon arcade](/blog/dracon-arcade-pipeline) and the bug it surfaced in [three games, one bug](/blog/three-games-one-bug). The catalog still says WIP for those five because flipping status from WIP to released is a quality call a human makes after playing the game, not a fact the pipeline asserts. The pipeline is the replay; the catalog is the scoreboard."},{type:"h2",text:"Why publish the honest version"},{type:"p",text:"Two reasons, one practical and one cultural. Practically, we learned that thin pages do not just fail to rank. They get flagged. A game page with no game behind it is exactly the kind of empty URL that poisons a domain's standing. When a game drops below launchable, its play page comes out of the sitemap the same day, which is why you will not find dead links in [the arcade](/games) and why the sitemap at /games/sitemap.xml only lists slugs that can actually boot. We would rather have six honest play URLs than eighteen hopeful ones."},{type:"p",text:"Culturally, our whole platform bet is that curation beats volume. A directory that says 'nine WIP not yet hosted, three experimental, not ready' earns the right to say 'this one is released' and be believed. The alternative (a glossy grid where every tile says Play Now and half the tiles 403) trains players to distrust every tile, including the good ones. We built the Dracon music library the same way: 250 cooks, each with its recipe on file, so you can judge before you listen. The arcade is the same idea with a stricter gate, because a 5-hour visual novel that cannot be finished is worse than a 3-minute song you skip."},{type:"h2",text:"What 'WIP to released' means in practice"},{type:"p",text:"Every game in the catalog is desktop-only (target_platform desktop in the catalog JSON, enforced by the hub), built on our own engines (the birds-eye and isometric demos double as engine testbeds) and moves up the ladder only when it clears a quality floor: a playable loop, a real win/lose, no placeholder art pretending to be a game, and a clean probe (one navigation, zero console errors, zero failing assets). The standing publish rules after the July 31 run are now in the runbook: the three SvelteKit games must be built with their base-path env vars before every publish (JR_BASE=/games/junk-runner/{version} and siblings), Neonbreak's postbuild passes --absolute-assets, and screenshots are staged into the build before publishing so they land at games/{slug}/{version}/screenshots/ with alts. When a WIP clears that floor, the catalog flip changes status, version, iframe_src, play_url, asset_base_url, screenshots, and updated_at in one JSON edit, the hub rebuilds (adapter-static, no service to restart), and the [changelog](/blog) records the move. This article regenerates when the catalog does, so the numbers above are a snapshot, not a monument."},{type:"p",text:"Next up the ladder are the five hosted WIP, one quality gate at a time. Neonbreak, Darklord, and Polis were the cleanest booting in the July 31 probe; Junk Runner and Hellhunter had the SvelteKit reload loop that [three games, one bug](/blog/three-games-one-bug) dissects, now fixed. Behind them are Hegemon (our strategy epic and the project's longest-running development saga) and Endless Tower Defense, both WIP/experimental but with real source under web/games/wip/ and web/games/released/. If you want to watch the ladder move, the [changelog](/blog) is the feed; if you want to play today, [One Million Girlfriends](/games/one-mil-girls/play) is the honest answer, and the five hosted WIP are the honest 'almost'."},{type:"callout",text:"Snapshot date: 2026-08-23: 1 released, 5 WIP hosted on the OVH bucket, 9 WIP not yet hosted, 3 experimental, 18 total. Live counts are always on /games; hosted builds live at https://dracon-master.s3.uk.io.cloud.ovh.net/games/{slug}/{version}
1/index.html. This article is regenerated whenever games-catalog.json changes, so the table above is current as of its updatedAt."}],G={slug:C,title:O,description:B,date:M,updatedAt:E,author:N,reviewedBy:R,family:W,tags:F,affiliateDisclosure:L,sources:j,sections:H},q="focus-music-library",U="2,500 tracks, 250 mixes, 166 mood tags: we built a free focus-music library and kept the receipts",V="The Dracon music library is 2,500 generated tracks in 250 curated 'cooks', every recipe kept. The data behind it and how to use it.",z="2026-07-31",_="2026-08-23",K="Dracon Music Team",J="Dracon Editorial",Y="music",Z=["music","focus","ambient","library"],X=!1,Q=[{label:"cookbook.json: 250 cooks, 2,500 tracks (updatedAt 2026-08-23T17:45:24.952Z)",href:"/music"},{label:"Dracon music library: browse all cooks",href:"/music/library"},{label:"Dracon cooks index: 250 recipes kept",href:"/music/cooks"}],ee=JSON.parse(`[{"type":"p","text":"Focus music is a solved problem if you like handing your attention to an algorithm that also sells ads. We wanted the opposite: a library where every track exists because someone wrote a recipe for it, and the recipe is kept. The [Dracon music library](/music) is 2,500 tracks organized into 250 curated collections we call cooks. And because the whole thing is a data file, we can tell you exactly what is in it. No hidden catalog, no rented mood playlists, no eight-hour piano loop pretending to be new every night. Each cook is 10 tracks at a specific headspace, and the 2,500-track count is 250 à 10, not an estimate."},{"type":"p","text":"Update (2026-08-23): this article was first published 2026-07-31 against 100 cooks and 1,000 tracks with 82 mood tags; cookbook.json now holds 250 cooks and 2,500 tracks with 166 distinct mood tags (updatedAt 2026-08-23T17:45:24.952Z). Headline numbers below reflect the current 250; original figures are noted inline where the catalog has moved so the early analysis remains reproducible."},{"type":"h2","text":"What's actually in the library"},{"type":"table","caption":"Counts from the live cookbook data, August 2026 (250 cooks, 2,500 tracks).","headers":["Metric","Value","What it means"],"rows":[["Tracks","2,500","250 cooks à 10 tracks, every audio key exists under audio/{cookId}/"],["Cooks (curated collections)","250","each with a written prompt, genre, BPM, key, structure, and mood tags"],["Distinct mood tags","166","from ambient and dreamy to intense, mechanical, and n
1octurnal, up from 82 at 100 cooks"],["Instrumental cooks","89 (35.6%)","no vocal at all; the rest split into gibberish-anime (63), English (51), English-lyrics (33), Japanese (8)"],["Distinct genre labels","230","largest cluster is futurecore at 5 cooks; almost one genre per cook by design"],["Most common key","F minor (30 cooks)","followed by E minor (26), A minor (24), D minor (22). No one planned it"],["Largest BPM band","151-240 BPM (63 cooks)","the fast end now outweighs the slow; the focus shelf lives at 40-100 BPM"]]},{"type":"p","text":"The cooks have names like [Late Night Lo-Fi](/music/cook/late-night-lo-fi), [Deep Focus Pulse](/music/cook/deep-focus-pulse), Cloud Garden, Neon Drive, [Iron Cathedral](/music/cook/iron-cathedral), [Stratosphere](/music/cook/stratosphere), [Vesper Hall](/music/cook/vesper-hall), and [Rain Diary](/music/cook/rain-diary). Each one a 10-track run at a specific headspace. About one third of the library is fully instrumental, which is the third most people leave on while working, and another quarter speaks in gibberish-anime or invented phonetics so you get a voice with no words to follow. The slowest cook is [Held Note, For Hours](/music/cook/drone-58) at no tempo at all, then Stratosphere at 40 BPM; the fastest push past 200. The [library view](/music/library) shows all 250 at once with cover art, BPM, key, and mood chips, and the [cooks index](/music/cooks) is the denser, filter-friendly version of the same data if you want to jump by tempo or tag rather than cover."},{"type":"h2","text":"The receipts: every track keeps its recipe"}
1,{"type":"p","text":"Each of the 2,500 tracks was generated with its full parameters stored. A real example from the library: the opening track of Late Night Lo-Fi: 'Lo-fi hip hop instrumental, mellow late-night study vibe, dusty vinyl samples, warm rhodes piano chords, muted thumb bass, soft brushed drum loops with vinyl crackle, tape saturation, jazzy chords moving slowly, intimate headphone mix' at 75 BPM in F minor, structure loop-2bars-loop-2bars, instrumental true. That is not marketing copy; it is the actual generation record written to cookbook.json as generationParams. It means the library is auditable and reproducible. When we say 'dark ambient for deep work', we can show you the recipes behind that claim, and you can read the prompt that made the snare sit behind the rhodes instead of on top of it."},{"type":"p","text":"We use the recipe in three places. First, before any audio is generated, a human writes the prompt, genre, mood array, instrument list, tempo label, BPM, key, and structure for the cook. The 10 track titles are drafted against that recipe so the titles match the headspace, not the other way around. Second, during generation, web/music/scripts/build-cookbook.mjs calls the music model with those fields as arguments (--prompt, --genre, --mood, --instruments, --bpm, --key, --structure, --instrumental), and stores the returned audioKey and coverKey alongside the recipe that produced them. Third, after generation, the player reads the same JSON: the cook page at [music/cook/{slug}](/music/cook/late-night-lo-fi) renders the prompt, BPM, key, mood chips, and the 10 tracks from the same object the build script wrote. There is no second database, no CMS copy, no drift. If a cook says 75 BPM in F minor, the JSON says so and the player shows it."},{"type":"h2","text":"The 10-track rule, and why it matters"},{"type":"p","text":"Every cook holds exactly 10 tracks. Not 9, not 14: at 100 cooks the minimum, maximum, and average were all 10, and at 250 they still are. We enforce this in build-cookbook.mjs: a cook is only considered complete when its 10 audio keys exist under web/music/out/audio/{cookId}/ and its 10 song entries are written to the songs array. The player expects 10. The cover art expects 10. The search index expects 10. That constraint is why we can say 2,500 tracks without hand-waving: count the cooks (250), multiply by 10, and you match the 2,500 song entries in cookbook.json. It also makes listening predictable: a cook is 35 to 55 minutes depending on track lengths (typically 90-130 seconds per track), which is a work block, a commute, or a wind-down, and you learn to trust that a cook will not end after three tracks at the point you were settling in."},{"type":"p","text":"The other half of the rule is genre spread. At 250 cooks there are 230 distinct genre labels (almost one per cook), with the biggest cluster at 5 (futurecore) and most clusters at 1 or 2. Dark ambient shows up 3 times (including [Iron Cathedral](/music/cook/iron-cathedral) and [Catacombs Lit Only by Phone](/music/cook/catacombs-59)), lo-fi hip hop twice, synthwave twice, metalcore twice, and so on. We keep it that way on purpose. When a new cook is commissioned we check the genre frequency table and brief against uncovered space, so the library grows outward rather than repeating its own center. That is why even cooks that share a tempo can feel completely different: [Deep Focus Pulse](/music/cook/deep-focus-pulse) (minimal ambient at 60 BPM, C minor) and [Vesper Hall](/music/cook/vesper-hall) (chamber classical at 60 BPM, D minor) sit at the same BPM and have no genre overlap, so one is a pulse that refuses to develop and the other is a cello that cannot help but develop."},{"type":"h2","text":"How curation actually works"},{"type":"p","text":"A cook starts as a one-paragraph brief. Example brief for Stratosphere: 'Space ambient, long evolving synthesizer pads, deep sub-bass rumbles, granular texture from field recordings, no rhythm, 40 BPM, E minor, sacred + dreamy + ambient.' The brief is turned into a recipe record with 8-12 instrument tags, a tempo label (slow, very slow, moderate, fast, etc.), and a structure tag like loop-2bars-loop-2bars or intro-verse-chorus. The writer then drafts 10 titles and a one-sentence description for the cook ('The view from 80km up') before any audio exists, so the cook has an identity to live up to. Only then does the generation loop run, one track at a time, with the same prompt and genre plus a title-specific variation, and the result is auditioned. If a track leans too busy, the prompt is narrowed and it is regenerated; the final audioKey overwrites the draft. The cover prompt is written in parallel: a single glowing amber candle in a black void for Late Night Lo-Fi, an empty concert hall at dusk for Vesper Hall, and generated as a 1:1 square, scored, and kept as coverKey."},{"type":"p","text":"That process is slow, which is why the library took months to reach 250 and why we do not add cooks faster than we can audition them. The alternative (generating 10,000 tracks against random prompts and clustering afterward) would be cheaper and would produce a larger catalog faster, but it would not produce a library you can reason about. Our bet is that a listener who can read the recipe and decide 'this 40 BPM E-minor space ambient with no rhythm is exactly what my evening needs' will keep listening longer than a listener who is told 'we think you will like this' b
1y a recommender. The numbers suggest that bet is paying: the slow end (40-100 BPM, instrumental) has grown from 23 cooks at 100 to 31 cooks at 250 because listeners kept reaching for it, so we kept commissioning there even as the median tempo rose to 130."},{"type":"h2","text":"How to use it"},{"type":"p","text":"Open the [player](/music), pick a cook that matches the headspace you need, and press play. No account, no ads, no algorithm deciding you have had enough focus for one day. For work, start with the three cooks that actually carry the focus mood: [Late Night Lo-Fi](/music/cook/late-night-lo-fi) for a warm room, [Deep Focus Pulse](/music/cook/deep-focus-pulse) for a clocklike 60 BPM pulse, [Pixel Cathedral](/music/cook/pixel-cathedral) if you focus better with a little joy at 132 BPM. Or filter the [library view](/music/library) for instrumental and BPM at or under 100 (31 cooks) and try [Stratosphere](/music/cook/stratosphere) at 40 BPM, [Iron Cathedral](/music/cook/iron-cathedral) at 50, or [Rain Diary](/music/cook/rain-diary) at 70. For wind-down, the same slow shelf is the sleep shelf we use ourselves; see our sleep picks for seven honestly described candidates from that shelf. The [cooks index](/music/cooks) lets you jump straight to any of the 250 by slug, and every cook page keeps its recipe on file so you can decide with your eyes before you listen with your ears. It is free because it is ours: the marginal cost of you listening to a track we already generated is zero, and charging for zero felt silly."},{"type":"callout","text":"The library keeps growing in batches. Each new cook is another 10 recipes added to the data. This article's numbers regenerate with the cookbook (version 1, updatedAt 2026-08-23T17:45:24.952Z, source: web/music/scripts/build-cookbook.mjs), so the counts above always match what the player serves. The 10-track rule is verified by grouping the 2,500 songs by cookId: every group has size 10, no exceptions."}]`),te={slug:q,title:U,description:V,date:z,updatedAt:_,author:K,reviewedBy:J,family:Y,tags:Z,affiliateDisclosure:X,sources:Q,sections:ee},ae="samai-keys-transparency",oe="Where do your AI keys go when you use our tools? A straight answer",re="BYOK tools ask for the most sensitive string you own. Exactly what happens to your keys across Dracon tools (extension, chat, vault) and what we never do.",se="2026-07-31",ie="2026-09-13",ne="Dracon Security Team",le="Dracon Editorial",he="products",ce=["products","privacy","byok","transparency"],de=!1,ue=[{label:"Vault: /dashboard/settings, AES-256-GCM per-key, last-four only",href:"/dashboard/settings"},{label:"Chat: /chat, browser-direct to provider (no proxy)",href:"/chat"},{label:"SamAI: /products/sam, local storage BYOK",href:"/products/sam"},{label:"products-catalog.json: 5 tools, shared credential philosophy",href:"/products"}],pe=[{type:"p",text:"An AI provider API key is a credit card number that also reads your mail. Any tool that asks for one should answer first: where does this string actually go? We ship several BYOK surfaces (the SamAI browser extension, the [/chat](/chat) page, the account vault), so here is the answer in enough detail to check our work, not just trust it."},{type:"h2",text:"The rule: your key goes to your provider, never through us"},{type:"p",text:"Every BYOK surface calls the provider directly from your browser. On [/chat](/chat) the request travels browser â provider; open devtools and you watch it happen. Our servers never see the prompt, response, or key in transit. The page makes only two kinds of requests: provider API calls to the host you configured, and one same-origin fetch that supplies your key from your own vault at [/dashboard/settings](/dashboard/settings) when you choose to save."},{type:"h2",text:"How to verify it in 30 seconds"},{type:"p",text:"Open [/chat](/chat) signed in, save a test key, open Network, and send a message. You will see a fetch to api.openai.com, api.anthropic.com, api.groq.com, or the provider you selected, not dracon.uk. Filter by dracon.uk and the only hit is the vault fetch that gave the browser the key."},{type:"ul",items:["Open [/chat](/chat) and either paste a key per session or save one in [the vault](/dashboard/settings) and reload.","Open DevTools â Network, clear, send one prompt.","Filter by the provider host. The headers carry Authorization: Bearer sk-⦠and the payload is your prompt. Our origin
1is not the destination.","If you ever see chat content POST to dracon.uk, that is a bug. Report it as severity-one."]},{type:"h2",text:"The vault: AES-256-GCM per key, honest about the rest"},{type:"p",text:"If you save keys so they follow you, they live in the [settings vault](/dashboard/settings): AES-256-GCM encrypted per key before storage, decrypted only when your authenticated session asks over TLS, with list views showing only last four characters. The full key is shown once at create; after that only last-four hints remain. Rotation is one click: save a new key, old ciphertext is overwritten. Deletion is immediate. Vault access logs store key ID and timestamp, not the string."},{type:"p",text:"We say plainly on the settings page: because encryption is server-side, the server can technically decrypt when serving your session. That is the trade for cross-device sync. If you do not want it, do not save. [/chat](/chat) works with a per-session paste that never touches our servers, and the [SamAI extension](/products/sam) defaults to an even stricter local path."},{type:"h2",text:"The extension: local first"},{type:"p",text:"The [SamAI extension](/products/sam) defaults to browser-local: keys in BYOK mode live in the browser's extension storage, used only to call providers you configured. Memory features that remember tab context store locally for the same reason. The philosophy holds across the 5 tools in our [products catalog](/products): credentials are load-bearing for you, not inventory for us. Uninstall the extension and the keys go with it. (2026-09-09 note: the extension is a separate product; /products/sam documents the hosted SamAI operator.)"},{type:"h2",text:"Threat model: what we protect, what we do not"},{type:"p",text:"A key must be usable to be useful, so no storage protects against every attacker. Here is the boundary:"},{type:"table",caption:"What Dracon BYOK protects and what it does not: decide save vs. paste by this boundary.",headers:["Threat","Mitigated?","How"],rows:[["Network snooping","Yes","TLS to dracon.uk and to provider; vault fetch over TLS"],["At-rest theft of vault DB","Yes","AES-256-GCM per key; lists show last four only"],["Our servers seeing prompts","Yes","Browser-direct BYOK: prompts go browser â provider"],["Compromised browser/extension","No","If malware reads storage or intercepts before TLS, rotate keys on a clean profile"],["Stolen dracon.uk session","No","Session can fetch decrypted key via vault API: protect session, rotate if suspected"]]},{type:"h2",text:"What we never do"},{type:"ul",items:["Never proxy provider traffic: no middlebox, no logging, no optimization layer reading prompts.","Never train on keys, prompts, or outputs. The question is legitimate, the answer is invariant.","Never email a key, display it in a list, or include it in a support export. Last-four hints only.","Never gate BYOK behind a subscription. [Chat](/chat) with free-tier keys is free; [Dracon Omni at /pricing](/pricing) buys tools and intel, not access to your own accounts.","Never log plaintext keys. Logs record key ID + timestamp, not the string."]},{type:"h2",text:"Save vs. paste: who should choose which"},{type:"ul",items:["Save in [the vault](/dashboard/settings) if you work across devices and want keys to follow you. Cost is server-side AES-256-GCM and last-four display.","Paste per session on [/chat](/chat) if you want zero server persistence: the key lives in memory for that tab and dies when you close it.","Use the SamAI extension's local storage for daily driver work: browser profile, provider-direct, no server copy."]},{type:"h2",text:"If a key leaks"},{type:"p",text:"Assume a key can leak like a password: screenshot, env file, screen share. Rotate at the provider first, not at Dracon."},{type:"ul",items:["Revoke/rotate at the provider dashboard. The old string dies immediately there.","In Dracon delete or overwrite the entry in [the vault](/dashboard/settings); last-four hints let you find the slot.","If the leak was a shared session or extension compromise, sign out, rotate, and paste per session until you have a clean profile."]},{type:"h2",text:"Where your keys live on dracon.uk today"},{type:"p",text:"Three surfaces, three homes. [/chat](/chat) can run with per-session paste (no home) or a vault key from [/dashboard/settings](/dashboard/settings). The vault is the cross-device home: AES-256-GCM per key, last-four, TLS only. The [SamAI extension](/products/sam) is the local home: browser storage, provider-direct, no server copy. For the rest of the catalog see [all products](/products) and [our pricing page](/pricing): BYOK is constant, where the key lives is your choice."},{type:"callout",text:"Verify it: open /chat, save a key, watch Network. Provider host â your prompt; dracon.uk â only the vault fetch supplying the key to your browser. If chat content hits dracon.uk, file a bug. Vault: AES-256-GCM per key, last-four display, TLS-only fetch, one-time full display on create."},{type:"h2",text:"The threat model we design against"},{type:"p",text:"A browser operator that holds API keys is a high-value target, so we name the threats plainly. Eavesdropping: every BYOK call from [chat](/chat) goes browser â provider over TLS; our servers never see the key in transit and we carry no proxy that could. At-rest theft: keys you save live encrypted in the [settings vault](/dashboard/settings): AES-256-GCM per key, with list views showing only the last four characters and decryption gated to your own session. The server can technically decrypt (that is the trade for cross-device sync), so if you do not want that capability to exist, do not save: [chat](/chat) works with a key you paste per session, and the [SamAI extension](/products/sam) keeps keys in your browser profile's own storage for the same reason. Phishing and support-channel leakage: we never email a key, never display one in a list, never include one in an export, and never train on prompts or keys. These are policy choices enforced by what the UI does not allow, not by fine print."},{type:"h2",text:"How to verify and what we still owe you"},{type:"p",text:"Open [/chat](/chat), sign in, save a key, and watch the network tab: you will see provider API calls and one same-origin call that fetches your key from your own vault, nothing else. That observation is worth more than this paragraph. What we still owe is an independent audit letter and a public key-trans
1parency log. Both are planned after the next vault rotation, not before, because a premature audit that does not cover the rotation is a checkmark, not assurance. Until then we publish the mechanics in the open: the 5 tools in our [products catalog](/products) share the same credential philosophy, the Dracon Omni [subscription](/pricing) never gates BYOK surfaces (free-tier keys work without paying us), and the [chat](/chat) page states the tradeoff on the surface where you make the decision. If you ever see chat content hit dracon.uk, that is a bug. Report it and we treat it as one."},{type:"callout",text:"Verify before you trust: network tab on /chat shows only provider calls + one vault fetch. Keys at rest: AES-256-GCM per key, last-four display only. Cross-device sync is server-side-encrypted and therefore server-decryptable by construction. Opt out by using per-session paste or extension-local storage. Surfaces: /chat, /dashboard/settings, /products/sam, /products."}],me={slug:ae,title:oe,description:re,date:se,updatedAt:ie,author:ne,reviewedBy:le,family:he,tags:ce,affiliateDisclosure:de,sources:ue,sections:pe},ye="cheapest-claude-august-2026",fe="The cheapest way to run Claude right now: every route in our catalog, from $0 to $200 a month",ge="Seven providers we track serve Claude. Free lanes, pay-as-you-go, and subscriptions compared, with the catches and the cheapest route for light vs heavy use.",be="2026-08-01",we="2026-08-23",ve="Dracon Research Team",ke="Dracon Editorial",xe="ai-providers",$e=["claude","anthropic","pricing","ai","api"],Te=!1,Ae=[{label:"ai-providers-catalog.json: 45 providers, verified 2026-08-16",href:"/ai-hub/providers"},{label:"Anthropic Claude pricing and plan pages (Pro / Max 5x / Max 20x), provider docs",href:"https://www.anthropic.com/pricing"},{label:"Provider catalog entries cross-checked June 2026",href:"/ai-hub/plans"}],Se=[{type:"p",text:"Claude is not one price. Depending on where you point your API key, the same model can be free with rate limits, metered by the request, bundled into a subscription, or discounted through a credit scheme. We maintain a [structured catalog of 45 AI providers](/ai-hub/providers), and seven of them list Claude models by name, with an eighth route via bring-your-own-key tooling. One caveat up front, because E-E-A-T starts with admitting what you do not know: the catalog tracks plans, allowances, and credit math as structured data, but it does not carry per-million-token prices for Claude itself in these provider wrappers. So this article compares what we can actually verify (routes, monthly costs, rate limits, and subscription math) and says exactly where the data stops. If you need pay-per-token Claude pricing, the provider's own pricing page is your source; our [provider directory](/ai-hub/providers) links you there for each entry."},{type:"h2",text:"How we verified each route"},{type:"p",text:"Every row in the next table is a provider entry in our catalog with a verified_at timestamp in June 2026 and a source_url pointing at the provider's own pricing or docs page. We read the page, captured the plan names and the allowance or credit math into structured fields (free_tier, subscription_plans, rate_limits, promo_codes), and re-fetched to confirm the field still resolves. Where a provider says 'varies by usage tier' without a hard number, we store that string instead of inventing one. Where a plan is labeled 'free tier' but scoped to personal use and prototyping, we store both facts. The [plans table](/ai-hub/plans) is the rendered view of that data, and the [free-tier hub](/ai-hub/free) is the filtered view for the $0 lanes. This article is a snapshot of that data as of August 1, 2026, refreshed August 23 without changing a price until the catalog itself changes."},{type:"h2",text:"Every route to Claude we track"},{type:"table",caption:"Providers in our catalog with a route to Claude, August 2026. 'Cost' is the catalog entry, not a per-token price; see the caveat above.",headers:["Provider","Route to Claude","Cost","The catch"],rows:[["GitHub Models","Claude 3.5 Sonnet on the free tier","$0, no credit card","Rate-limited, and scoped to personal use and prototyping"],["Kilo Code","Free plan with sign-in; Claude 3.5 Sonnet in the model list","$0","200 requests/hour cap; BYOK when you outgrow it"],["LLM Gateway","Free tier, then pay-per-token routing to Claude","$0 to start, no credit card","A 5% fee rides on token spend after the free tier"],["AI Router","Smart routing to Claude 3.5 Sonnet with fallbacks","Free entry at 1K requests/month; Starter is â¬20/mo for 20K requests","Above the included volume you pay per request (â¬0.0015 on Starter)"],["CrofAI","Straight pay-as-you-go Claude 3.5 Sonnet","No monthly charge at all","The Hobby tier caps at 500 requests/day"],["OpenRouter","Claude 3.5 Sonnet, paid","Usage-based","The famous 50 req/day free pool excludes Claude; the free models rotate, and Claude is not one of them"],["Anthropic","Direct: Pro, Max 5x, Max 20x","$20 / $100 / $200 per month","No free tier and a card is required; the Max tiers buy headroom, not newer models"],["Kilo Pass","Monthly AI-credit subscription inside Kilo Code","$19 / $49 / $199 per month","Credits, not unlimited use; the 50% bonus credit is what makes the math interesting"]]},{type:"h2",text:"Cheapest for light use: genuinely free"},{type:"p",text:"If your Claude usage is a few dozen prompts a day, the cheapest answer in the catalog is GitHub Models: Claude 3.5 Sonnet on a free tier, no credit card, with paid usage beyond the free limits. The catch is scope: the plan is documented for personal use and prototyping, so a product backend does not belong on it. That is not our editorializing, it is the plan's own terms, and we link the source from the [provider entry](/ai-hub/providers) . Kilo Code gives you 200 requests per hour just for signing in, which is generous for an editor built around Claude, and [LLM Gateway](/ai-hub/providers) starts free and only charges token spend (plus that 5% routing fee) once you pass its free tier. AI Router's entry lane is 1,000 requests a month, which is evaluation volume, not a lifestyle. Open the [free-tier hub](/ai-
1hub/free) and you can filter these four side by side; the [plans table](/ai-hub/plans) shows what each one costs once you stop being free, because the cheapest month is rarely the cheapest year."},{type:"h2",text:"Cheapest for heavy use: do the subscription math"},{type:"p",text:"If Claude is a daily tool rather than an experiment, the math inverts. Anthropic's own Pro plan is $20 a month with Claude Code access and every Claude model in the catalog, from Claude 4.5 Sonnet up to Claude 4.1 Opus. The Max 5x ($100) and Max 20x ($200) tiers multiply the allowance and add priority access at peak, but the model lineup is identical at $20, a common misunderstanding. You are buying headroom and priority, not a newer model. Kilo Pass is the other structure worth doing arithmetic on: $19 a month buys up to $26.60 in credits, $49 buys up to $68.60, and $199 buys up to $278.60, a 50% bonus on each tier, and Kilo's Auto Model routes each request to a capability and cost tier instead of burning everything on the flagship. That bonus is why Kilo Pass sometimes beats Anthropic direct on a per-credit basis if you live inside Kilo Code. If you want pure metered billing with zero monthly commitment, CrofAI is the only provider in the catalog that sells Claude as straight pay-as-you-go with no subscription wrapped around it: you pay per request until you hit the Hobby cap of 500 requests/day, then you upgrade. For teams, that pay-per-request shape is easier to attribute to a cost center than a credit pool."},{type:"p",text:"Two honest notes, because comparison tables flatter the winner. First, OpenRouter is usually the default answer to 'cheap access to everything', and it is excellent for open models: 50 free requests a day without a card, 1,000 once you add $10 in PAYG credit. But Claude sits outside that free pool (our OpenRouter entry says so explicitly, and the provider's own free-model list confirms it), so it does not win this particular contest. Second, per-million-token Claude pricing is exactly the kind of field we do not track in the catalog wrappers yet; Anthropic's catalog entry describes its API as usage-based with no monthly subscription required, and when providers publish token prices for Claude we add them. Until then, the [provider directory](/ai-hub/providers) and our [pricing page](/pricing) carry whatever is current, and the [AI hub](/ai-hub/providers) is the front door to all of it. If you are building a product on Claude, run the same prompt through two routes on [/chat](/chat) with your own keys and watch the latency and rate-limit headers yourself. That is worth more than any comparison article."},{type:"h2",text:"Who should pick which"},{type:"ul",items:["Trying Claude for the first time or prototyping a prompt: GitHub Models or Kilo Code. No card, no commitment, and the limits are high enough to finish the prototype before you decide.","Light production that fits in ~1K requests/month: AI Router free tier, then Starter at â¬20/mo if you need fallbacks and smart routing.","Bursty pay-as-you-go without a subscription: CrofAI Hobby (500 requests/day) or LLM Gateway (5% fee after the free tier but no monthly minimum).","Daily driver for coding: Anthropic Pro at $20/mo is the cleanest buy. If you already live in Kilo Code, do the Kilo Pass credit math at $19/$49: the 50% bonus can make Kilo cheaper than direct if you route through Auto Model.","Teams that need priority at peak: Anthropic Max 5x/20x ($100/$200) buys headroom, not a better model. Budget for the allowance multiplier, not a model upgrade."]},{type:"h2",text:"Limitations and when to re-check"},{type:"p",text:"Plans, credit offers, and free-tier scopes rotate without notice. A provider that was free last month can be paywalled this month, and a 50% bonus can become 25%. Our catalog stores a verified_at per entry for exactly this reason, and we re-verify monthly; the directory reflects changes first. This article's prices and caps are accurate as of August 1, 2026, editorially refreshed August 23. Before you commit to an annual plan, open the live [provider entry](/ai-hub/providers). If the number on the provider page disagrees with the number here, the provider page is right and we want the bug report."},{type:"callout",text:"Data in this article comes from the provider catalog we maintain, with plan entries verified against provider pages in June 2026 and accurate as of August 1, 2026 (editorial refresh 2026-08-23). Plans, credit offers, and free-tier scopes rotate; the directory reflects changes first. No per-token Claude prices are shown where our catalog does not carry them: we compare routes, not invented numbers."}],Pe={text:"Claude pricing moves month to month. The provider pages carry the newest terms; this article is the August snapshot.",links:[{label:"All tracked providers, priced",href:"/ai-hub/providers"},{label:"Discuss in Discord",href:"https://discord.gg/gAjfKwRbtQ?ref=blog&utm_source=article&utm_medium=cta",external:!0}]},Ie={slug:ye,title:fe,description:ge,date:be,updatedAt:we,author:ve,reviewedBy:ke,family:xe,tags:$e,affiliateDisclosure:Te,sources:Ae,sections:Se,cta:Pe},De="ai-promo-codes-august-2026",Ce="AI promo codes: 15 tracked offers rechecked, with conditions and corrections",Oe="A September 17 source check of 15 AI promo and referral offers: current terms, historical claims, eligibility limits and explicit notes where rewards could not be reconfirmed.",Be="2026-08-01",Me="2026-09-17",Ee="Dracon Research Team",Ne="Dracon Editorial",Re="ai-providers",We=["ai","promo-codes","credits","deals","api"],Fe=!0,Le=[{label:"Original offer inventory: provider catalog (historical claims, not evidence of current availability)",href:"/ai-hub/providers"},{label:"RunPod official referral terms â checked 2026-09-17",href:"https://www.runpod.io/referral-and-affiliate-program"},{label:"Kilo Pass official referral offer â checked 2026-09-17",href:"https://kilo.ai/pricing/kilo-pass/refer"},{label:"LLM Gateway official referral program â checked 2026-09-17",href:"https://llmgateway.io/referrals"},{label:"Alibaba World First campaign terms â checked 2026-09-17",href:"https://www.alibabacloud.com/en/campaign/benefits-world-first"},{label:"BytePlus official Coding Plan campaign â checked 2026-09-17",href:"https://www.byteplus.c
1om/en/activity/codingplan"}],je=JSON.parse(`[{"type":"p","text":"We revisited the official sources for the 15 offers in this article on September 17, 2026. The previous claim that all 15 were active was too strong: a catalog refresh is not a fresh verification of each reward. This update retains the original inventory, separates Alibaba's referral and World First campaigns into two rows, and annotates changed or unconfirmed terms instead of quietly removing them. The August URL stays unchanged so existing links still reach the corrections."},{"type":"h2","text":"What the status and dates mean"},{"type":"p","text":"Active means the official page currently advertises the described offer; normal terms still apply. Conditional means eligibility or spending requirements are material, or the old reward could not be reconfirmed; the row says which. Expired is reserved for an explicit end date or official withdrawal, not inferred from a blocked page. Last checked records our source-access attempt. Last verified records the date the stated terms were readable; for blocked or unconfirmed rewards we retain the older catalog verification date and label it historical, not newly verified. No checkout, purchase, signup or code redemption was performed."},{"type":"callout","text":"A login screen, blank application shell or security challenge is not proof that an offer works or has expired. Rows marked unconfirmed are not offers you should budget around. Use the official source to confirm your account's eligibility before paying; a date on this article does not override that warning."},{"type":"h2","text":"All 15 original offers: status, dates and what changed"},{"type":"table","caption":"15 original offers across 13 providers. Official-source checks: 2026-09-17. Historical verification dates are explicitly distinguished from new confirmations. No tracked offer has been deleted.","headers":["Offer","Status and verification","Current evidence and conditions","Previous claim / correction"],"rows":[["Perplexity student / educator","Status: conditional â unconfirmed. Last checked: 2026-09-17. Last verified: 2026-06-13 (historical catalog record only).","The [official student page](https://www.perplexity.ai/students) returned a security challenge in both HTTP and browser checks. Current eligibility, pricing and Comet terms could not be read.","Previously: the tracked student offer was described as 50% off Pro at $10/month, or 75% off with the Comet browser at $4.99/month; no code string is republished here. These are historical claims, not freshly verified discounts; the earlier best-discount recommendation is withdrawn."],["Perplexity referrals","Status: conditional â unconfirmed. Last checked: 2026-09-17. Last verified: 2026-06-13 (historical catalog record only).","The [official referral terms](https://www.perplexity.ai/hub/legal/refer-a-friend-program) returned a security challenge in HTTP and browser checks. Neither a current reward nor an expiry could be confirmed.","Previously: $15 cash to the referrer, no friend discount. Retained as a historical claim only; do not assume that cash program still operates."],["Alibaba Coding Plan referral","Status: conditional â changed destination; original reward unconfirmed. Last checked: 2026-09-17. Last verified: 2026-09-17 (current landing-page terms only); original reward: 2026-06-15 (historical).","The [original campaign source](https://www.alibabacloud.com/campaign/ai-scene-coding) redirects to a Token Plan landing page. It advertises an invite-for-credits program without a fixed reward amount, plus a separate $2 new-user coupon: minimum $5 order, expires 14 days after redemption, not valid with other offers.","Previously: referral credits and a supposedly reliable 70M+ free-token baseline. The current landing page does not substantiate that token total, so it is no longer presented as guaranteed or as a referral benefit. The $2 coupon is a separate current campaign, not a promise attached to the old code."],["Alibaba World First campaign","Status: conditional â changed terms, approval required. Last checked: 2026-09-17. Last verified: 202
16-09-17 (current campaign terms).","The [official World First page](https://www.alibabacloud.com/en/campaign/benefits-world-first) advertises $200 credit for eligible new users with no previous paid orders, registered after April 1, 2025. Business details, phone verification and staff approval are required; reseller/channel and KA/KP exclusions apply. Credit lasts 60 days once redeemed, with product exclusions.","Previously merged into the Coding Plan row as unspecified extra coupon consideration. Now shown separately, as it was already a distinct tracked offer. This is not automatic $200 on signup or a guaranteed Coding Plan discount; claim before the first payment and check product eligibility."],["Hyperbolic","Status: conditional â gated, reward unconfirmed. Last checked: 2026-09-17. Last verified: 2026-08-12 (historical catalog record only).","The [official app](https://app.hyperbolic.ai/) invite flow led to the app/login surface without readable reward terms. The last catalog record required phone verification and a minimum $5 deposit within 14 days; those conditions have not been newly verified.","Previously: $6 to both sides and no-purchase starting credit. That omitted the recorded deposit requirement. The claim that $1 to $6 triples the balance was also arithmetically wrong. The $6 reward is retained only as historical and unconfirmed, not free signup cash."],["Synthetic","Status: conditional â gated, reward unconfirmed. Last checked: 2026-09-17. Last verified: 2026-06-13 (historical catalog record only).","The [official site](https://synthetic.new/) did not show the reward in the fetched landing page; the [referrals route](https://synthetic.new/referrals) redirected to login. No fresh public terms were obtained.","Previously: $5 credit to each side. Retained as an unconfirmed historical reward; the earlier recommendation of immediately available, no-purchase credit is withdrawn."],["LLM Gateway","Status: conditional â changed description, referrer funding required. Last checked: 2026-09-17. Last verified: 2026-09-17 (current program terms).","The [official referral page](https://llmgateway.io/referrals) says referrers must top up $100 to unlock referrals and earn 1% of referred teams' LLM spend after discounts. Rewards are platform credits, automatically deposited and not withdrawable.","Previously: referral credits plus $5 free to start, with a 5% routing-fee claim. The current referral page supports the referrer program, not that invitee signup bonus or a universal fee. Those claims are no longer used to recommend the offer."],["Kilo Code","Status: active â advertised referral offer; subscription terms apply. Last checked: 2026-09-17. Last verified: 2026-09-17 (official offer page).","The [official Kilo Pass referral page](https://kilo.ai/pricing/kilo-pass/refer) advertises 50% bonus credits for the first two months rather than the standard first month alone. It is a paid credit subscription. Bonus credits are released after paid credits are used and expire at month-end.","Previously: the same two-month 50% offer, but with $26.60/$68.60/$278.60 examples. Those figures are 40% above the listed $19/$49/$199 prices, not 50%; they have been removed from the two-month example rather than repeated as referral math. Check the applicable plan and offer terms before subscribing."],["OpenCode","Status: conditional â old discount unavailable in current public terms. Last checked: 2026-09-17. Last verified: 2026-09-17 (standard plan price only); old referral reward: not reconfirmed.","The [official Go page](https://opencode.ai/go) and [Go documentation](https://opencode.ai/docs/go/) advertise a $10/month subscription. Neither checked page substantiates the old $5 first-month referral offer. Absence alone does not establish an expiry date.","Previously: $5 first month via referral, then $10/month. The catalog also stopped listing an active referral in its August 31 update. The old discount is retained for transparency, not offered as currently redeemable; no replacement code is invented."],["Z.AI GLM","Status: conditional â original invitee discount unconfirmed. Last checked: 2026-09-17. Last verified: 202
16-09-17 (public program headline only); original reward: 2026-06-13 (historical).","The [official subscription page](https://z.ai/subscribe) currently advertises invite-friends credits with up to 20% back. That referrer headline does not verify an invitee's checkout discount or Builder benefits.","Previously: 10% off the GLM Coding Plan plus Builder benefits. Retained as historical and unconfirmed. Do not confuse the public referrer percentage with a guaranteed saving for the new subscriber."],["MiniMax","Status: conditional â original reward unconfirmed. Last checked: 2026-09-17. Last verified: 2026-06-13 (historical catalog record only).","The [official Token Plan page](https://platform.minimax.io/subscribe/token-plan) rendered subscription pricing, but the captured public page did not confirm the tracked invite-code reward. No purchase or authenticated redemption was attempted.","Previously: 10% off Token Plan plus Builder benefits. Those historical benefits are not carried forward as verified active merely because the subscription page still exists."],["BytePlus ModelArk","Status: conditional â first-subscription and referral eligibility. Last checked: 2026-09-17. Last verified: 2026-09-17 (current campaign terms).","The [official Coding Plan campaign](https://www.byteplus.com/en/activity/codingplan) advertises 10% off a referred friend's first subscription and a 10% voucher for the referrer on the friend's order. The first recorded invitation determines the relationship. Creating your own invitation code first makes you ineligible for the referee first-order discount.","Previously: unspecified campaign rewards plus a 500K/2M free-token baseline. The reward is now specified by the campaign; that separate free-token claim is not presented as a verified referral benefit."],["Venice","Status: conditional â reward unconfirmed. Last checked: 2026-09-17. Last verified: 2026-06-13 (historical catalog record only).","The [official chat route](https://venice.ai/chat) redirected to /chat/agent;
1 the captured page did not expose readable referral terms. The current amount, eligibility and availability remain unconfirmed.","Previously: unspecified Venice credits via referral. No amount was recorded, and none is invented now. The earlier assertion that the program exists is not treated as a fresh verification."],["Mimo","Status: conditional â partial confirmation, credit grant unconfirmed. Last checked: 2026-09-17. Last verified: 2026-09-17 (10% friend-discount headline only); credit grant: 2026-06-13 (historical).","The [official Xiaomi MiMo Token Plan page](https://platform.xiaomimimo.com/token-plan) says 'Friend 10% off, Up to 20% back' and describes referrer rates. The public capture does not confirm the old $2 grant or its expiry. This is Xiaomi MiMo, not a promise about another product with a similar name.","Previously: $2 API credits for both parties, 10% off the first plan, and 40-day credit expiry. Only the public friend-discount headline was reconfirmed; the $2 and 40-day terms remain historical, not a current budget allowance."],["RunPod","Status: conditional â referred-user spend required. Last checked: 2026-09-17. Last verified: 2026-09-17 (official program terms).","The [official referral terms](https://www.runpod.io/referral-and-affiliate-program) give both parties randomized $5â$500 credits after the referred user's first $10 spend. Credits expire after 90 days. The referrer earns 3% on Pod spend and 5% on Serverless spend for the first 6 months; credits are non-transferable and self-referrals are prohibited.","Correction: the previous 'mostly $5' claim had no supporting distribution data; the spend threshold and expiry were missing. The percentage commissions go to the referrer, not automatically to both parties. Do not budget on receiving the top of the random range."]]},{"type":"h2","text":"What to do with this list"},{"type":"ul","items":["Start with the conditions, not the headline reward. RunPod requires spending before the credit is awarded; LLM Gateway requires a referrer top-up. Neither is a no-purchase trial.","Separate paid subscription bonuses from free credit. Kilo's two-month bonus requires a subscription, while BytePlus's discount is tied to an eligible first subscription. Neither reduces every provider bill or BYOK usage cost.","Do not stack historical promises. Alibaba's old token-total claim, its separate current coupon and its approval-based World First credit are not one guaranteed signup package.","For blocked or partial checks, confirm the exact terms in your own account before committing money. An unconfirmed reward is not a saving. Compare recurring allowances separately in the [free-tier hub](/ai-hub/free) and [plans table](/ai-hub/plans)."]},{"type":"h2","text":"Affiliate disclosure and verification limits"},{"type":"p","text":"The original inventory described 13 of the 15 offers as Dracon-owned referral programs. That historical ownership disclosure does not establish current eligibility or availability. We may benefit when you use our referral links on provider-directory pages; this article links to official public sources without adding referral query parameters or publishing redeemable code strings. Public-source checks verify advertised terms, not successful redemption or your personal eligibility. Historical amounts appear only to explain corrections. Dates on other catalog pages were not refreshed by this article check."},{"type":"callout","text":"Editorial refresh: 2026-09-17. All 15 original offers retained; the former 14-row table combined two Alibaba campaigns. Current source checks and older reward-verification dates are now separate. No source-access failure is labelled an expired offer, and no unconfirmed historical reward is represented as freshly verified active."}]`),He={text:"Before relying on a promo, compare the provider's ongoing price and confirm the offer's terms in your own account.",links:[{label:"Provider guides & key setup",href:"/ai-hub"},{label:"Share working codes in Discord",href:"https://discord.gg/gAjfKwRbtQ?ref=blog&utm_source=article&utm_medium=cta",external:!0}]},Ge={slug:De,title:Ce,description:Oe,date:Be,updatedAt:Me,author:Ee,reviewedBy:Ne,family:Re,tags:We,affiliateDisclosure:Fe,sources:Le,sections:je,cta:He},qe="free-ai-rate-limits-2026",Ue="Free AI API rate limits, compared: which free tiers can do real work and which are demo taps",Ve="22 of the 45 AI providers we track have a free tier. The real limits side by side: RPM, daily caps, token grants, and the 7 that hold up for actual work.",ze="2026-08-01",_e="2026-08-23",Ke="Dracon Research Team",Je="Dracon Editorial",Ye="ai-providers",Ze=["ai","free-tier","rate-limits","api","byok"],Xe=!1,Qe=[{label:"ai-providers-catalog.json: 45 providers, rate_limits field, verified 2026-08-16",href:"/ai-hub/providers"},{label:"Free-tier hub: live filtered view of same data",href:"/ai-hub/free"},{label:"Plans table: paid tiers for context when free runs out",href:"/ai-hub/plans"}],et=[{type:"p",text:"A free tier is only as good as its rate limit, and rate limits are the field providers least want to print in big type. We track them as structured data across [45 providers](/ai-hub/providers): 22 have a free tier of some kind, and the limits range from '~40 requests per minute, no daily cap' to '$0.10 of credit per month'. This article puts the whole picture side by side with the numbers our catalog actually carries, including the places where it carries none, because honesty about missing data is more useful than a guessed number. If you just want the maintained filter, the [free-tier hub](/ai-
1hub/free) is the live view; this post is the snapshot plus the nuance the table alone cannot carry: tier versus free-model nuance, what a 'request' even means on each provider, and which limits actually block real work."},{type:"h2",text:"Free models versus free tiers: the tier nuance most posts skip"},{type:"p",text:"A provider can be free in two different shapes. A free tier is an account-level allowance that applies to the provider's own models (Google AI Studio's daily quota, NVIDIA NIM's 40 RPM, Groq's 30 RPM). A free-model pool is a set of third-party or open models the provider lets you call for free inside an otherwise paid platform (OpenRouter's 50 requests/day on its rotating free-model set, OpenCode Zen's 5 free models). The distinction matters because it changes what you can route where. A free tier follows your credentials; a free-model pool follows the model list, which rotates. On OpenRouter, your 50 requests/day can be spent on any model the provider currently marks free. But Claude, for example, is explicitly excluded from that pool. On OpenCode, you get 5 free models, but which five changes periodically. When you build a router, treat free-model pools as opportunistic capacity, not as a stable API contract. Our catalog stores this difference in free_tier_model and rate_limits so the [free-tier hub](/ai-hub/free) can surface it separately from a plain account quota."},{type:"p",text:"One more nuance: card requirements. Some free lanes require a card on file (Mistral Le Chat, OpenCode) while others do not (OpenRouter base tier, NVIDIA NIM, Groq, Cloudflare Workers AI). We store requires_credit_card as its own boolean rather than folding it into 'free means free', because for many developers a no-card lane is the only lane they will actually try first. The [plans table](/ai-hub/plans) lets you filter by this field before you sign up."},{type:"h2",text:"The rate-limit table: every number we have, and where we have none"},{type:"table",caption:"Free-tier limits as tracked in our catalog, August 2026 (verified 2026-08-16). Where a provider publishes no hard numbers, we say so instead of guessing.",headers:["Provider","Free limit","Card required?","Realistic use"],rows:[["NVIDIA NIM","~40 requests/min, no daily cap","No","Real work: sustained interactive use on a rotating model list"],["Google AI Studio","~1,500 requests/day on the free endpoint","No","Real work: a full day of scripting, rotating model lineup"],["Groq","30 requests/min; 1K to 14.4K requests/day depending on model","No","Genuinely fast lanes, but the daily cap swings hard by model"],["Kilo Code","200 requests/hour with sign-in","No","Real work inside a coding assistant; BYOK beyond it"],["Cloudflare Workers AI","10K neurons/day, 300 requests/min","No","Decent burst capacity; 'neurons' are Cloudflare's own metering unit"],["OpenRouter","50 requests/day on free models; $10 of PAYG credit raises it to 1,000/day","No for the base tier","Light daily use; the $10 unlock is the best-value move on this list"],["Mistral Le Chat","Base-tier messages, web search, libraries, and image generation","Yes","Daily-driver chat subject to fair use; the API is a separate paid lane"],["OpenCode","5 free models on OpenCode Zen; per-model limits rotate","Yes","A finite promotional tier; check the current model set first"],["Cline","Hosted free models with per-model limits that rotate","No","Useful in the editor; BYOK when you hit a wall"],["Ollama","Local: unlimited. Cloud free tier: 1 concurrent model","No","Local is the only truly unlimited lane on this list"],["OpenAI Codex","Free with a ChatGPT account; the 1x tier is ~20 messages per 5-hour window","Yes","A taste of the agent, not a workload"],["OVHcloud AI Endpoints","2 requests/min per IP without a key; 400 requests/min with a paid key","No for the IP lane","2 requests/min is a health check, not an app"],["SiliconFlow","100 requests/day plus $1 in credit","No","Evaluation of specific models"],["Hugging Face","~$0.10 of inference credit per month ($2 on PRO)","No","The smallest allowance we track; demo-only by design"]]},{type:"h2",text:"The seven we classify as usable, and the closest miss"},{type:"p",text:"In the catalog we flag a free tier as 'meaningful' when sustained real use is plausible under the published recurring limits. Seven of the 22 qualify: NVIDIA NIM, Google AI Studio, Mistral, Kilo Code, OpenCode, Cline, and OpenRouter. Look at the table and you can see why: those are the lanes with continuous allowances (per minute, per hour, or per day) rather than a one-time pile of credit that dies the first weekend you enjoy yourself. Groq is the closest miss, and it is instructive. Thirty requests per minute is generous (faster than most apps need), but the daily cap swings from 14.4K down to 1K depending on which model you pick. If you benchmark Groq on the high-cap model and then ship on the low-cap one, your production limit is one-fourteenth of what you tested. Plan around the model you actually want, not the headline number. The [free-tier hub](/ai-
1hub/free) carries the current meaningful classification for all 22, and the [provider directory](/ai-hub/providers) links the source page for each limit so you can read the exact wording yourself."},{type:"h2",text:"The demo-only tier, and why we still track it"},{type:"p",text:"The rest are scoped as trials, and that is fine as long as you treat them that way. One-time grants: Hyperbolic hands you $1, Alibaba gives 1M free tokens per model for 90 days (plus 70M+ tokens for new accounts), BytePlus ModelArk offers 500K free tokens per LLM and 2M for vision models, and OVHcloud's $200 public-cloud trial credit can be pointed at AI Endpoints. These are excellent for benchmarking a provider you might pay later. They are not foundations for a product. One honest gap: GitHub Models and DeepSeek both run free lanes, but our catalog carries no hard numbers for either, so they are absent from the table rather than represented by invented ones. That is deliberate: the honest-absence rule says we would rather show a gap than a number we cannot source. If you rely on either free lane, treat the [provider entry](/ai-hub/providers) as your source until the provider publishes a hard limit."},{type:"h2",text:"What a 'request' means, and other fine print that changes the math"},{type:"ul",items:["On Cloudflare Workers AI the free unit is 'neurons' (10K/day), not requests. Neurons map to compute rather than to calls, so a heavy prompt burns more neurons than a tiny one. The 300 RPM is a burst ceiling on top of that compute allowance.","On OVHcloud the '2 requests/min per IP' lane is unauthenticated and per-IP, not per-account; the 400 RPM number requires a paid key. Don't average the two.","On OpenAI Codex the '1x tier (~20 messages per 5-hour window)' is tied to a ChatGPT account, not an API key. It is a consumer-agent allowance measured in messages, not an API token allowance.","On Groq and SiliconFlow the daily cap varies by model. Our catalog stores the range (Groq: 1Kâ14.4K/day) rather than a single number so you don't anchor on the best case.","On Mistral's Le Chat and OpenCode Zen the 'per-model limits that rotate' note means the free model list itself changes, so your code should handle 'model not available for free today' as a normal case, not an error."]},{type:"h2",text:"The working pattern: hold several, route around exhaustion"},{type:"p",text:"The working pattern, as we keep saying on this blog, is not picking one free tier: it is holding several and routing around whichever one is exhausted. That is why our [chat page](/chat) is bring-your-own-key and browser-direct: your keys stay in your own vault, requests go straight from your browser to the provider, and leaving a provider costs one click. Put NVIDIA NIM and Groq behind your interactive loop, OpenRouter behind your batch jobs, Google AI Studio behind your long-context reasoning, and Kilo inside your editor. When one lane throttles, the others still have headroom. The [free-tier hub](/ai-hub/free) is the maintained version of this article's table, and the [pricing page](/pricing) covers what happens when you outgrow all of it, because eventually you will, and the cheapest paid step (often $10 in PAYG credit to unlock OpenRouter's 1,000/day free-model pool) is usually better value than another free account."},{type:"callout",text:"Rate-limit data is from our maintained catalog as of August 1, 2026 (verified 2026-08-16, editorial refresh 2026-08-23), re-verified against provider pages monthly. 'Meaningful' is our editorial classification of whether sustained real use is plausible under the published recurring limits, not the provider's marketing copy. Where we carry no hard numbers, we say so."}],tt={text:"Rate limits move as fast as prices. The catalog carries the current published limits for every provider we track.",links:[{label:"Current rate-limit data",href:"/ai-hub/free"},{label:"Compare notes in Discord",href:"https://discord.gg/gAjfKwRbtQ?ref=blog&utm_source=article&utm_medium=cta",external:!0}]},at={slug:qe,title:Ue,description:Ve,date:ze,updatedAt:_e,author:Ke,reviewedBy:Je,family:Ye,tags:Ze,affiliateDisclosure:Xe,sources:Qe,sections:et,cta:tt},ot="byok-real-cost",rt="What bring-your-own-key actually costs: the real math",st="The honest math behind bring-your-own-key: real API token prices from our 45-provider catalog versus $20 AI subscriptions, and why Dracon Omni is $10.",it="2026-08-01",nt="2026-08-23",lt="Dracon Research Team",ht="Dracon Editorial",ct="products",dt=["byok","pricing","ai","subscriptions","transparency"],ut=!1,pt=[{label:"byok-registry.json: 45 providers, 26 supported, 21 free tiers (2026-08-16)",href:"/ai-hub/providers"}
1,{label:"Dracon Omni pricing: $10 founding, $15 standard",href:"/pricing"},{label:"Provider pricing pages: OpenAI, DeepSeek, Anthropic",href:"/ai-hub/providers"}],mt=[{type:"p",text:"Every AI tool you use is paying for tokens somehow. The $20 subscription bundles hide the meter behind a flat fee and a rate limit; API accounts put the meter in front of you and bill per million tokens. Dracon is built on the second shape: you bring your own provider keys, our tools are the interface, and the token bill lands on accounts you own. This article is the arithmetic of that choice, using only prices from [our provider catalog](/ai-hub/providers) and [our own pricing page](/pricing)."},{type:"h2",text:"What the subscription shape costs"},{type:"p",text:"Our catalog tracks 45 AI providers, and consumer tiers cluster tightly: ChatGPT Plus $20/month, Claude Pro $20/month, Google AI Pro $19.99/month, Mistral Pro $14.99/month, SuperGrok $30/month. You buy a monthly allowance of messages, not tokens. ChatGPT Plus lists roughly 20 messages per 5-hour window on base Codex models; higher tiers are multipliers of that window. Two bundles (Claude for writing plus ChatGPT for code, or Gemini for search plus Grok for images) puts you at $35 to $50 before API spend. Three bundles pushes $55 to $70, with a window limit on each."},{type:"h2",text:"What the BYOK shape costs: the $0.28 month"},{type:"p",text:"Take the cheapest frontier-class API price we track: DeepSeek V4 Flash at $0.14 per million input tokens and $0.28 per million output as of its 2026-07-31 beta. A heavy personal month (30 long conversations a day) is roughly 1M input and 0.5M output tokens. That is 1.0M Ã $0.14 + 0.5M Ã $0.28 = $0.28. Add [Dracon Omni at the $10 foun
1ding price](/pricing) and the month is $10.28. Ten times that (10M in, 5M out with daily agent runs) is $2.80 in tokens, $12.80 with Omni. Route free tiers instead (Groq up to 14.4K requests/day no card, OpenRouter 50 free requests/day, Google AI Studio ~1,500/day) and tokens are $0; the month is $10 alone. Try it today on [/chat](/chat) with a per-session paste."},{type:"table",caption:"Monthly cost scenarios using catalog prices, plus Dracon Omni at $10 founding. Token prices per million tokens (input/output).",headers:["Monthly usage","Provider route","Token cost","Total with Omni"],rows:[["1M in / 0.5M out (heavy personal chat)","DeepSeek V4 Flash $0.14 / $0.28","$0.28","$10.28"],["10M in / 5M out (power user)","DeepSeek V4 Flash $0.14 / $0.28","$2.80","$12.80"],["Light daily use","Free tiers: Groq, OpenRouter, Google AI Studio","$0.00","$10.00"],["For contrast: one bundle","One typical AI subscription","included","$20.00"],["For contrast: two bundles","ChatGPT Plus + Claude Pro","included","$40.00"]]},{type:"h2",text:"The catalog behind the numbers: 45 providers, 26 BYOK-ready"}
1,{type:"p",text:"Prices live in web/packages/byok/src/data/byok-registry.json: 45 entries as rendered at [/ai-hub/providers](/ai-hub/providers) on 2026-08-16. Of those, 26 are supported BYOK: Alibaba DashScope, Anthropic, Cerebras, Chutes, DeepInfra, DeepSeek, Fireworks AI, GitHub Models, Google AI Studio, Grok, Groq, Hugging Face, Hyperbolic, Kimi, MiniMax, Mistral, NVIDIA NIM, Ollama, OpenAI API, OpenCode, OpenRouter, Perplexity, SambaNova, SiliconFlow, Venice, Z.AI GLM. Twenty-one carry a free-tier flag. The other 19 are listed as unsupported with a reason (endpoint unverified, CLI tool not an API, requires an account ID, or browser calls blocked by CSP), so the claim is auditable."},{type:"h2",text:"How to run the math for your workload"},{type:"p",text:"A page of dense text is ~500 tokens; a long chat turn with tool output is 1,000â3,000 tokens; a 10-page PDF is ~5,000 tokens. Pick the model per task, then multiply. The [free-tier hub](/ai-hub/free) shows the input/output split."},{type:"ul",items:["Estimate: daily conversations à avg tokens per turn à 30. At 3,000 input and 1,500 output per day you hit ~90K in and ~45K out per month, one tenth of the heavy-chat row.","Route cheap lanes for drafting (DeepSeek V4 Flash, Groq-hosted Llama, SiliconFlow 100/day + $1 credit) and reserve a frontier lane (Anthropic, OpenAI, Google AI Studio) only when the reasoning gap matters.","Apply the split: (input_M à input_price) + (output_M à output_price). Add $10 for Omni if you want hosted tools; leave it $0 if you only use [/chat](/chat) with free-tier keys per session."]},{type:"h2",text:"Free-tier lanes that make the $10 month real"},{type:"p",text:"Several free tiers are not demos. Groq gives 30/min and 1Kâ14.4K/day by model, no card. Google AI Studio gives ~1,500/day. NVIDIA NIM sits near 40/min with no daily cap. OpenRouter gives 50/day free, 1,000/day after $10 credit, cheaper than a bundle as a fallback. We flag the usable ones in the [free-tier comparison](/ai-hub/free). Browser-direct BYOK matters: trying three lanes costs three pastes, not three lock-ins."},{type:"h2",text:"Why Dracon can charge $10 and be honest about it"},{type:"p",text:"The reason is cost structure, not generosity. On [/chat](/chat) your browser calls the provider directly; we never proxy, so we never pay for your tokens. Marginal cost per subscriber is ~$0: static pages, object-storage streaming, and browser-direct AI mean one more user costs nothing measurable. The $10 founding tier (locked while subscribed; $15 standard later) buys everything on dracon.uk with zero markup on keys. The free surface is free: [chat with free-tier keys](/chat) costs nothing, and the vault at [/dashboard/settings](/dashboard/settings) is optional."},{type:"h2",text:"The honest catches, and when the bundle wins"},{type:"ul",items:["You manage keys. Generating a key and pasting it into [a tool](/chat) is five minutes once; saving in [the vault](/dashboard/settings) follows you, pasting per session keeps it off our servers.","Cheap â flagship. Routing 90% to a cheap lane and hard questions to a frontier model is the saving; using the priciest model for everything can pass $20.","Rate limits move both ways. Bundles cap messages per window; free tiers cap requests per day. Our [free-tier roundup](/ai-hub/free) tracks which limits hold up, because quotas tighten quietly.","The $20 bundle wins if you want one bill, one app, zero setup. If you live in one chat app with memory and mobile, stay there. We are for people who prefer to own the meter.","Founding $10 is a lock, not a forever price for newcomers. Keep the sub, keep $10; new buyers after the window pay $15 standard, still one tier for everything."]},{type:"h2",text:"Where to check the live numbers next"},{type:"p",text:"Prices move in weeks, so treat directories as truth. Start with [the provider directory](/ai-hub/providers) for per-provider prices and browser-direct status, check the [free-tier hub](/ai-hub/free) for usable limits, try a lane on [/chat](/chat) per session, and compare on [our pricing page](/pricing). If a number here no longer matches the directory, the directory is right."},{type:"callout",text:"Provenance: web/packages/byok/src/data/byok-registry.json (45 providers, 26 supported BYOK, 21 with free tiers) as rendered at /ai-hub/providers on 202
16-08-16. Subscription tiers from the same catalog (ChatGPT Plus $20, Claude Pro $20, Google AI Pro $19.99, Mistral Pro $14.99, SuperGrok $30). DeepSeek V4 Flash $0.14/$0.28 dated 2026-07-31 beta. Dracon Omni $10 locked while subscribed, $15 standard (see /pricing). Prices move; the directory is live."},{type:"h2",text:"A second scenario: the heavy user"},{type:"p",text:"The heavy-user math matters more than the light-user headline. Take a freelance developer who routes every ticket through [our chat page](/chat) with their own keys: roughly 5 million input and 2.5 million output tokens a month across planning, coding, and review. At DeepSeek V4 Flash ($0.14/$0.28) that is about $1.40. At GPT-5.6 Luna's new price ($0.20/$1.20) it is about $4.00. At Anthropic's Claude pricing (higher per million, captured in the same catalog at [the provider directory](/ai-hub/providers)) the same volume is roughly $15â$18. Add [Dracon Omni at the $10 founding price](/pricing) and the heaviest of those three is still $28, under the $40 you would pay for two subscription bundles without their window limits, and you keep the ability to swap models per task: frontier for reasoning, flash for bulk. The [free-tier hub](/ai-hub/free) changes the math further: Groq's 14.4K requests/day or OpenRouter's 50 free-model requests/day can cover the bulk lane at zero token cost, with [Omni](/pricing) as the only fixed line."},{type:"h2",text:"Who should stay on subscriptions"},{type:"p",text:"The $20 bundle is still the right buy if you want one bill, one app, and zero setup. If you live in one chat app, like its memory and mobile app, and you never want to see a token price, stay there. Subscriptions buy convenience and integration (memory, file search, canvas, voice) that a raw API key does not include until you build it. We are the shape for people who would rather own the meter and swap providers with one click, who already track usage per project, or who hit the bundle's 20-messages-per-5-hours window and feel the cap. Both shapes are valid; the honest comparison is not $0.28 versus $20 but $10.28 with control versus $20â$50 with limits. Our [plans page](/ai-hub/plans) tracks the recurring kind, because a $5 credit that expires in 40 days is not a business model. A free tier you can use every day is."},{type:"callout",text:"Methodology: token prices from byok-registry.json as rendered at /ai-hub/providers on 2026-08-16; DeepSeek V4 Flash dated to its July 31, 2026 public beta; subscription bundle prices from the same catalog's tracked consumer tiers. Dracon Omni founding $10 locked while subscribed, $15 standard (see /pricing). Check the directory page for live numbers; this article's date is 2026-08-01 with an editorial refresh 2026-08-23."}],yt={text:"BYOK means you pay providers directly: no markup, no middleman. See what that looks like in practice.",links:[{label:"Dracon products",href:"/products"},{label:"Ask questions in Discord",href:"https://discord.gg/gAjfKwRbtQ?ref=blog&utm_source=article&utm_medium=cta",external:!0}]},ft={slug:ot,title:rt,description:st,date:it,updatedAt:nt,author:lt,reviewedBy:ht,family:ct,tags:dt,affiliateDisclosure:ut,sources:pt,sections:mt,cta:yt},gt="one-person-platform",bt="One person, one platform: how dracon.uk actually runs",wt="An honest ops tour of dracon.uk: one VPS, five static apps and two Node apps behind Caddy, five Rust APIs on unix sockets, Paddle, OVH buckets, one person.",vt="2026-08-01",kt="2026-09-13",xt="Dracon Team",$t="Dracon Editorial",Tt="products",At=["infrastructure","ops","indie","sveltekit","rust"],St=!1,Pt=[{label:"products-catalog.json: 11 catalog entries (5 open-source tools, 1 SamAI service page, 5 browser extensions)",href:"/products"},{label:"Dracon platform: /games, /music, /books, /ai-hub surfaces",href:"/about"},{label:"Docs, status, and pricing: /docs, /status, /pricing",href:"/docs"}],It=JSON.parse(`[{"type":"p","text":"dracon.uk looks like a small company: a [games arcade](/games), a [music library](/music), a [bookstore](/books), an [AI hub](/ai-hub), a paid subscription, a blog. It is one person and a rotating cast of AI agents. This is the machinery behind that, and everything here is verifiable in the public repo: the Caddyfile, the deploy scripts, and the catalog JSON."},{"type":"p","text":"Update (2026-08-24): the catalog snapshot numbers in this piece were accurate as of their publication dates but the music library has since grown. The wave-3 expansion took it from 100 cooks / 1,000 tracks (2026-08-01, when this was published) to 200 cooks / 2,000 tracks (2026-08-23) and now 250 cooks / 2,500 tracks (2026-08-24). Figures below are kept as written so the article stays reproducible against its own date; the closing platform callout is corrected to the current counts."},{"type":"h2","text":"One VPS, one Caddyfile"}
1,{"type":"p","text":"Every request hits a single VPS running Caddy with Let's Encrypt TLS. The Caddyfile routes by path prefix. Five prebuilt SvelteKit apps (home, products, music, games, books) are served as static files from their build directories. Two dynamic SvelteKit apps ([/ai-hub](/ai-hub) and the dashboard) run as Node processes behind unix sockets. No containers, no orchestrator, no load balancer, because there is nothing to balance. The file is infra/caddy/Caddyfile.prod, and changes ship through one script that validates and reloads."},{"type":"p","text":"Behind the web tier, five Rust APIs listen on unix sockets in /run/dracon/: auth, billing, email, ai, and music. Caddy picks by path: /api/v1/auth/* â auth-api.sock, /api/v1/billing/* â billing-api.sock, /api/v1/email/* â email-api.sock, /ai/* â ai-api.sock. They run as systemd units. At 2 a.m. the debug surface is one proxy config and five services, a surface one person can hold in their head."},{"type":"h2","text":"The short list of things that cost money"},{"type":"ul","items":["The VPS. One box runs the proxy, Node apps, and five Rust services. No autoscaling group, just headroom and a Caddyfile.","Paddle for payments. Billing API receives Paddle webhooks at /api/v1/webhooks/paddle; Paddle is merchant of record, so we never touch card data.","OVH object storage. One bucket (dracon-master, S3-compatible, UK) holds game builds and music audio. Caddy proxies it at /_game-cdn and /_music-cdn, adding CORS headers the bucket does not send.","Notably absent: AI compute. Every AI feature runs browser-direct with your own key (see [our pricing page](/pricing)), so token spend never hits our infra. That is why the sub can be $10 founding ($15 standard) with marginal cost ~$0."]},{"type":"h2","text":"The six product detail pages that prove the model"},{"type":"p","text":"The product surface is the clearest test of solo scope. The catalog at web/products/src/lib/data/products-catalog.json lists 11 entries as of September 2026: five open-source tools, the SamAI service-page entry, and five browser extensions. The six service-page entries are browseable at [/products](/products); the extensions link directly to their stores:"},{"type":"table","caption":"The six service-page entries in the catalog. The five browser extensions are listed separately with direct store links.","headers":["Product","Slug","Surface","Detail page"],"rows":[["Tiles","tiles","open-source TUI","/products/tiles"],["SamAI","sam","hosted AI operator","/products/sam"],["Folder Auto Banner","folder-auto-banner","open-source banner","/products/folder-auto-banner"],["Dracon Warden","warden","open-source git filter","/products/warden"],["Dracon Sync","sync","open-source sync daemon","/products/sync"],["Dracon System","system-guard","open-source diagnostics","/products/system-guard"]]},{"type":"p","text":"The six detail pages ([Tiles](/products/tiles), [SamAI](/products/sam), [Folder Auto Banner](/products/folder-auto-banner), [Dracon Warden](/products/warden), [Dracon Sync](/products/sync), and [Dracon System](/products/system-guard)) each explain the install and link to source. The five browser extensions stay separate with direct store links. One catalog, no hidden SKUs."},{"type":"h2","text":"Deploys: a daemon with commit access"},{"type":"p","text":"The strangest piece is deploys, because there barely is one. [Dracon Sync](/products/sync), dogfooded, watches the working tree, auto-commits within seconds, and pushes to three remotes: GitHub, GitLab, Codeberg. Production serves static apps from a plain git checkout; Caddy's root points at that checkout. The only special path is the Caddyfile itself, which ships via a script that validates and reloads. History is never rewritten: a commit can be pushed to three remotes before you finish typing amend, and auto-messages like '2 file(s) in src [...]' are expected, not noise to rewrite."},{"type":"h2","text":"Why one person, and what stays human"},{"type":"p","text":"Solo forces boring choices, and boring is maintainable. No team stands on call for the Rust APIs, no SRE owns the Caddyfile, no content team owns the catalogs. One person knows every socket and webhook. That is also a trust signal: the [about page](/about) names the operator, the [pricing page](/pricing) lists one tier without enterprise folds, and [/methodology](/methodology) explains catalog capture. If you evaluate whether to trust a platform with a key or a repo, traceability matters more than headcount."},{"type":"p","text":"The division of labor is explicit: agents do production (games, books, tracks, articles like this) and the human does judgment. The roadmap's open errands waiting on a person are release-quality calls on two games, choosing bookstore genres, and a Google OAuth verification, not token wrangling or infra babysitting. Agents do not decide what ships; they make the decision possible."},{"type":"h2","text":"What one person actually maintains"},{"type":"p","text":"Catalog data tells the scale without varnish. The AI registry tracks 45 providers with prices and limits; the music library holds 2,500 tracks across 250 curated cooks (it was 1,000 tracks in 100 cooks when this was published); the games catalog tracks 16 projects from playable to placeholder; the bookstore holds five novels totaling 523,980 words from our pi
1peline; the products catalog has 11 entries, with 5 open-source tools and 5 browser extensions listed on the index plus the SamAI service page. No human curates daily churn by hand. The [games arcade](/games), [music library](/music), [bookstore](/books), and [AI hub](/ai-hub) are all rendered from the same JSON the repo commits."},{"type":"p","text":"To inspect rather than take my word for it: [/status](/status) shows live service state, [/docs](/docs) holds technical docs, [/about](/about) is the one-person disclosure, and the [pricing page](/pricing) is the business model in one tier. The stack is deliberately boring. Boring is what one person can run at 2 a.m., and what survives the next audit without a rewrite."},{"type":"h2","text":"When solo breaks, and when it wins"},{"type":"ul","items":["Solo breaks when judgment is needed asleep: a bad deploy can wait, a data-loss bug cannot. Mitigation is multi-remote push plus OVH streaming: even if the VPS dies, builds and audio survive in three git remotes and the bucket.","Solo wins on coordination cost. No planning meeting, no ticket shuffle. A docs fix is one commit, one push, one checkout on prod: minutes, not a sprint.","Solo wins on honesty. No 50-person roadmap to look fundable. The catch is the open errands list (games waiting on a quality call, genres waiting on a choice), and that list is shorter than a team would make it look."]},{"type":"callout","text":"Provenance: infra/caddy/Caddyfile.prod (routing, sockets, OVH proxies, Paddle webhook), web/products/src/lib/data/products-catalog.json (11 catalog entries: 6 service pages plus 5 browser extensions) at /products, web/packages/byok/src/data/byok-registry.json (45 providers) at /ai-hub/providers, and live inventory at /status and /docs. All checked in."},{"type":"h2","text":"What one person can and cannot promise"},{"type":"p","text":"One person can promise craft and velocity. One person cannot promise 24-hour on-call, enterprise SSO next quarter, or a roadmap that satisfies every vertical. The honest pitch for a one-person platform is not 'we do everything' but 'we do a small number of things with unusual cohesion because they share a single taste.' Our surfaces reflect that: a [games arcade](/games) that treats the browser as a first-class console, a [music library](/music) where every track keeps its recipe, a [bookstore](/books) where the AI label is on the tin, an [AI hub](/ai-hub) that tracks 45 providers honestly, and [products](/products) like Tiles, Warden, and Sync that solve problems the author had himself. The [status page](/status) shows live service state without theatre, [docs](/docs) hold the technical documentation you can check before you pay, and [the pricing page](/pricing) is a single tier because a one-person business cannot afford the support cost of tier logic, nor wants to."},{"type":"h2","text":"Why the comparison site exists at all"},{"type":"p","text":"Dracon builds comparison tools ([VPS](/tools/vps-compare), [domains](/tools/domain-tco), [email](/tools/email-api-compare), [vector DBs](/tools/vector-db-compare), [object storage](/tools/object-storage-compare)) for a selfish reason: they are how we shop for ourselves. The catalogs behind them (384 domain rows, 12 VPS providers, 14 email APIs, 22 vector DBs) are captured from the same provider pages you would have to open manually, with provenance dates and per-row notes. Publishing them as tools is both a service and a discipline: if our own pricing is ever wrong, the same audit that catches a registrar's ICANN flag will catch ours. The editorial factory that produces this blog is the same idea at a smaller scale: articles are data in [web/home/src/lib/data/articles](/about) so they can be regenerated when a catalog changes, rather than edited by hand until they drift. One person cannot out-staff anyone; one person can out-instrument the comparison."},{"type":"callout","text":"Platform as of 2026-09-13: 11 product-catalog entries (Tiles, SamAI, Folder Auto Banner, Warden, Sync, System Guard, plus 5 browser extensions); 10 are listed on the index and six have service pages. The platform also tracks 16 games (1 playable), 2500 music tracks (250 cooks), 5 bookstore novels, and 45 AI providers. Single tier: Dracon Omni $10 foun
1ding / $15 standard; see /pricing. Surfaces: /games, /music, /books, /ai-hub, /products, /tools, /docs, /status."}]`),Dt={slug:gt,title:bt,description:wt,date:vt,updatedAt:kt,author:xt,reviewedBy:$t,family:Tt,tags:At,affiliateDisclosure:St,sources:Pt,sections:It},Ct="ai-written-novels-bookstore",Ot="We published 5 novels written by our own book pipeline",Bt="Five novels, 523,980 words, written end to end by our own book pipeline and published free forever with the AI label on the tin. Meet the Dracon Bookstore.",Mt="2026-08-01",Et="2026-08-23",Nt="Dracon Team",Rt="Dracon Editorial",Wt="products",Ft=["books","ai","products","launch"],Lt=!1,jt=[{label:"shelf.json: source ai-auto-writer, 523,980 words, 95 chapters (2026-08-01)",href:"/books"},{label:"products-catalog.json: 12 products (2026-08-16 snapshot)",href:"/products"},{label:"byok-registry.json: 45 providers (2026-08-16)",href:"/ai-hub/providers"}],Ht=[{type:"p",text:"Today we open the [Dracon Bookstore](/books) with five full novels on the shelf: 523,980 words across 95 chapters, all written end to end by our own book pipeline. No crowdfunding, no soft launch, no shrug. The books say how they were made, they are free to read, and they always will be. Here is the shelf, then the honest part: how the engine works and where the label lives."},{type:"h2",text:"The shelf"},{type:"table",caption:"The five launch titles from web/books/src/lib/data/shelf.json as of August 1, 2026.",headers:["Title","Author","Genre","Words","Chapters"],rows:[["[The Thornwood Cottage](/books/thornwood-cottage)","Wren Hallow","Cozy Gothic Fantasy","119,203","20"],["[The Gilded Alibi](/books/gilded-alibi)","Mira Quill","Cozy Mystery","107,440","20"],["[The Lighthouse Keeper's Phoenix](/books/lighthouse-keepers-phoenix)","Corvin Ash","Epic Fantasy","106,085","20"],["[Echoes of the Shattered Command](/books/echoes-of-the-shattered-command)","Ash Frost","Military Sci-Fi","98,172","15"],["[Signal Zero](/books/signal-zero)","Sven Nordlicht","Sci-Fi Thriller","93,080","20"]]},{type:"p",text:"The spread is deliberate. [The Thornwood Cottage](/books/thornwood-cottage) is cozy gothic fantasy about a cottage the forest digests. [The Gilded Alibi](/books/gilded-alibi) is a Bloomsbury mystery around a forty-year silence. [Signal Zero](/books/signal-zero) starts under a dead Icelandic volcano, [The Lighthouse Keeper's Phoenix](/books/lighthouse-keepers-phoenix) guards a light out for twenty years, and [Echoes of the Shattered Command](/books/echoes-of-the-shattered-command) follows the last ship of a written-off fleet. Five genres, five pen names, one engine. The shelf has since grown (see the [full index](/books)), but these five are the provenance anchor."},{type:"h2",text:"How the books were made: pipeline, not prompt"},{type:"p",text:"The shelf data carries the receipt: source reads ai-auto-writer, generated at 00:18 UTC on August 1, 2026. Authors are pen names for pipeline configs, not people: Wren Hallow, Mira Quill, Corvin Ash, Ash Frost, Sven Nordlicht each map to a genre and pacing preset. The pipeline runs in stages and emits complete chapter files, not a chat log stitched together."},{type:"ul",items:["Premise and bible: genre, blurb, discovery metadata (tropes, mood, pacing, heat, themes), and a 20-chapter outline are generated and frozen. The outline is the contract: chapters cannot invent a protagonist in chapter 14.","Chapter drafting: each chapter is generated against the bible plus prior summaries, 4,000â7,000 words. The JSON records per-chapter counts (e.g., Thornwood Cottage chapter 9 at 6,996 words) so length is auditable.","Continuity pass: names, timelines, and clues are checked, critical for [The Gilded Alibi](/books/gilded-alibi), where the locket and photograph must line up across 20 chapters.","Rollup: 523,980 words across 95 chapters for the launch five (~105K per novel, ~5,500 per chapter). As of 2026-08-22 the shelf totals ten books and ~1,045K words, same source tag and same pipeline."]},{type:"h2",text:"The cookbook: recipes, not magic"},{type:"p",text:"Each novel is built from a cookbook of versioned prompt recipes (premise, outline, chapter, revision) with style constraints. Like the [cooks in our music library](/music), a recipe turns ingredients into a track; a book cook turns a genre and premise into a manuscript. The recipes are the IP, the manuscripts the demo, and the future member tool the kitchen where you point the engine at your premise."},{type:"ul",items:["Premise cook â blurb + tropes/mood/pacing/heat/themes.","Outline cook â 20-chapter beats from premise + bible.","Chapter cook â 4Kâ7K word chapter from outline + bible + prior summaries.","Continuity cook â flagged inconsistencies and patches.","Cover prompt cook â image prompt for hand-painted cover style, no text on cover."]},{type:"h2",text:"The ethics disclosure on the tin"},{type:"p",text:"Readers forgive a machine-written book; they do not forgive being tricked into one. The shelf, each book page, and this article carry the same disclosure: these are AI-pipeline novels, pen names are configurations, source is ai-auto-writer with timestamp. Open any book at [/books](/books) and the metadata is there: not a JavaScript footnote, but the JSON that builds the page."},{type:"ul",items:["We never claim a human ghostwriter. The byline is the pen name, provenance is the pipeline, chapters are generated, not dictated or lightly edited from a human draft.","We never paywall these five. They are free forever at [/books](/books) and via [/books/thornwood-cottage](/books/thornwood-cottage), [/books/gilded-alibi](/books/gilded-alibi), [/books/signal-zero](/books/signal-zero), [/books/lighthouse
1-keepers-phoenix](/books/lighthouse-keepers-phoenix), [/books/echoes-of-the-shattered-command](/books/echoes-of-the-shattered-command). The bookstore is the demo, not the product.","We never train on your reading. Opening a chapter does not feed a model; highlights and likes stay in the product domain, not a training set.","We label growth. The five later titles added by 2026-08-22 carry the same ai-auto-writer tag. A book without it is not ours."]},{type:"h2",text:"Who should read these, and who should not"},{type:"p",text:"If you want to judge whether a pipeline can sustain a novel (chapter structure, planted clues, a protagonist who changes), read chapter one then skip to chapter ten to see if the thread held. [The Gilded Alibi](/books/gilded-alibi) is the best test for clue discipline; [Echoes of the Shattered Command](/books/echoes-of-the-shattered-command) for pacing under fire; [The Thornwood Cottage](/books/thornwood-cottage) for slow-burn atmosphere. If you want a human-memoir voice or research-heavy nonfiction, these are not that. Better you know in paragraph one than chapter twelve."},{type:"p",text:"Limitations are part of the label. Pipeline prose can be even when it should be rough, tidy when it should be tangled, generous with description when a scene needs to breathe less. We edit for continuity, not for voice transfusion: the pipeline's cadence is the book's cadence. Future member controls will expose heat, pacing, and mood as dials; these five are what the dials produced fixed."},{type:"h2",text:"Where to start, and what comes next"},{type:"p",text:"Start on the [shelf](/books) by itch. Cozy and mossy: [Thornwood Cottage](/books/thornwood-cottage). Genteel and puzzling: [Gilded Alibi](/books/gilded-alibi). Cold and procedural: [Signal Zero](/books/signal-zero). Mythic and melancholy: [Lighthouse Keeper's Phoenix](/books/lighthouse-keepers-phoenix). Grim and relentless: [Echoes of the Shattered Command](/books/echoes-of-the-shattered-command). Each page lists words, chapters, and tropes. When the member tool ships it will live alongside these free proofs (same pipeline, your premise). Until then the books are evidence, free forever, with the AI label where it belongs."},{type:"callout",text:"Provenance: web/books/src/lib/data/shelf.json (source ai-auto-writer, 2026-08-01T00:18 UTC; five launch titles 523,980 words, 95 chapters (Thornwood Cottage 119,203; Gilded Alibi 107,440; Lighthouse Keeper's Phoenix 106,085; Echoes 98,172; Signal Zero 93,080). Later shelf 2026-08-22 totals ten books ~1,045K words, same source. Free at /books; pipeline's future surface at /products."}],Gt={slug:Ct,title:Ot,description:Bt,date:Mt,updatedAt:Et,author:Nt,reviewedBy:Rt,family:Wt,tags:Ft,affiliateDisclosure:Lt,sources:jt,sections:Ht},qt="dracon-arcade-pipeline",Ut="How a game ships to the Dracon arcade: build, bucket, catalog flip",Vt="The 8-step pipeline from local build to OVH bucket to the catalog flip, the real status counts across our 18-game catalog today, and what ships next.",zt="2026-08-01",_t="2026-08-23",Kt="Dracon Games Team",Jt="Dracon Editorial",Yt="games",Zt=["games","dev-diary","pipeline","arcade"],Xt=!1,Qt=[{label:"games-catalog.json: 16 games, canLaunch predicate, hosted_path + version",href:"/games"},{label:"GAMES-PIPELINE-2026-07-31.md: build, publish, probe runbook",href:"/blog/three-games-one-bug"},{label:"games/libs/platform/hosting.ts: canLaunch logic",href:"/games"}],ea=JSON.parse(`[{"type":"p","text":"Every game on [the Dracon arcade](/games) gets there the same way: an eight-step runbook that ends in a single field changing in a JSON file. We run it manually, on purpose, because the steps where it breaks are exactly the steps worth watching. On July 31 we ran it five times in one day and learned where the OVH bucket, SvelteKit's base handling, and our own postbuild each wanted to fail. Here is the pipeline as we run it today, the catalog it produces at 18 entries, and what is queued behind it. If you are shipping static to object storage, this is the checklist we wish we had found."},{"type":"h2","text":"The eight steps"},{"type":"ul","items":["1. Build the game with bun run build in its repo under web/games/wip/{slug} or web/games/released/{slug}. The build output is the static artifact the hub will never serve directly. It is a staging directory for the bucket.","2. Rewrite the static artifact for bucket hosting with the game's postbuild (scripts/rewrite-static-artifact.mjs), which prepares asset paths for object storage. For most games this relativizes bare literals so chunks load relative to the document; for SvelteKit games it must cooperate with the base path (see step 3). Neonbreak's postbuild now passes --absolute-assets /games/neonbreak/{version}.","3. Build with a real base path for every SvelteKit game. JR_BASE=/games/junk-runner/{version} bun run build (HH_BASE for Hellhunter, NB_BASE for Neonbreak). Without this, paths.relative serializes base as \\"./\\", SvelteKit's client router strips two characters off the pathname with slice(base.length), the leading slash is eaten, no route ever matches, and the game falls back to native navigation in a loop. That loop took down three games on July 31 and got its own postmortem in [three games, one bug](/blog/three-games-one-bug).","4. verify-release must exit 0. Each game carries its own checks; Polis's were rewritten the week of July 31 after we found them asserting a deleted Phaser architecture while the real game had moved to Svelte. A failing verify is a stop-the-line signal, not a warning.","5. Publish to the OVH bucket with ovh:publish, which uploads under games/{slug}/{version}/ with a per-object public-read canned ACL on every object. There is no bucket policy to widen: OVH does not implement PutBucketPolicy, so each putObject must carry the ACL. We learned this the hard
1way when a stale upload cost Junk Runner its ACLs and started serving 403 AccessDenied.","6. Screenshots: stage PNGs into the build BEFORE publishing, so they land at games/{slug}/{version}/screenshots/ alongside index.html, captured with a headless Chromium probe that names files 01-title.png, 02-*.png with alts in the catalog entry. The catalog's screenshots array is the source of truth for the hub's gallery.","7. Catalog flip: edit web/games/libs/data/games-catalog.json: status, version, hosted_path (/games/{slug}), hosted_artifact, asset_base_url (https://dracon-master.s3.uk.io.cloud.ovh.net/games/{slug}/), play_url (https://dracon.uk/games/{slug}/play), iframe_src (https://.../games/{slug}/{version}/index.html; always naming index.html explicitly because the bucket serves no directory index), screenshots with alts, and updated_at. The canLaunch predicate the hub reads is: hosted_path && play_url && iframe_src && screenshots.length > 0. If any is missing, the Play button does not render.","8. Hub rebuild and rsync deploy, then live smoke through the real URL (for example [Darklord](/games/darklord/play) at /games/darklord/play): the iframe content renders and no asset answers 400 or above. The probe script is a headless Chromium that counts framenavigated events, listens for pageerror and requestfailed, and flags any response at 400+. A healthy SvelteKit game boots with exactly one document navigation; the July 31 bug produced 390-451 in six seconds, one every ~13ms, with zero console errors."]},{"type":"h2","text":"Bucket facts that bite"},{"type":"p","text":"Three properties of the OVH bucket shape everything above. It serves no directory index, so /games/{slug}/{version}/ is a 403 and every reference must name index.html explicitly; the catalog's iframe_src always does. Public access is a per-object canned ACL because PutBucketPolicy returns NotImplemented on this endpoint. And root-absolute runtime references like /generated/... resolve against the bucket root, not the version prefix, which is why [Darklord](/games/darklord/play) publishes its generated art and fonts to the bucket root as a deliberate, documented exception rather than a bug. Document it or someone will 'fix' it and break darklord's art fetches."},{"type":"p","text":"A fourth fact we added to the runbook after July 31: SvelteKit's base semantics. When paths.relative is true (the default when the *_BASE env var is unset), SvelteKit serializes base as \\"./\\" into the bootstrap. The client router then does pathname.slice(base.length) (two characters) to strip the base, which eats the leading slash of the real path (/games/junk-runner/0.8.0/index.html becomes games/junk-runner/0.8.0/index.html without the leading slash) and from that moment no route can match. Kit gives up and falls back to native navigation, which reloads, which mismatches again, which reloads. Our two working launches that week, [Darklord](/games/darklord/play) and [Polis](/games/polis/play), are plain Vite single-page apps with no kit router, which is the only reason they never hit it. Two characters, \\"./\\", took down three games, and the fix lives in three places: a real base at build time, a [...rest] catch-all route, and goto(resolve(...))."},{"type":"h2","text":"The catalog today"},{"type":"table","caption":"Real status counts from web/games/libs/data/games-catalog.json (18 entries, updated 2026-07-29).","headers":["Status","Count","Who lives there","Probe + hosted"],"rows":[["Released","1","[One Million Girlfriends](/games/one-mil-girls/play) 0.2.15 (branching visual novel, 5 heroines, 10 endings)","released: adapter-static at /games/one-mil-girls/play, bucket at games/one-mil-girls/0.2.15/"],["WIP: hosted (bucket smoke clean)","5","[Junk Runner](/games/junk-runner/play) 0.8.0, [Darklord](/games/darklord/play) 1.0.0, [Hellhunter](/games/hellhunter/play) 1.0.0, [
1Neonbreak](/games/neonbreak/play) 0.10.4, [Polis](/games/polis/play) 1.0.0","all five are on the bucket with zero failing assets; catalog still WIP by quality call"],["WIP: not yet hosted","9","Hegemon, template-canvas2d 0.0.1, template-isometric 0.0.1, template-birds-eye 0.1.0, Doomtap 1.0.0, Football Forever 0.1.0, Hooked Forever 0.1.0, Forever Mulligan 0.1.0, Forever Feast 0.1.0","local builds only, no iframe_src"],["Experimental","3","Capture Anime Girls 0.1.0, Deathrun 2.0.0, Endless Tower Defense 0.1.0","concepts with source, not yet publish candidates"],["Total","18","Every entry desktop-only, DRM-free, no account; target_platform desktop in every row","6 have a live iframe_src, 1 is released"]]},{"type":"p","text":"One honest wrinkle in that table: the five hosted WIP were published to the bucket in the July 31 run at versions 0.8.0 through 1.0.0 and passed live smoke with zero failing assets after the fixes in [three games, one bug](/blog/three-games-one-bug) were applied. The runbook records [Darklord](/games/darklord/play) and [Polis](/games/polis/play) as 'playable on bucket, quality hold' and the other three as 'bucket-playable after base fix', but the catalog status field still says wip. Flipping that field is a quality call a human makes after playing the game end to end, not a fact the pipeline asserts. The catalog is the scoreboard; the runbook is the replay. When we do flip one, the hub rebuild is a static rsync and the [changelog](/blog) records the move, and this article regenerates from the catalog so the table stays current."},{"type":"h2","text":"What the probe actually checks"},{"type":"p","text":"The headless Chromium probe is the only gate we trust after publish because it exercises the real bucket URL, not a local file. It navigates to https://dracon-master.s3.uk.io.cloud.ovh.net/games/{slug}/{version}/index.html, counts framenavigated events (healthy = 1), subscribes to pageerror and requestfailed, collects every response status, and fails the run if any asset answers 400 or above. For SvelteKit games it also walks the in-game router: Junk Runner from menu to the difficulty modal, Hellhunter from FORGE A NEW HERO through town into the dungeon with HUD live, Neonbreak from New Operation through the intro to faction select, all without a full navigation. The hub's own 401 on /api/v1/me for anonymous visitors is expected and ignored; it is the auth check for the platform shell, not the game. We keep the probe recipe in the runbook so anyone on the team can run it with one command and get the same 13ms-per-loop signal we saw on July 31 if the base regresses."},{"type":"h2","text":"What ships next"},{"type":"p","text":"The standing publish rules from July 31 are now in the runbook: the three SvelteKit games must be built with their base-path env vars before every publish, Neonbreak's postbuild passes --absolute-assets, screenshots land before the bucket put, and every catalog flip must include versioned iframe_src plus per-object ACLs. Next up the status ladder are the five hosted WIP, one quality gate at a time. Neonbreak and Polis were the cleanest booters in the post-fix probe; Darklord is close behind despite its bucket-root art exception; Junk Runner and Hellhunter needed the full three-part SvelteKit fix but now boot to one navigation. Behind them in WIP are Hegemon (our strategy epic, longest-running dev saga) and the experimental trio (Endless Tower Defense and Deathrun especially), which will enter the pipeline when their playable loops close. Moves get recorded in the [changelog](/blog) as they happen, and this article is regenerated when the catalog changes, so the table above is a snapshot, not a monument. If you want to see today's truth, open [the arcade](/games) and sort by status."},{"type":"callout","text":"Counts computed from games-catalog.json (18 entries, updated 2026-07-29): 1 released, 14 wip (5 hosted on the OVH bucket), 3 experimental. Pipeline steps, bucket facts, and July 31 outcomes from docs/strategy/GAMES-PIPELINE-2026-07-31.md, the living runbook in the repo. Probe recipe: one navigation, zero page errors, zero assets at 400+, Chromium headless against the versioned bucket index.html."},{"type":"h2","text":"The probe that catches what eyes miss"},{"type":"p","text":"Every publish runs a headless Chromium probe that counts document navigations, listens for pageerror and requestfailed, and flags any response at 400 or above. A healthy game boot produces one navigation, then the game's hash router takes over: [Junk Runner](/games/junk-runner/play) from menu to difficulty modal, [Hellhunter](/games/hellhunter/play) from forge through town into the dungeon, [Neonbreak](/games/neonbreak/play) from New Operation through intro to faction select. The bug that broke three games on July 31 produced 390â451 navigations in six seconds with zero console errors;
1 the probe caught it because it counts what the console does not show. The same probe now gates every publish: one navigation, zero 400s, stable HUD, or the build does not ship. The recipe lives alongside the fix in [its own postmortem](/blog/three-games-one-bug): the next person to hit paths.relative should find it in a search result."},{"type":"h2","text":"What ships and what stays candidate"},{"type":"p","text":"Shipping to the bucket does not automatically promote a game on [the arcade](/games). The [games catalog](/games) tracks readiness separately: prod, wip, candidate, experimental. A game can be hosted at /games/junk-runner/0.8.0 and still list as candidate, which is a quality call, not a hosting one. [One Million Girlfriends](/games/one-mil-girls/play) is prod today; Darklord and Polis are wip Vite apps that never hit the SvelteKit bug; Junk Runner, Hellhunter, and Neonbreak are candidates after their fixes: playable at 0.8.0, 1.0.0, 0.9.0 respectively, with the [changelog](/blog) as the human-readable ship log. The distinction matters for trust: a green launch badge means someone played it end to end on the bucket, not just that the build script exited zero."},{"type":"callout","text":"Pipeline SSOT: games-catalog.json canLaunch = non-experimental + hosted_path + version; hosting.ts mirrors it. Publish requires JR_BASE/HH_BASE/NB_BASE with versioned base path, [...rest] catch-all, and goto(resolve()) sweep. Bucket is OVH; build is SvelteKit 2.x with adapter-static for games. See /games and the pipeline doc for the full recipe."}]`),ta={slug:qt,title:Ut,description:Vt,date:zt,updatedAt:_t,author:Kt,reviewedBy:Jt,family:Yt,tags:Zt,affiliateDisclosure:Xt,sources:Qt,sections:ea},aa="three-games-one-bug",oa="Three games, one bug: the SvelteKit hosting bug that broke our arcade",ra="One SvelteKit default broke three of our games on the same night: 390 to 451 reloads in six seconds, zero console errors. The full postmortem, with the fix.",sa="2026-08-01",ia="2026-08-23",na="Dracon Games Team",la="Dracon Editorial",ha="games",ca=["games","dev-diary","sveltekit","postmortem"],da=!1,ua=[{label:"GAMES-PIPELINE-2026-07-31.md: the 8-step runbook and probe recipe",href:"/games"},{label:"games-catalog.json: 18 entries, hosted builds at games/{slug}/{version}/",href:"/games"},{label:"SvelteKit docs: paths.relative, base, and the $app/paths resolve/asset helpers",href:"https://svelte.dev/docs/kit/$app-paths"}],pa=JSON.parse(`[{"type":"p","text":"On the evening of July 31, 2026, three of our browser games ([Junk Runner](/games/junk-runner/play), [Hellhunter](/games/hellhunter/play), and [Neonbreak](/games/neonbreak/play)) were broken on our OVH bucket in exactly the same way. Each one loaded its index.html, then loaded it again, and again: between 390 and 451 full document reloads in six seconds, one fresh navigation roughly every 13 milliseconds, and not a single console error to explain any of it. This is the postmortem, with the numbers, because the next person to hit this deserves to find it in a search result. It is also the companion to [how a game ships to the Dracon arcade](/blog/dracon-arcade-pipeline), which documents the pipeline that surfaced the bug; this post is the bug."},{"type":"h2","text":"The symptom: a reload loop with no errors"},{"type":"p","text":"Our release probe is a headless Chromium script that counts framenavigated events, listens for pageerror and requestfailed, and flags any response at status 400 or above. A healthy game boot produces one document navigation, then the game's internal hash router takes over (#menu, #town, #battle, all without touching the document). On July 31, Junk Runner 0.8.0 produced 390 to 451 navigations in a six-second window. Hellhunter and Neonbreak were the same. The loop ran about every 13ms, fast enough that the page never visually settled, and the console stayed perfectly clean because nothing was actually throwing. The game was not crashing. It was politely handing itself to the browser's native navigation, over and over, forever. The bucket logs said 200 for every index.html fetch, which made it look healthy if you only checked status codes. The giveaway was the navigation count: one is healthy, 400 is a router that has given up."},{"type":"p","text":"We first noticed it because screenshots were empty. The probe stages PNGs into the build before publishing so they land at games/{slug}/{version}/screenshots/, and the screenshot step was capturing a white page that was mid-reload. A manual open of https://dracon-master.s3.uk.io.cloud.ovh.net/games/junk-runner/0.8.0/index.html in a real browser showed the same: the address bar flickered, the devtools network panel filled with repeated index.html fetches, and the console remained empty. The two games that had shipped the same day and were fine ([Darklord](/games/darklord/play) at 1.0.0 and [Polis](/games/polis/play) at 1.0.0) are plain Vite single-page apps with no SvelteKit router, which is why they were spared. That split (three SvelteKit games broken, two Vite games f
1ine) was the first real clue."},{"type":"h2","text":"Root cause: two characters"},{"type":"p","text":"All three broken games are SvelteKit apps, and all three were built with paths.relative set to true, the default when their base-path env vars (JR_BASE, HH_BASE, NB_BASE) are unset. That serializes base as \\"./\\" into the bootstrap. SvelteKit's client router, on boot, strips the base from the current path with pathname.slice(base.length), and here is the bug: a two-character base eats the leading slash of the real path. If the hosted path is /games/junk-runner/0.8.0/index.html and base is \\"./\\" (length 2), slice(2) yields games/junk-runner/0.8.0/index.html without the leading slash. From that moment no route can ever match any hosting path, because routes are matched against a leading-slash pathname and the stripped pathname no longer has one. Kit's boot gives up and falls back to native navigation. The browser reloads, lands on the same mismatched state, and loops. Two characters, \\"./\\", took down three games at once."},{"type":"p","text":"We confirmed this by inspecting the built bootstrap. With JR_BASE unset, the generated app.html contained base:\\"./\\" and the client runtime did indeed slice two characters. With JR_BASE=/games/junk-runner/0.8.0, the same build emitted base:\\"/games/junk-runner/0.8.0\\" and pathname.slice(base.length) correctly yielded /index.html, a string the router could match. The SvelteKit docs describe paths.relative as 'whether the base path should be relative to the current directory', which is useful for file:// previews but wrong for bucket hosting where the base is a versioned prefix that must be absolute. The fix is to never rely on the default: every future build of these games must set its *_BASE env var before bun run build. It is now a standing rule in the runbook, not a suggestion."},{"type":"h2","text":"The fix: three parts, all required"},{"type":"ul","items":["Build with a real base path. JR_BASE=/games/junk-runner/{version} bun run build (HH_BASE and NB_BASE for the others) makes pathname.slice(base.length) yield /index.html, a string route matching can actually work with. Every future version of these games must be built this way before publish; it is now a standing rule in the runbook. Verify by grepping the built kit manifest for base:\\"/games/.","Add a [...rest] catch-all route with prerender disabled that mounts the same screen-mount component as the home page, so a bucket path like /games/junk-runner/0.8.0/index.html matches a route at all. The game's own hash router (#menu and friends) is unaffected; kit stays in pathname mode. We rejected kit hash-routing (router: { type: 'hash' }) because it would fight the game's existing URL-hash screen router and require rewriting every screen transition.","Replace every goto('/x') with goto(resolve('/x')) using resolve from $app/paths, because kit 2.x goto() does not prepend base and was full-navigating players to origin /town (an S3 403 XML page) in Hellhunter. The subtle part: a literal regex misses variable calls. Neonbreak's menu helper called goto(href), where href was a prop, which full-navigated to /intro until the probe caught it. The sweep that works: grep -rn \\"goto([a-z]\\" src/ | grep -v \\"goto(resolve\\". If it matches, fix it.","For root-absolute static refs, use asset() from $app/paths. Hellhunter's /art/... references in TownBuilding and HeroPortraitCard were 403ing from the bucket root because /art resolves against origin, not the version prefix; asset('/art/hero.png') prepends the base and works at any route depth, which plain relative paths (../../art/) do not once client-side navigation changes the document depth."]},{"type":"p","text":"A note on why all four were required. The base fix alone stops the reload loop but leaves navigation broken for any goto that does not resolve. The [...rest] route alone makes the bucket path match, but without the base the match still fails because the slash is missing. goto(resolve(...)) alone fixes in-app navigation but does not fix the initial boot mismatch. asset() alone fixes art fetches but does not fix routing. We tried applying them singly and watched the probe still flag. Only the set together produced one navigation and zero 400s. The [games catalog](/games) still lists these three as wip, not because the bucket is still broken, but because the quality gate after a fix is a human playthrough, not a probe pass. That playthrough is what flips status to released."},{"type":"h2","text":"The second bug: our own postbuild script"},{"type":"p","text":"One layer down we found a bug of our own making. Our rewrite-static-artifact.mjs postbuild, the step that prepares builds for bucket hosting, was relativizing bare asset literals so chunks load relative to the document. That is fine for a single-route game and broken for a multi-route one, because client-side navigation changes the document's depth and every relative literal resolves somewhere new. Neonbreak's /images and /audio literals were being relativized to ../images and broke on the second navigation; Hellhunter's /art literals escaped the relativizer by prefix accident (/art did not match the /images|/audio pattern), which is the worst kind of working: it passes by luck and fails when someone adds a matched prefix."},{"type":"p","text":"The fix is an opt-in flag, --absolute-assets {prefix}: document-resolved literals (bare quoted paths like \\"/images/foo.png\\" and new URL(\\"/audio/bar.mp3\\", document.baseURI) patterns) become version-absolute (/games/neonbreak/0.
110.4/images/foo.png) while import() and CSS url() stay chunk-relative because file-based resolution is depth-independent and already correct. Neonbreak's postbuild now runs node scripts/rewrite-static-artifact.mjs --absolute-assets /games/neonbreak/{version}; an empty prefix keeps legacy relativizing behavior so no other game is affected. We chose an explicit flag over a global switch because Darklord deliberately publishes to the bucket root (games/darklord/generated/... lives at the bucket root, not under /games/darklord/{version}/generated/) and a global absolute rewrite would have broken its documented exception. The runbook now lists which games pass the flag and which do not, with the reason beside each."},{"type":"h2","text":"What verified looks like"},{"type":"p","text":"After the four fixes, all three games boot with a document-navigation count of exactly one and stay there through full menu-to-gameplay flows: [Junk Runner](/games/junk-runner/play) from menu to the difficulty modal, [Hellhunter](/games/hellhunter/play) from FORGE A NEW HERO through town into the dungeon with its HUD live, [Neonbreak](/games/neonbreak/play) from New Operation through the intro to faction select. Zero responses at 400 or above, zero console errors, zero requestfailed events. The three games are on the bucket and probe-clean at 0.8.0, 1.0.0, and 0.10.4 respectively, though the [games catalog](/games) still lists them as wip (a deliberate quality call, not a hosting one). The publish rules and the probe recipe now live in the pipeline runbook at docs/strategy/GAMES-PIPELINE-2026-07-31.md, which we wrote up for player-visible consumption in [how a game ships to the Dracon arcade](/blog/dracon-arcade-pipeline)."},{"type":"p","text":"If you are shipping SvelteKit to object storage, the checklist we now run before every publish is: base env var set, bootstrap grepped for base:\\"/games/, [...rest] route present, no bare goto( without resolve, no bare /art or /images without asset(), postbuild flag correct for this game's hosting shape, per-object ACLs on every put, iframe_src naming index.html, probe showing one navigation. The July 31 run failed four of those and the probe counted 390-451 reloads at ~13ms. The August runs pass all of them. The difference is visible in the [changelog](/blog) when a catalog flip lands. Until then, the honest status is WIP with a clean bucket, and the honest play buttons are the five WIP-hosted plus the one released on [the arcade](/games)."},{"type":"callout","text":"Numbers as of August 2026: reload counts (390-451 in 6s, roughly 13ms per loop) measured by our headless Chromium probe on the published bucket builds of July 31. Root causes and fixes are documented in the repo at docs/strategy/GAMES-PIPELINE-2026-07-31.md; the player-visible pipeline is at /blog/dracon-arcade-pipeline. All three fixed games are on the OVH bucket at games/{slug}/{version}/index.html and probe-clean; catalog status remains wip by quality gate."}]`),ma={slug:aa,title:oa,description:ra,date:sa,updatedAt:ia,author:na,reviewedBy:la,family:ha,tags:ca,affiliateDisclosure:da,sources:ua,sections:pa},ya="focus-music-by-the-data",fa="What 2,500 tracks of focus music have in common: we ran the numbers",ga="We computed the real stats behind our 2,500-track focus library: BPM bands, mood-tag counts, the 10-track rule, and why only 3 cooks in 250 carry the focus tag.",ba="2026-08-01",wa="2026-08-23",va="Dracon Music Team",ka="Dracon Editorial",xa="music",$a=["music","focus","ambient","data","bpm"],Ta=!1,Aa=[{label:"cookbook.json: 250 cooks, 2,500 tracks (updatedAt 2026-08-23T17:45:24.952Z)",href:"/music"},{label:"Dracon music library: live cook index and recipes",href:"/music/cook"},{label:"Methodology: web/music/scripts/build-cookbook.mjs",href:"/music/library"}],Sa=JSON.parse(`[{"type":"p","text":"Everyone sells focus music. Almost nobody shows their work. Our [music library](/music) is 2,500 tracks organized into 250 curated cooks, and every track keeps its full recipe on file: prompt, genre, mood tags, BPM, key, structure, and whether it is instrumental. So instead of telling you this is great music to work to, we ran the numbers on what the library actually contains. Some of what we found surprised us, and we built the thing. This is the audit we wish every focu
1s playlist came with: counts you can re-run, tempos you can sort by, and recipes you can read before you press play."},{"type":"p","text":"Update (2026-08-23): the library has grown since this piece was first published. The analysis below was computed on 2026-08-01 against 100 cooks and 1,000 tracks; cookbook.json now holds 250 cooks and 2,500 tracks (updatedAt 2026-08-23T17:45:24.952Z). Headline figures are preserved as published so the original analysis remains reproducible, and the methodology section at the end explains how the same queries run against the current 250. Where the current library diverges meaningfully we call it out inline. The biggest shift is tempo: the median cook has moved from 110 BPM to 130 BPM as we added faster, more energetic mixes."},{"type":"h2","text":"Focus is not a mood tag"},{"type":"p","text":"First surprise from the original 100-cook audit: only 3 of the 100 cooks carried the 'focus' mood tag, which worked out to 30 tracks out of 1,000. That ratio still holds at 250 cooks: 3 of 250, or 30 tracks of 2,500, carry 'focus'. They are [Late Night Lo-Fi](/music/cook/late-night-lo-fi) at 75 BPM, [Deep Focus Pulse](/music/cook/deep-focus-pulse) at 60 BPM, and [Pixel Cathedral](/music/cook/pixel-cathedral) at 132 BPM. No new focus-tagged cooks have been added, not by oversight but by design: we tag what the music is, not what you might use it for. The current tag leaderboard is led by intense (64 cooks), dark (45), dreamy (43), aggressive (35), and mechanical (34). Warm (32), anthemic (33), and melancholy (27) still chart, but the long tail has lengthened to 166 distinct mood tags across 250 cooks, up from 82 at 100. We read this as an honest lesson about our own catalog: focus is an outcome, not an ingredient. The music people actually work to hides under tags like chill, ambient, meditative, and nocturnal."},{"type":"p","text":"That outcome framing matters because the three focus cooks themselves do not sound alike. Late Night Lo-Fi is lo-fi hip hop with dusty rhodes piano, muted thumb bass, and brushed drums under vinyl crackle (instrumental, F minor, slow). Deep Focus Pulse is minimal ambient: a C-minor sub-bass pulse at exactly 60 BPM, a slow-evolving arpeggiator, and almost no development by intent. Pixel Cathedral is chiptune: NES pulse waves, square bass, bright four-on-the-floor at 132 BPM, C major, joyful rather than calm. Three mutually incompatible answers to the same question. If you need a starting shelf, those three remain the cleanest A/B test in the [library](/music): one dusty, one minimal, one playful, all tagged focus for the same reason we would tag a chair 'good for reading'. It describes effect, not material."},{"type":"h2","text":"The tempo map"},{"type":"p","text":"We bucket every cook by its BPM because tempo is the one number that predicts feel before you hear a note. At 100 cooks the median was 110 BPM (mean 112.4) with a near-even spread. At 250 cooks the library has shifted faster (the median is now 130 BPM and the mean is 129.6) because the second 150 cooks leaned into high-energy genres like futurecore, drum and bass, metalcore, and witch house. The table below is the current distribution computed directly from cookbook.json today. Compare it to the original seven-band table captioned in the callout and you can see the catalog's center of gravity move."},{"type":"table","caption":"BPM distribution across all 250 cooks, computed from cookbook.json (updatedAt 2026-08-23T17:45:24.952Z).","headers":["BPM band","Cooks","Share","What lives there"],"rows":[["No tempo at all","2","0.8%","noise and drone: [Held Note, For Hours](/music/cook/drone-58) and its companion: rhythm was never invited"],["40-70","15","6.0%","the deep-work end: space ambient, dark ambient, dungeon synth, doom, including [Stratosphere](/music/cook/stratosphere) at 40 BPM and [Iron Cathedral](/music/cook/iron-cathedral) at 50 BPM"],["71-90","29","11.6%","lo-fi, vaporwave, mellow jazz, dub, neo-classical, with [Late Night Lo-Fi](/music/cook/late-night-lo-fi) at 75 BPM and [Rain Diary](/music/cook/rain-diary) at 70 BPM"],["91-110","38","15.2%","the old center of gravity, now the mid-lane: [Vesper Hall](/music/cook/vesper-hall) at 60 BPM actually sits below here, this band holds mid-tempo rock and indie pop"],["111-130","48","19.2%","house, city pop, trance, synthpop, chillwave"],["131-150","55","22.0%","j-core, phonk, witch house, and [Pixel Cathedral](/music/cook/pixel-cathedral) at 132 BPM, the most crowded band today"],["151-240","63","25.2%","drum and bass, breakcore, grindcore, futurecore, and every tempo above 180"]]},{"type":"p","text":"Two details in that table are worth sitting with. First, the four cooks tagged 'ambient' still average 59.5 BPM, the slowest mood cluster in the library, unchanged from the 100-cook audit despite the overall acceleration. They are Deep Focus Pulse (60), Iron Cathedral (50), Lantern in the Dark (88), and Stratosphere (40). The three tagged 'focus' still average 89 BPM (75, 60, 132). Second, the genuinely useful focus shelf is not the tag at all but the intersection of 'fully instrumental' and 'at or under 100 BPM'. At 100 cooks that shelf held 23 c
1ooks; at 250 it holds 31 cooks. It is the shelf we recommend if lyrics steal your attention, and it stretches from Held Note, For Hours at no tempo through Stratosphere at 40 to the 100 BPM ceiling. Open the [full cook index](/music/cook) and you can filter that shelf by reading each cook's BPM, key, and instrumental flag before you press play, which is the point of keeping recipes at all."},{"type":"h2","text":"Ten tracks, no exceptions"},{"type":"p","text":"Every cook in the library holds exactly 10 tracks. At 100 cooks the minimum, maximum, and average were all 10; at 250 they still are. We enforce this in web/music/scripts/build-cookbook.mjs: a cook is not considered complete until its 10 audio keys and 10 generation records exist, and the player expects 10. That constraint is why the library can claim 2,500 tracks without hand-waving: 250 Ã 10, auditable as 250 folders under audio/ and 2,500 song entries in cookbook.json. The [music library view](/music/library) lists all 250 with their 10-track grids; the [cooks index](/music/cooks) is the same data in a denser layout if you want to skim faster."},{"type":"p","text":"The other discipline is genre spread. At 100 cooks there were 99 distinct genre labels and only one repeated: dark ambient (Iron Cathedral and [Catacombs Lit Only by Phone](/music/cook/catacombs-59)). At 250 cooks the library has 230 distinct genre labels (almost one per cook) with the largest cluster still tiny: futurecore at 5 cooks, then dark ambient at 3, denpa futurecore at 3, and a handful of doubles (lo-fi hip hop, synthwave, metalcore, uplifting trance, drum and bass each at 2). In other words, the curation process rarely repeats itself. Even the three focus-tagged cooks share no genre: lo-fi hip hop, minimal ambient, and chiptune are three mutually incompatible answers to the same question, by intent. When we add a new cook we write its recipe prompt, genre, and mood tags before any audio is generated, so duplication is visible early and we can steer toward uncovered space."},{"type":"p","text":"Who sings matters for focus. At 100 cooks, 53 cooks were fully instrumental, 41 sang in English, and 6 sang in constructed languages. At 250, 89 cooks are fully instrumental (35.6%). Of the remaining 161 with vocals, the vocalLanguage field breaks as: instrumental flag false but vocal rendering as gibberish-anime (63 cooks), english (51), english-lyrics (33), japanese (8), invented-phonetic (3), latin-fake (3), and 17 with no language tag at the recipe level because they predate that field. The gibberish-anime and invented-phonetic cooks are a genuine feature if lyrics steal your attention: you get the texture of a human voice with no words to follow. The most common key in the library is now F minor (30 cooks), followed by E minor (26), A minor (24), and D minor (22): D minor led at 100, F minor leads at 250. Nobody planned either; the generator and the curators simply landed there."},{"type":"h2","text":"What the tags actually say"},{"type":"p","text":"With 166 distinct mood tags the library is a better map of feeling than any single tag. At 100 cooks the top tags were warm (28), anthemic (16), dreamy (15), melancholy (15). At 250 the top is intense (64 cooks, 25.6%), then dark (45), dreamy (43), aggressive (35), mechanical (34), anthemic (33), warm (32), nocturnal (32), agitated (31), neon (30), cinematic (30), chaotic (28), melancholy (27), emotional (25). The shift reflects the second batch's heavier, more cinematic brief, but the practical takeaway is unchanged: if you need calm, do not type 'focus' into search and expect the system to read your mind. Filter by what the music is: meditative (13 cooks), dreamy (43), nocturnal (32), chill (8), ambient (4), and by tempo. Stratosphere is dreamy + sacred + ambient at 40 BPM; Iron Cathedral is dark + ambient + melancholy at 50; Vesper Hall is melancholy + dreamy + sacred at 60; Rain Diary is melancholy + dreamy at 70. Those tag combinations are more predictive than any single marketing word."},{"type":"p","text":"We use mood tags in two ways while curating. First, each cook's recipe lists 2-4 moods up front (for example, Stratosphere lists ambient, sacred, dreamy; Iron Cathedral lists dark, ambient, melancholy). Second, we audit the tag distribution after each batch and intentionally commission cooks that stretch uncovered feelings. That is
1why the slow, meditative shelf still exists even though the median tempo rose: we kept adding at 40-70 BPM because the library without them would be lying about its range. You can see the audit directly: every cook page at [music/cook/{slug}](/music/cook/stratosphere) shows its mood chips, BPM, key, and the exact prompt that generated it, so you can judge whether our tag matches your sense before you commit 40 minutes to a cook."},{"type":"h2","text":"How the cookbook is built, and how to re-run these numbers"},{"type":"p","text":"The single source of truth is web/music/libs/data/cookbook.json. It is built by web/music/scripts/build-cookbook.mjs from the per-cook recipe records and the generated audio keys under web/music/out/audio/. Each cook entry stores id, name, slug, description, recipe (prompt, genre, mood array, instruments, tempo label, bpm, key, structure, instrumental boolean, vocalLanguage), cover, and gated flag; each song entry stores id, cookId, title, audioKey, coverKey, generationParams (model music-2.6-free, prompt, genre, mood, instruments, bpm, key, structure, instrumental, lengthSeconds), and createdAt. Version is 1, updatedAt is 2026-08-23T17:45:24.952Z, source is the build script path. No other file is canonical: the player, the search index, and these articles all read the same JSON."},{"type":"p","text":"To reproduce every number in this article, cat web/music/libs/data/cookbook.json and count. The BPM bands query is: bucket by recipe.bpm (0 = no tempo, else 40-70, 71-90, 91-110, 111-130, 131-150, 151-240). Median and mean are over integer BPMs excluding zeros. Mood counts are a frequency table over recipe.mood (a cook can carry multiple). Instrumental count is where recipe.instrumental is true; vocalLanguage distribution is over recipe.vocalLanguage. Genre distinct is over recipe.genre. Key distribution is over recipe.key. The 10-track rule is verified by grouping songs by cookId: every group has size 10, no exceptions. We keep cookbook.json in git so any revision of this article can be diffed against the data revision that produced it; the callout below is the provenance stamp for this version."},{"type":"h2","text":"How to use this if you want to work"},{"type":"p","text":"Open the [library](/music) and sort by headspace, not hype. Need flow? Start with the three focus-tagged cooks above: [Late Night Lo-Fi](/music/cook/late-night-lo-fi) for a warm, dusty room, [Deep Focus Pulse](/music/cook/deep-focus-pulse) for a clock that refuses to surprise you, [Pixel Cathedral](/music/cook/pixel-cathedral) if you focus better with a little joy. Need slower? Filter the [full cook index](/music/cook) for instrumental and BPM ⤠100 (31 cooks at 250) and audition [Stratosphere](/music/cook/stratosphere) at 40 BPM, [Iron Cathedral](/music/cook/iron-cathedral) at 50, [Deep Focus Pulse](/music/cook/deep-focus-pulse) at 60, [Vesper Hall](/music/cook/vesper-hall) at 60, or [Rain Diary](/music/cook/rain-diary) at 70. Each lists its BPM, key, and mood chips before you press play. Need the opposite? The 131-150 and 151-240 bands are now the library's largest, so if slow makes you sleepy, start at 120 and climb. No account, no ads, no algorithm deciding you have had enough focus for one day. Just recipes you can read and a player that respects them."},{"type":"callout","text":"All numbers computed from cookbook.json (version 1, updatedAt 2026-08-23T17:45:24.952Z, source: web/music/scripts/build-cookbook.mjs): 250 cooks, 2,500 tracks, every cook exactly 10 tracks. Historical figures (100 cooks, 1,000 tracks, median 110 BPM, mean 112.4) are preserved as published 2026-08-01 and reproducible by checking out that git revision. Re-run the same queries against the file and you will get the same answers: the cookbook is the single source of truth for the player."}]`),Pa={slug:ya,title:fa,description:ga,date:ba,updatedAt:wa,author:va,reviewedBy:ka,family:xa,tags:$a,affiliateDisclosure:Ta,sources:Aa,sections:Sa},Ia="sleep-music-cooks",Da="Music to fall asleep to, built from recipes",Ca="Seven sleep-friendly cooks from our 2,500-track recipe library: a 40 BPM space drift, a note held for hours, dark ambient with a shadow, and honest caveats.",Oa="2026-08-01",Ba="2026-08-23",Ma="Dracon Music Team",Ea="Dracon Editorial",Na="music",Ra=["music","sleep","ambient","drone","night"],Wa=!1,Fa=[{label:"cookbook.json: 250 cooks, 2,500 tracks (updatedAt 2026-08-23T17:45:24.952Z)",href:"/music"},{label:"Sleep foundation: music and sleep: tempo, structure, and arousal",href:"https://www.sleepfoundation.org/bedroom-environment/best-music-for-sleep"},{label:"Dracon cooks: Stratosphere, drone-58, Iron Cathedral, Vesper Hall",href:"/music/cook"}],La=JSON.parse(`[{"type":"p","text":"Sleep music has a trust problem. The big playlists promise eight hours of gentle piano and quietly swap in ads at 3AM. Our approach is different on a structural level: the [Dracon music library](/music) is built from recipes, every track generated from a stored prompt with its BPM, mood tags, and key kept on file. That means we can do something a playlist curator cannot: point at the exact cooks that are slow, quiet, and repetitive by design, and show you the recipe that makes them that way. This is not a mood, it is a specification. If a cook says 40 BPM, E minor, no rhythm, you can hear that it is 40 BPM, E minor, with no rhythm."},{"type":"p","text":"Update (2026-08-23): the library has grown since this guide was first written. The sleep shelf below was chosen from 100 cooks; cookbook.json now holds 250 cooks and 2,500 tracks (updatedAt 2026-08-23T17:45:24.952Z) with 166 mood tags. The seven picks are unchanged (they remain the slowest, most patient cooks in the enlarged library), and the caveats still apply. The expanded counts in the table caption and in the 'slow end' section reflect the current 250; original 100-cook figures are noted inline so the curation logic remains reproducible."},{"type":"h2","text":"The slow end of the library"},{"type":"p","text":"Out of 250 cooks, 31 run at 80 BPM or slower plus 2 with no tempo at all, which is roughly resting-heart-rate territory and below. The absolute floor is 40 BPM (about half the speed of a typical ballad), occupied by [Stratosphere](/music/cook/stratosphere) and [Catacombs Lit Only by Phone](/music/cook/catacombs-59). On the tag side, 13 cooks are marked meditative (130 tracks), 32 are nocturnal, and 43 are dreamy. Two cooks have no BPM at all: [Held Note, For Hours](/music/cook/drone-58) and its sibling noise-57, both drone. This is the shelf we reach for when the day is done. Of the 31 slow instrumental cooks (a cook is instrumental and â¤100 BPM), we tested evenings against seven and kept notes. Here are the seven, honestly described, sorted by tempo so you can feel the descent."},{"type":"table","caption":"The sleep shelf: seven cooks from cookbook.json, sorted by tempo (250-cook library, updatedAt 2026-08-23).","headers":["Cook","Tempo","Key","Genre","What it actually is"],"rows":[["[Held Note, For Hours](/music/cook/drone-58)","none","D","drone","One sustained tone with slowly shifting overtones. No melody, no rhythm, no percussion. The bell still ringing after you stop hitting it."],["[Stratosphere](/music/cook/stratosphere)","40 BPM","E minor","space ambient","Long evolving pads and deep sub-bass. Granular texture from field recordings. The view from 80km up."],["[Iron Cathedral](/music/cook/iron-cathedral)","50 BPM","E minor","dark ambient","Drone with metallic hits and a ghostly choir. Subsonic rumble. Not cheerful, deeply calm."],["[Deep Focus Pulse](/music/cook/deep-focus-pulse)","60 BPM","C minor","minimal ambient","A pulse that refuses to develop. Slow-evolving arpeggiator over a sub-bass pulse at exactly resting heart rate."],["[Vesper Hall](/music/cook/vesper-hall)","60 BPM","D minor","chamber classical","Solo cello with string quartet. Bach-like counterpoint, slow and reflective. The empty concert hall at dusk."],["[Rain Diary](/music/cook/rain-diary)","70 BPM","B-flat minor","neo-classical","Solo piano with sparse string swells. Long sustain pedal, confessional arpeggios. An October letter, unsent."],["[Late Night Lo-Fi](/music/cook/late-night-lo-fi)","75 BPM","F minor","lo-fi hip hop","Dusty rhodes, muted bass, brushed drums, vinyl crackle. Tape saturation. The 1AM study session, quieter than it sounds."]]},{"type":"p","text":"A practical filter if you want to build your own sleep
1shelf beyond these seven: in the [full cook index](/music/cook) look for instrumental true plus BPM ⤠80 (31 cooks) or mood tags meditative, nocturnal, dreamy. Stratosphere is the intersection of all three (instrumental, 40 BPM, ambient + sacred + dreamy), which is why it leads this list. Vesper Hall and Rain Diary are the melodic exceptions: they have tunes, but both sit at 60-70 BPM, both are instrumental, and both keep their dynamics flat so the tune does not become a surprise."},{"type":"h2","text":"Honest notes from the person who picked these"},{"type":"p","text":"Stratosphere and Held Note, For Hours are the purest sleep candidates we have: one is the slowest pitched cook in the library, the other literally has no tempo. Held Note is the one we test naps against. Its recipe record reads 'Drone, sustained bass drone in D, slow-shifting overtone synth, Tibetan singing bowl sample at the start, tape hiss underneath, no melody, no rhythm, no percussion', and its own description compares it to a bell still ringing after you stop hitting it. If that sounds like nothing, that is exactly the point. We have fallen asleep to it on an office couch without meaning to, which we count as a pass. It is 10 tracks of almost nothing, each one a different overtone coloring the same held D, and it is the least likely cook in the library to surprise you at minute 23."},{"type":"p","text":"Iron Cathedral is the honest oddball. Fifty BPM of dark ambient with metallic hits and a ghostly choir is not everyone's lullaby, but if spa playlists make your teeth hurt, it works precisely because it has a shadow. The prompt specifies 'deep evolving synth pad, distant industrial metallic hits, ghostly choir texture, subsonic rumble, no rush anywhere'. The effect is less 'relax' and more 'the cathedral is empty and you are safe in it'. We recommend it for people who find gentle piano anxious-making because gentle piano is trying too hard to be gentle. Iron Cathedral is not trying to be anything; it simply is slow, low, and patient. E minor helps. The whole cook stays in the chest, never the head."},{"type":"p","text":"Deep Focus Pulse was built for work, not sleep, yet its whole design is a resting-tempo pulse that never surprises you, which is all sleep asks of music. At 60 BPM it sits exactly at a resting heart rate; at C minor it sits low in the keyboard; its structure never develops beyond a slow-evolving arpeggiator over a sub-bass pulse. We fall asleep to it differently than to Stratosphere. Stratosphere dissolves you, Deep Focus Pulse holds you still. Vesper Hall and Rain Diary are the melodic picks, for people who need a tune to let go of the day. Vesper Hall is a solo cello with string quartet, D minor, 60 BPM, Bach-like counterpoint at a tempo that leaves air between notes. Rain Diary is solo piano in B-flat minor with sparse string swells, 70 BPM, long sustain pedal, confessionally slow. One caveat for both: their descriptions are honest (Vesper Hall is 'the empty concert hall at dusk' and Rain Diary is 'an October letter, unsent'), and both are tagged melancholy and dreamy, so if sad-beautiful keeps you awake thinking, skip ahead. Late Night Lo-Fi is the gateway cook: it has a beat, but a brushed 75 BPM beat under vinyl crackle and tape saturation, in F minor, which is why it has been the library's default evening listen since the beginning. The beat is felt more than heard, and the rhodes never plays a busy phrase."},{"type":"p","text":"What we deliberately left off: [Catacombs Lit Only by Phone](/music/cook/catacombs-59) ties Stratosphere at 40 BPM and its recipe promises 'no rhythm', which sounds perfect until you read the rest: low strings, breathy pads, dripping water, distant clinks, and the sound of being alone under a city at night. Statistically it qualifies for this list and at 40 BPM, B-flat minor, dark ambient, it is slow enough. We are not recommending it for sleep unless you are that specific person who finds dripping water and distant metal clinks soporific rather than alerting. You know who you are. The same goes for the second no-tempo cook, noise-57 at 0 BPM. It is texture without pitch or tempo, and while some people sleep to noise, most do not, so we left it off the core seven and mention it here for completeness."},{"type":"h2","text":"What sleep science suggests, and where recipes help"},{"type":"p","text":"We are not clinicians, so we treat sleep literature as a design input, not a prescription. The consistent findings we design against are modest: lower tempo tends to lower arousal, lower dynamic range tends to reduce awakenings, repetitive structure with little surprise tends to let attention detach, and absence of lyrics tends to reduce semantic engagement that keeps the brain parsing. Those four map directly onto recipe fields we already store. Tempo maps to BPM (we pick 40-75 BPM for sleep, or none at all); dynamics maps to prompt language like 'sparse', 'distant', 'subtle', and to structure tags that avoid builds; repetition maps to structure ('loop-2bars-loop-2bars' or a drone with no structure at all); lyrics maps to instrumental true and vocalLanguage instrumental. Every sleep pick above is instrumental true, by policy (no gibberish-anime, no English, no Japanese in this list), because even unintelligible vocal texture is a little more to parse at midnight than a pad or a piano."},{"type":"p","text":"Key and harmony matter less in the literature than tempo and repetition, but we keep them on file because they predict feel. Five of the seven sleep picks are in minor keys (E minor, C minor, D minor, B-flat minor, F minor), not because minor is sleepier, but because minor at slow tempo tends to sit lower in the mix and uses fewer high harmonics that cut through a quiet room. Stratosphere in E minor and Iron Cathedral in E minor both live in the sub-bass and low pad region by prompt, so the key choice reinfor
1ces the orchestration rather than driving it. If you are sensitive to brightness at night, filter by key in the [library](/music/library): F minor and E minor at 40-60 BPM will be darker than C major at the same tempo, and you can hear that before you commit to a full cook."},{"type":"h2","text":"How to listen without waking yourself up"},{"type":"p","text":"To listen: open any of the cooks above, or browse the [full cook index](/music/cook) and look for the mood tags meditative, nocturnal, and dreamy. Start quieter than you think you need. These cooks are mastered with headroom so a low phone volume still carries the pad without the metallic hit in Iron Cathedral ever punching through. Set the player to loop the cook rather than autoplay next; a 10-track cook is 40-50 minutes, and a second cook at a different tempo is more likely to wake you than the same texture continuing. No account, no ads, and nothing that swaps in at 3AM except your own thoughts, which our data cannot help with. If you want to build a personal sleep shelf, save 3-4 cooks that work for you (we keep Stratosphere, Held Note, Vesper Hall, and Late Night Lo-Fi in rotation) and let familiarity do the work that novelty cannot."},{"type":"callout","text":"Cook names, tempos, keys, genres, and quoted descriptions come from cookbook.json (version 1, updatedAt 2026-08-23T17:45:24.952Z, source: web/music/scripts/build-cookbook.mjs): 250 cooks, 2,500 tracks, every cook exactly 10 tracks. Sleep notes above are lived experience from evening testing, not medical advice. If sleep difficulties persist, speak to a clinician; our receipts cover music, not medicine."}]`),ja={slug:Ia,title:Da,description:Ca,date:Oa,updatedAt:Ba,author:Ma,reviewedBy:Ea,family:Na,tags:Ra,affiliateDisclosure:Wa,sources:Fa,sections:La},Ha="vps-sla-fine-print",Ga="We read the SLA fine print of 12 VPS providers so you don't have to",qa="Marketing pages say 99.9%. Contracts say things like 95%, or nothing at all. Every published uptime commitment across our 12-provider VPS catalog, read from the actual legal documents.",Ua="2026-08-22",Va="2026-08-23",za="Dracon Research Team",_a="Dracon Editorial",Ka="infrastru
1cture",Ja=["vps","sla","uptime","hosting","transparency"],Ya=!1,Za=[{label:"vps-catalog.json (verifiedAt 2026-08-22: 12 providers, 8 cloud + 4 dedicated)",href:"/tools/vps-compare"},{label:"fx.ts EURâUSD 1.08 (as-of 2026-08-20, shared FX hint for ranking)",href:"/tools/vps-compare"},{label:"Contabo Cloud VPS S â¬4.99, contabo.com/vps-hosting (4 vCPU / 8 GB / 32 TB)",href:"https://contabo.com/en/product/cloud-vps/"}],Xa=[{type:"p",text:"Every hosting marketing page has a number on it. Very few contracts do. An SLA (service level agreement) is the only part of a provider's uptime story that is legally theirs, and the gap between the two can be enormous. We went through the published SLAs for all twelve providers in [our VPS comparison](/tools/vps-compare): eight cloud providers and four dedicated lines, from Hetzner to Contabo to Akamai's Linode. Some of what we found surprised us: one major budget provider guarantees just 95%, two publish no SLA at all, and the industry's standard remedy for broken uptime is a credit on your next bill. Rarely cash back. This article is the annotated reading, with math, edge cases, and the capture notes so you can verify every claim without opening twelve legal PDFs yourself."},{type:"h2",text:"The full board"},{type:"table",caption:"Published SLA commitments, captured 2026-08-20â¦22 from each provider's own legal or SLA pages. Source of truth: our vps-catalog.json (verifiedAt 2026-08-22) with per-row provenance notes.",headers:["Provider","Published commitment","What it actually means"],rows:[["DigitalOcean","99.99% / month","Per-Droplet instance SLA: among the strongest commitments in the group"],["Linode (Akamai)","99.99% / month GA services","Applies to generally-available services; limited-availability services get 99%"],["Vultr","100% host-node + network",'Downtime credits when your host node or network fails. But "100%" covers those components, not everything'],["OVHcloud Advance (dedicated)","99.95% / month","Advance bare-metal range; credit-based"],["Hetzner Cloud","99.9% / month","Per cloud server, credit-based"],["Hostinger VPS","99.9% / month","Service uptime guarantee per their legal agreement"],["OVHcloud Public Cloud","99.9%","Public Cloud services, credit-based"],["InterServer","99.9% VPS uptime","Guarantee on the VPS line"],["netcup","⥠99.9% annual average","Guaranteed average annual minimum availability, measured over a year, not per month"],["Contabo","95% in T&C","See below. This one deserves its own section"],["BuyVM","None published","No SLA found in their terms (checked 2026-08-22)"],["Hetzner Dedicated (Robot)","None published","SLA applies to the cloud line only; the dedicated Robot line carries no published uptime guarantee"]]},{type:"h2",text:"The 95% outlier"},{type:"p",text:"Contabo's terms and conditions guarantee 95% availability. That is not a typo and it is not our paraphrase. It is their own knowledge base wording, captured into our catalog with a dated provenance note on 2026-08-22 and sourced to their public T&C. To appreciate the difference: 95% monthly availability allows about 36 hours of downtime in a 30-day month. A 99.9% commitment allows roughly 43 minutes. A 99.99% commitment allows about four minutes. Contabo remains genuinely popular because the hardware-per-euro ratio is aggressive. Their smallest catalog plan is 4 vCPU / 8 GB RAM / 32 TB bandwidth at â¬4.99/month (listed as EUR 4.40 in the catalog's net-of-VAT capture, displayed as â¬4.99 incl. VAT on their storefront, verified via [contabo.com/vps-hosting](https://contabo.com/en/product/cloud-vps/)). But an SLA is the part of the deal that says what happens when things break, and this one says: quite a lot of breakage is within contract. If you run background workers that retry, 95% can be a fine economic trade. If you run a checkout or a game lobby, that 36-hour contractual window is the number to carry into your incident math."},{type:"callout",text:"The math: 5% of a 30-day month is 36 hours. 0.1% is 43 minutes. 0.01% is 4.3 minutes. A single digit between 95 and 99.99 is worth about 500à in contractual downtime tolerance. At 95% you are contractually agreeing that a day and a half offline per month is acceptable service."},{type:"h2",text:"When there is nothing to read"},{type:"h2",text:"Credits, not refunds"},{type:"ul",items:["Check the measurement window: monthly percentages let one bad weekend eat the whole allowance; annual averages (netcup's â¥99.9%) smooth spikes over a year but let a single bad month hide inside twelve good ones.","Check the exclusions:
1scheduled maintenance, your own configuration, upstream DDoS mitigation, and 'limited availability' services are routinely outside the number. Linode's 99% vs 99.99% split is exactly this.","Check the remedy: credit schedules usually cap out well below your actual monthly cost, require you to open a ticket within a claim window (often 30 days), and pay only in future service.","Check the scope: per-instance (DigitalOcean's Droplet SLA) beats per-platform averages; component-scoped 100% (Vultr's host-node + network) is excellent for those parts and silent about the rest."]},{type:"h2",text:"Who actually bears this risk?"},{type:"p",text:"We get asked whether a thin SLA means a provider is bad. It does not. It means the risk allocation is explicit and sits with you. If you run a side project, a staging box, or a batch renderer that retries, Contabo's 95% at â¬4.99 is an outstanding economic trade. You are buying raw compute per euro and self-insuring uptime with architecture (restarts, multi-node, backups) rather than with a contract. If you run a checkout, an API that external customers poll, or a multiplayer lobby with a live population, you are buying contractual uptime first and raw compute second, so a 99.99% per-Droplet promise with defined credits belongs near the top of your filter, even if it costs more per vCPU. The same portfolio thinking applies across tools: a European founder who values sovereignty might accept Hetzner or Contabo's EUR pricing (normalized in our rankings at the fixed 1.08 EUR/USD hint from `fx.ts`, as-of 2026-08-20) and offset the weaker SLA with a cheaper hot standby elsewhere, while a team shipping to a global audience might pay Vultr or Linode's premium for denser regions and clearer per-node remedies. Compare the trade live in [our VPS comparison](/tools/vps-compare) or see how we handle promo markup in [the domain TCO tool](/tools/domain-tco)."},{type:"h2",text:"How we captured and verified it"},{type:"p",text:"Every row above comes from `vps-catalog.json` verifiedAt 2026-08-22: twelve providers (eight shared cloud, four dedicated) with live-verified pricing from vendor pricing sheets and GPU plans verified against public APIs (DigitalOcean's pricing page HTML, Linode and Vultr's public plan APIs, sweep 2026-08-22; stale Hetzner/OVHcloud/Contabo GPU rows removed). EUR rows (Hetzner, Contabo, OVHcloud, netcup, Hetzner Robot/OVH Advance) carry `currency: EUR` and are ranking-normalized via the shared `fx.ts` hint at EURâUSD 1.08 (FX_AS_OF 2026-08-20) so comparisons are unit-consistent while native prices stay displayed. The `slaUptime` field itself was captured 2026-08-22 from each vendor's own legal/SLA surface: docs.hetzner.com, digitalocean.com/sla/cpu-droplets, vultr.com/sla, akamai.com/legal/sla-compute, hostinger.com/legal/hosting-agreement, contabo knowledge base via contabo.com/blog, netcup product page, buyvm.net ToS, OVH contract PDF, and interserver.net/vps. Where no commitment exists, the catalog says \"None published\" with the check date rather than inventing coverage. If any vendor updates its terms, the next recapture flips the value and this article gets revised rather than defended. Refreshability is a core property of our editorial factory, documented in the strategy docs and visible in the updatedAt at the top of this page."},{type:"callout",text:"Sources: every commitment above was captured 2026-08-20â¦22 from the provider's own SLA, terms, or contract pages and lives in vps-catalog.json with per-row provenance notes (verifiedAt 2026-08-22). Verified absences are recorded as exactly that (none published) rather than guessed. EURâUSD display hint: 1.08 as-of 2026-08-20 from src/lib/fx.ts. Prices cited: Contabo Cloud VPS S â¬4.99/mo incl. VAT (4 vCPU, 8 GB RAM, 32 TB bandwidth, captured from contabo.com/vps-hosting). Catalog stores EUR 4.40 ex-VAT per its net-of-VAT convention."}],Qa={slug:Ha,title:Ga,description:qa,date:Ua,updatedAt:Va,author:za,reviewedBy:_a,family:Ka,tags:Ja,affiliateDisclosure:Ya,sources:Za,sections:Xa},eo="renewal-trap-ranked",to="The renewal trap, ranked: year-1 â year-2 jumps at 12 domain registrars",ao="The first year is marketing; the second year is the price. We ranked all 12 registrars in our captured catalog by their .com renewal jump, from IONOS's +1900% to Cloudflare's 0%.",oo="2026-08-22",ro="2026-08-23",so="Dracon Research Team",io="Dracon Editorial",no="infrastru
1cture",lo=["domains","registrars","pricing","renewals","transparency"],ho=!1,co=[{label:"domain-tld-catalog.json (verifiedAt 2026-08-20: 384 rows, 12 registrars à 32 TLDs)",href:"/tools/domain-tco"},{label:"domain-tld-compute.ts renewalHikePct: (renewalâyear1)/year1, â when year1=0",href:"/tools/domain-tco"},{label:"fx.ts EURâUSD 1.08 as-of 2026-08-20: EUR renewals normalized for ranking",href:"/tools/domain-tco"}],uo=[{type:"p",text:"Domain pricing has two numbers and only one of them matters long-term. The first-year price is marketing: a loss leader designed to get your card on file. The renewal price is the one you will pay every year for as long as you hold the domain, which for a good domain means effectively forever. We captured every registrar price in [our domain TCO tool](/tools/domain-tco) (12 registrars across 32 TLDs: 384 price rows, each row flagged for ICANN-fee handling and currency, verifiedAt 2026-08-20 from official registrar pricing pages) and computed the honest number the checkout page never shows you: the year-1 â year-2 jump on a .com, plus the ten-year total that actually predicts your bill. This article shows the ranking, explains why the percentage alone can mislead, and publishes the capture methodology so you can check our math."},{type:"h2",text:"The ranking (a .com, year 1 â year 2)"},{type:"table",caption:"Captured from domain-tld-catalog.json (verifiedAt 2026-08-20, 12 registrars à 32 TLDs). Jump = (renewal â year-1) ÷ year-1; EURâUSD normalized at 1.08 for sorting but shown native here. Source of truth lives behind our domain TCO tool.",headers:["Registrar","Year 1","Renewal","Jump","Renewal in USD"],rows:[["IONOS","$1.00","$20.00","+1900%","$20.00"],["GoDaddy","$11.99","$23.19","+93%","$23.19"],["Namecheap","$9.19","$13.55","+47%","$13.55"],["OVHcloud","â¬7.78","â¬10.07","+29%","â $10.88"],["Spaceship","$8.44","$10.75","+27%","$10.75"],["Dynadot","$9.37","$10.67","+14%","$10.67"],["Gandi","â¬10.52","â¬11.90","+13%","â $12.85"],["Hover","$14.81","$15.77","+6%","$15.77"],["Porkbun","$10.11","$10.68","+6%","$10.68"],["NameSilo","$10.18","$10.47","+3%","$10.47"],["Cloudflare Registrar","$9.15","$9.15","0%","$9.15"],["Squarespace Domains","$20.00","$20.00","0%","$20.00"]]},{type:"h2",text:"The $1 domain is a $20 domain"},{type:"p",text:`IONOS's dollar-domain is the purest expression of the shape: $1 year one, $20 every year after: a 1,900% step-up that makes it the most expensive .com in our entire catalog from year two onward. Over the ten years most domains are actually held, that $1 headline becomes $181 ($1 + 9Ã$20). Cloudflare's "boring" flat $9.15 becomes $91.50. The trap works because comparison shoppers sort by year one, and year one is precisely the number the trap is built on. The same pattern repeats on trendier TLDs: IONOS's captured .io jumps +241%, its .dev +147%, its .ai +118%, all captured in the same 2026-08-20 sweep and living in the same catalog you can inspect inside [the TCO tool](/tools/domain-tco). IONOS is not alone; it is just the most legible example of a market-wide pattern where the first-year discount is funded by the renewal.`},{type:"h2",text:"Percent versus dollars: why both numbers matter"},{type:"p",text:"A high percentage jump is not automatically the worst deal, and a low percentage is not automatically good, because percentages scale with the base. GoDaddy's +93% looks scarier than Namecheap's +47%, but GoDaddy renews at $23.19 while Namecheap renews at $13.55. In absolute dollars, GoDaddy costs $9.64 more per year every year after year one, despite the smaller-looking surge in the table's comparison of IONOS vs Squarespace. Conversely, Hover at +6% and Porkbun at +6% look equally flat, but Hover's renewal is $15.77 while Porkbun's is $10.68, a $5.09 annual gap hidden behind an identical percentage. The number that predicts your future bill is the absolute renewal price (or better, the normalized USD renewal: we convert EUR rows at the fixed 1.08 hint from `fx.ts`, as-of 2026-08-20, so Gandi's â¬11.90 correctly compares as â$12.85, not as \"eleven-ish dollars\"). The jump percentage just tells you how much of year one was marketing; the absolute renewal tells you how much of year two will be real. Our compute engine stores both: `renewalHikePct` for the shape of the promo and `annualRenewalUsd` for the sortable truth."},{type:"callout",text:'Honesty in both directions: a flat 0% is not automatically cheap: Squarespace is flat at $20.00, which is the second-most-expensive .com renewal in the catalog despite having "no trap" at all. Always sort by the dollar total (our default is ten-year TCO), not by the percentage.'},{type:"h2",text:"What flat pricing looks like"},{type:"h2",text:"Methodology: 384 rows without guessing"},{type:"p",text:"The catalog is not a scrape with marketing copy pasted in. For 12 registrars (Cloudflare, Porkbun, Spaceship, Dynadot, NameSilo, Namecheap, Gandi, OVHcloud, Hover, Squarespace, IONOS, GoDaddy) we captured 32 high-demand TLDs each (.com, .net, .org, .info, .biz, .pro, .dev, .io, .ai, .app, .co, .store, .online, .site and eighteen more), producing 384 price rows. Each row stores year1Price, renewalPricePerYear, transferPrice, currency (USD or EUR for Gandi/OVHcloud), and an icannFeeIncluded boolean (352 rows inclusive, 32 GoDaddy rows exclusive; more on that in [the ICANN fee piece](/tools/domain-tco)). Prices were hand-verified from official registrar pricing pages on 202
16-08-20 and carry provenance notes; where a transfer price was not published we record the absence rather than substituting the registration price silently. The compute layer notes it explicitly. Our ranking engine (`domain-tld-compute.ts`) consumes the catalog directly: ten-year TCO = year1Cost + renewalAnnual à (yearsâ1), and `renewalHikePct` uses the formula above, with a free-first-year ($0 entry) correctly rendered as â (unbounded) rather than 0%. Details in [the infinite-markup article](/tools/domain-tco). EUR amounts are normalized to USD at the single fixed hint EURâUSD 1.08 from `src/lib/fx.ts` (FX_AS_OF 2026-08-20), so sorting never mixes currencies, while the UI still shows native euros beside their USD equivalent."},{type:"ul",items:["Normalize before sorting: compare annualRenewalUsd, not raw euro versus dollar strings. Otherwise OVHcloud's â¬10.07 looks cheaper than it is by ~8%.","Read the ten-year total, not just year two: a shallow promo on a high base (Squarespace $20 flat) can still lose to a steeper promo on a low base over a holding period.","Check the transfer-out cost before factoring promos: the standard 60-day lock after registration means year one is sunk, and hopping registrars later adds a transfer fee plus a fresh year.","Filter by what matters to you: at-cost wholesale, EU-sovereign billing, free WHOIS privacy, or WebAuthn 2FA. Our tool marks filtered-out registrars ineligible with a reason instead of silently hiding them."]},{type:"h2",text:"Who should care, and what to do"},{type:"callout",text:"Provenance: domain-tld-catalog.json verifiedAt 2026-08-20: 384 rows (12 registrars à 32 TLDs) hand-captured from official pricing pages, each row with capture date, currency, and ICANN-fee flag. EURâUSD normalization: fixed 1.08 as-of 2026-08-20 via src/lib/fx.ts. Compute: domain-tld-compute.ts: renewalHikePct = (annualRenewal â year1)/year1, â for free first year; totalCostUsd normalized for ranking."}],po={slug:eo,title:to,description:ao,date:oo,updatedAt:ro,author:so,reviewedBy:io,family:no,tags:lo,affiliateDisclosure:ho,sources:co,sections:uo},mo="eur-usd-domain-bill",yo="What the exchange rate does to your domain bill: EUR registrars in USD clothing",fo="A â¬10.07 renewal is not a $10.07 renewal. How ignoring the euro/dollar rate misranks European registrars by ~7%, and what fixed ranking looks like.",go="2026-08-22",bo="2026-08-23",wo="Dracon Research Team",vo="Dracon Editorial",ko="infrastru
1cture",xo=["domains","registrars","currency","pricing","methodology"],$o=!1,To=[{label:"domain-tld-catalog.json (verifiedAt 2026-08-20: 384 rows, 12 registrars à 32 TLDs)",href:"/tools/domain-tco"},{label:"fx.ts EURâUSD 1.08, FX_AS_OF 2026-08-20, shared display hint",href:"/tools/domain-tco"},{label:"vps-catalog.json EUR rows (verifiedAt 2026-08-22, same 1.08 hint for VPS ranking)",href:"/tools/vps-compare"}],Ao=[{type:"p",text:'Two of the twelve registrars in [our domain comparison](/tools/domain-tco) (Gandi and OVHcloud) price in euros, because they are European companies with European cost bases, VAT regimes, and billing entities. Everyone else prices in dollars. That sounds like a trivial detail until you try to answer the question the whole tool exists for: which registrar is cheapest? The moment your ranking mixes currencies without converting, it stops being a ranking and becomes a coincidence. A â¬10.07 line sitting next to a $10.47 line is not eight cents cheaper; at the 1.08 EUR/USD rate our engine uses, it is about $10.88 (forty-one cents more expensive), and the misranking propagates into every ten-year total, every sorted board, and every "cheapest" badge on every comparison site that forgets the symbol.'},{type:"h2",text:"The bug we caught in our own rankings"},{type:"p",text:"When we added a \"rank by ongoing $/yr\" view to our tool, our first implementation compared renewal rates across registrars directly: â¬11.90 next to $10.47 as if the symbols were decoration. At the then-current 1.08 EUR/USD rate (the fixed conversion constant our compute engine publishes in `src/lib/fx.ts`, with provenance it calls FX_AS_OF 2026-08-20), Gandi's â¬11.90 .com renewal is really about $12.85, and OVHcloud's â¬10.07 is about $10.88. Comparing the raw euro numbers against American dollar rates understated both by roughly 7â8%, enough to place OVHcloud second-cheapest on renewals when it actually belongs further down the board. We caught it in our own audit pass on 2026-08-22 and normalized every ranking key through the FX rate; the live tool now sorts on USD-normalized values while still displaying native currency beside the conversion. The fix is the same one we already applied in [our VPS comparison](/tools/vps-compare) (where Hetzner, Contabo, and OVHcloud price in euros) and in [our email and storage tools](/tools/email-api-compare) where Scaleway and Brevo/Mailjet bill in euros. One hint, one provenance date, every ranking."},{type:"callout",text:"Fixed does not mean frozen: 1.08 is a transparent display hint, not a prediction. EUR/USD has traded between ~1.05 and ~1.20 in recent years, a 14% swing. We publish the as-of date alongside the number so any reader can re-normalize at a different rate and see how the ranking would move. A site that converts silently with no date is asking you to trust a hidden assumption."},{type:"h2",text:"What the corrected board looks like"},{type:"table",caption:".com renewals, native price vs USD-equivalent at fixed 1.08 EUR/USD (FX_AS_OF 2026-08-20), ranked correctly. Source: domain-tld-catalog.json verifiedAt 2026-08-20 (384 rows) + fx.ts shared hint. Native prices as captured; USD column is derived but displayed.",headers:["Registrar","Native renewal","USD equivalent","True rank","Currency"],rows:[["Cloudflare","$9.15","$9.15","1","USD"],["NameSilo","$10.47","$10.47","2","USD"],["Dynadot","$10.67","$10.67","3","USD"],["Porkbun","$10.68","$10.68","4","USD"],["Spaceship","$10.75","$10.75","5","USD"],["OVHcloud","â¬10.07","â $10.88","6","EUR"],["Gandi","â¬11.90","â $12.85","7","EUR"],["Namecheap","$13.55","$13.55","8","USD"]]},{type:"p",text:"Read that table twice, because the error direction is not intuitive. Naive symbol-blind sorting puts OVHcloud's â¬10.07 between Porkbun ($10.68) and Namecheap ($13.55), apparently second place on renewals at a glance, or at least comfortably mid-table. The honest conversion moves it below four dollar registrars into sixth, behind Spaceship. Seven cents of exchange rate times the wrong assumption did that; at other times in recent years when EUR/USD has been at or above 1.20, the distortion would be 20% instead of 8%: enough to flip OVHcloud behind Namecheap as well. And the effect stacks: at ten domains held ten years, an 8% misranking on a â¬10 renew
1al is â¬80 before compounding. That is not a rounding choice; it is a ranking bug that looks like a rounding choice."},{type:"h2",text:"The part that isn't even about ranking"},{type:"p",text:'For anyone paid in dollars, a euro-denominated registrar is also a floating-rate subscription. Your OVHcloud renewal is â¬10.07 forever in euro terms, but its dollar cost drifts with the market. You are implicitly long EUR/USD every year you hold the domain. Some people actively want that hedge, especially European teams whose revenue is already in euros and who value EU-sovereign billing (Gandi and OVHcloud both flag euSovereign: true in the catalog, just as Hetzner and Contabo do in [our VPS dataset](/tools/vps-compare)). Almost nobody chooses that exposure consciously at domain checkout; a comparison site that hides the currency is choosing it for them. Our approach is to keep the native price visible (â¬10.07 stays â¬10.07) while publishing the normalized sort key beside it, with a tooltip that says "normalized at 1.08 EURâUSD, as-of 2026-08-20" so the conversion never becomes invisible.'},{type:"h2",text:"Methodology: one hint, one date, every tool"},{type:"p",text:"Before the fix, three Dracon tools each carried their own FX hint with slightly different as-of claims: a January-dated mid-market claim in one file, a vague \"2026-08 capture\" in another. The 2026-08-23 provenance audit (R10) collapsed them into the single authority: `src/lib/fx.ts` exports EUR_TO_USD = 1.08 and FX_AS_OF = '2026-08-20', and every other mention must derive from those constants instead of restating its own date. That is why you see the same provenance line in the domain, VPS, object-storage, and email tools: it is the same number from the same file, verified on the same date. Capture cadence is quarterly to match how slowly registrar list prices move; FX itself is reviewed quarterly alongside re-verification."},{type:"ul",items:["Always convert before comparing: the symbol is not decoration, and 'â¬10' is not 'ten-ish dollars': at 1.08 it is $10.80, at 1.20 it is $12.00.",'Surface the rate and its date: a ranking that converts silently is not reproducible. Ours prints "1.08 as-of 2026-08-20" next to the sorted total.',"Beware fixed-rate marketing: some registrars bill in one currency and display another at their own conversion rate plus a spread. We capture billing currency, not display currency.","If you hold many domains for many years, currency drift can move your effective renewal more than most promo discounts save. Model ten years, not one.","Our tool ranks on FX-normalized totals (fixed 1.08 EURâUSD via fx.ts) and displays native prices side by side (checkable, not vibes), live in [the domain TCO tool](/tools/domain-tco)."]},{type:"h2",text:"What to do with this"},{type:"p",text:"If you bill in dollars, filter the [domain table](/tools/domain-tco) to USD-only and then re-add the EUR rows with the conversion visible. You will see exactly how far the normalization moves the Ranking Top 3. If you bill in euros, reverse it: think of the dollar rows as convenience conversions, not your invoice. In either case, prefer registrars that are transparent about billing currency over those that let you toggle display currency without saying which one hits the card. The catalog field we sort on is registrar.currency, not a UI toggle. And if you maintain a portfolio (brand domain, docs, staging, a few defensive TLDs), bring the same normalization discipline to your other infra: [compare VPS](/tools/vps-compare) with the same 1.08 hint (Hetzner's CX22 at â¬3.49 normalizes to â$3.77 before ranking), and treat object-storage's EUR and GBP rows the same way. The full ten-year picture, including where each registrar lands once everything is converted, ICANN fees handled honestly, and promos ignored, is the default view of [the domain TCO tool](/tools/domain-tco)."},{type:"callout",text:"Provenance: domain-tld-catalog.json verifiedAt 2026-08-20: 384 rows (12 registrars à 32 TLDs) captured from official pricing pages. FX: src/lib/fx.ts EUR_TO_USD 1.08, FX_AS_OF 2026-08-20, single authority after R10 audit 2026-08-23. OVHcloud â¬10.07 and Gandi â¬11.90 are .com renewalPricePerYear as captured (native EUR); USD equivalents are derived at 1.08 and rounded to cents."}],So={slug:mo,title:yo,description:fo,date:go,updatedAt:bo,author:wo,reviewedBy:vo,family:ko,tags:xo,affiliateDisclosure:$o,sources:To,sections:Ao},Po="hidden-icann-fee",Io="The hidden ICANN fee: who includes the $0.18 and who tacks it on",Do="Every gTLD registration carries a mandatory $0.18/year ICANN fee. Whether it's already inside the listed price depends entirely on the registrar, and checkout is where you find out.",Co="2026-08-22",Oo="2026-08-23",Bo="Dracon Research Team",Mo="Dracon Editorial",Eo="infrastru
1cture",No=["domains","registrars","pricing","icann","transparency"],Ro=!1,Wo=[{label:"domain-tld-catalog.json (verifiedAt 2026-08-20: 384 rows, icannFeeIncluded per-row flag)",href:"/tools/domain-tco"},{label:"domain-tld-compute.ts single-count logic (ICANN $0.18 à domains à years, only when flag is false)",href:"/tools/domain-tco"},{label:"fx.ts EURâUSD 1.08 (as-of 2026-08-20: EUR rows normalized consistently)",href:"/tools/domain-tco"}],Fo=[{type:"p",text:"There is a small tax hiding inside every generic domain name you own: ICANN (the Internet Corporation for Assigned Names and Numbers) levies a flat $0.18 per domain per year on every registered gTLD (.com, .net, .org, .info, .biz, .app, .dev and the rest). It is mandatory, it is universal, and whether you ever see it as a separate line at checkout depends entirely on how your registrar prices things. Some absorb it into the advertised price; some add it on top, per domain, per year, forever. We captured pricing for all twelve registrars in [our domain TCO tool](/tools/domain-tco) with an explicit per-row flag for which model each one uses (`icannFeeIncluded` true/false across 384 price rows: 12 registrars à 32 TLDs, verifiedAt 2026-08-20), and the answer splits cleanly enough to be honest about in one paragraph and to have fooled us in code for a while."},{type:"h2",text:"Who includes it"},{type:"p",text:"Eleven of the twelve registrars we captured price ICANN-inclusive across their entire catalog: Cloudflare, Porkbun, Spaceship, Dynadot, NameSilo, Namecheap, Gandi, OVHcloud, Hover, Squarespace, and IONOS. That's 352 of the 384 price rows in our catalog. For these registrars, the number on the pricing page is the number on the invoice: $9.15 at Cloudflare is $9.15 all-in, â¬10.07 at OVHcloud is â¬10.07 all-in, $10.68 at Porkbun is $10.68 all-in. The inclusive model makes comparison honest by default: when every site quotes pre-fee numbers, the inclusive registrars look identical to the itemized ones until the itemized one's checkout line appears. We flag it explicitly so [the TCO ranking](/tools/domain-tco) does not need to guess."},{type:"h2",text:"Who adds it on top"},{type:"p",text:"One registrar in our catalog itemizes the fee: GoDaddy marks all 32 of its captured TLD rows as `icannFeeIncluded: false`, so $0.18 per domain per year appears as its own line at checkout. On a single .com that's $0.18 a year. Rounding error. But the fee scales with portfolio size and time: ten domains over ten years is $18 of pure line-item noise ($0.18 à 10 à 10), a hundred domains over ten years is $180, and more importantly, it makes GoDaddy's headline prices look fractionally cheaper than they are at exactly the moment comparison shoppers are reading them. A $11.99 .com is really $12.17; a $23.19 renewal is really $23.37. Over the same ten-year horizon we use for the renewal trap ranking, GoDaddy's headline $23.19 renewal understates the decade by $1.80 per domain. Not enough to swing a single-domain decision, but enough to be the entire gap between two mid-table competitors once the board is normalized to USD via the shared 1.08 hint from `fx.ts`."},{type:"callout",text:"Full transparency about our own tooling: when we first built our domain cost engine, we added the $0.18 fee unconditionally to every registrar's total, double-counting it for the eleven inclusive registrars and overstating their ten-year costs by as much as $18 per ten domains per decade. Our own audit caught it because the catalog carried the inclusion flag but the compute ignored it. The fix shipped 2026-08-22 in domain-tld-compute.ts: the fee is now summed only where icannFeeIncluded !== true: that is, only for the integer billableDomainCount derived from GoDaddy's 32 exclusive rows. We mention this because price-comparison trust is earned by publishing corrections, not just captures."},{type:"h2",text:"Why this matters more than $0.18"},{type:"p",text:`The ICANN fee itself will never decide a purchase. What matters is what the flag reveals: whether a registrar's listed price is a complete price. Itemized fees are not evil by themselves (some argue they make cost structures transparent), but they interact badly with comparison shopping, because aggregators and marketplace listings almost always quote the pre-fee number, whether they intend to or not. Any registrar that adds mandatory fees on top gains a systematic appearance-of-cheapness in every table that doesn't normalize for it. The same pattern shows up with WHOIS-privacy upsells (our catalog stores a per-TLD privacy flag too) and with renew
1al jumps (where the "jump" percentage hides the absolute renewal price): the honest comparison unit is the all-in second-year price, which is exactly what our [TCO rankings](/tools/domain-tco) compute, including the ICANN fee exactly once, from whichever side of the flag it comes, and normalizing EUR rows at 1.08 so Gandi's â¬11.90 (â$12.85) and OVHcloud's â¬10.07 (â$10.88) are compared honestly against dollar rivals.`},{type:"h2",text:"The method, including the mistake"},{type:"p",text:"Our catalog stores `icannFeeIncluded` per price row with capture dates (verifiedAt 2026-08-20 for the current 384-row pass), so the comparison stays checkable rather than anecdotal. The compute step in domain-tld-compute.ts single-counts: icannFeeTotal = $0.18 à icannBillableDomainCount à years, where icannBillableDomainCount counts only domains whose price row has icannFeeIncluded !== true. Before 2026-08-22, the engine initialized icannBillableDomainCount to totalDomainCount and never consulted the flag, identical to the domain-TCO bug that ignored the renewal flag. The self-audit was mechanical: the ledger said \"double-count bug fixed 2026-08-22\" and we proved the fix by computing a ten-domain, ten-year portfolio at two registrars, Porkbun (inclusive) and GoDaddy (exclusive), and asserting that Porkbun's ten-year total no longer moved by $18 when we corrected the flag handling, while GoDaddy's did. That property is now pinned by tests so it cannot regress. Currency handling mirrors the EUR/USD correction from [our FX article](/tools/domain-tco): GoDaddy bills in USD while the EUR-inclusive registrars bill in euros, so icannFeeTotal is applied in the registrar's native currency before the final toUsd step."},{type:"ul",items:["$0.18/domain/year à 10 domains à 10 years = $18: real money only at portfolio scale, but a reliable tell of itemized-pricing habits everywhere else that registrar lists prices.","ICANN fees apply to gTLDs (.com, .dev, .appâ¦) under ICANN's per-transaction fee. Country-code TLDs like .io, .ai or .de are governed by their registries instead and do not carry this line.","If a checkout shows an 'ICANN fee' line, your quoted price was pre-fee everywhere that aggregator compared it. Mentally add $0.18 to every pre-fee headline before comparing.","Our catalog stores the inclusion flag per price row with provenance notes, and our [VPS verification](/tools/vps-compare) applies the same honest-null discipline to SLA presence: no signal, no guess, no filler.","Portfolio check: multiply your real domain count by years held and by $0.18 before you decide a $0.20 price gap matters. At scale it may be the entire $0.20."]},{type:"h2",text:"Who should care"},{type:"p",text:"If you hold one domain for a personal site, ignore the $0.18 entirely and focus on the renewal trap: the $11 gap between NameSilo at $10.47 and Hover at $15.77 matters 60à more than the ICANN line. If you hold a portfolio (a brand domain, docs, staging, plus defensive typos), care about it as a habit signal and as a rounding budget: at thirty .coms held for a decade, inclusive versus exclusive billing is a $54 line, enough to pay a year of [VPS](/tools/vps-compare) on Hetzner's CX22. If you run comparison tooling yourself, care about it as an invariant: inclusive prices must not be double-counted, exclusive ones must not be under-counted, and the test suite should enforce that inclusive registrars are insensitive to the fee flag."},{type:"p",text:"All 384 rows, flags, capture dates, and provenance notes live in the open data behind [the domain TCO tool](/tools/domain-tco). If a registrar changes its pricing model (for instance, if GoDaddy were to become inclusive across its 32 rows or an inclusive registrar were to start itemizing), the next recapture flips the flag, the compute flips the total, and this article gets updated rather than defended. That refreshability is why we version the catalog by verifiedAt and publish the flag rather than burying it."},{type:"callout",text:"Provenance: domain-tld-catalog.json verifiedAt 2026-08-20: 384 rows (12 registrars à 32 TLDs) with per-row icannFeeIncluded. Compute: domain-tld-compute.ts single-count logic shipped 2026-08-22; tests pin inclusive insensitivity. FX: EURâUSD 1.08 as-of 2026-08-20 via fx.ts. Examples: GoDaddy $11.99â$12.17 / $23.19â$23.37 via $0.18 line; at portfolio scale 10Ã10 = $18."}],Lo={slug:Po,title:Io,description:Do,date:Co,updatedAt:Oo,author:Bo,reviewedBy:Mo,family:Eo,tags:No,affiliateDisclosure:Ro,sources:Wo,sections:Fo},jo="infinite-promo-markup",Ho="Free first year = infinite markup: promo domains, dissected",Go="A $0 or $1 first year renders as a 0% 'renewal hike' on most comparison sites. The worst promos look like the best deals anywhere on the internet. Here is the math that fixes it.",qo="2026-08-22",Uo="2026-08-23",Vo="Dracon Research Team",zo="Dracon Editorial",_o="infrastru
1cture",Ko=["domains","pricing","promotions","methodology","transparency"],Jo=!1,Yo=[{label:"domain-tld-catalog.json (verifiedAt 2026-08-20: 384 rows, 12 registrars à 32 TLDs)",href:"/tools/domain-tco"},{label:"domain-tld-compute.ts formatRenewalHikePct: â for $0 entry, finite % otherwise",href:"/tools/domain-tco"},{label:"fx.ts EURâUSD 1.08 as-of 2026-08-20, EU promo renewals normalized",href:"/tools/domain-tco"}],Zo=[{type:"h2",text:"How the math breaks"},{type:"callout",text:`Our tool now reports the $0 case as â (an unbounded hike) rather than pretending it's a number, and pins that behavior in tests so it cannot regress. If you see "â Renewal Spike" in our rankings, it means: entry price â 0, ongoing price very much not 0, and the percentage is undefined. We render the honest bound, not a cosmetic zero.`},{type:"h2",text:"What the promos actually look like"},{type:"table",caption:"Steepest year-1 â renewal jumps in our captured catalog (verifiedAt 2026-08-20, 12 registrars à 32 TLDs). The .store rows renew in the same $50â$91 range. Only the promo depth differs. EUR rows normalized at 1.08 for USD comparison.",headers:["Registrar","TLD","Year 1","Renewal","Jump","Ten-year total"],rows:[["IONOS",".store","$1.00","$79.50","+7850%","$716.50"],["IONOS",".online","$1.00","$62.50","+6150%","$563.50"],["IONOS",".site","$1.00","$57.40","+5640%","$517.60"],["IONOS",".com","$1.00","$20.00","+1900%","$181.00"],["GoDaddy",".store","$5.20","$90.50","+1640%","$819.70"],["OVHcloud",".store","â¬2.98","â¬49.50","+1561%","â â¬448.48"],["Namecheap",".store","$3.82","$61.95","+1522%","$561.37"],["Spaceship",".store","$3.35","$50.90","+1419%","$461.45"]]},{type:"p",text:"Look at what unifies that table: everyone is racing to renewals in the $20â$91 range from different depths of loss-leader. The .store first-year prices range from $1.00 to $5.20 across registrars, while every one of them lands on a steep ongoing price set at or near registry rates plus the registrar's margin. That is the signature of a promo war: the discount competes for your checkout click, and the renewal pays for it. OVHcloud's â¬49.50 renewal on .store, once normalized via `fx.ts` at 1.08, is â$53.46, still behind GoDaddy's $90.50, but the depth of the promo ($1 vs $5.20) does not tell you that. None of these numbers are secret; they're just never shown next to each other in the flows that sell domains, because showing them next to each other kills the promo's magic. The table also exposes why percentages explode as entry approaches zero: IONOS's $1â$79.50 is +7850%, while GoDaddy's $5.20â$90.50 is only +1640%, yet GoDaddy renews eleven dollars higher every year thereafter. Percentage measures marketing depth; renewal measures cost."},{type:"h2",text:"Infinite, not zero: the honest rendering"},{type:"p",text:'Our compute layer (`domain-tld-compute.ts`) handles the edge exactly once and in one place. If year1Cost === 0 and annualRenewal > 0, renewalHikePct is set to Number.POSITIVE_INFINITY, mathematically correct, since any positive annual cost over a zero entry is an unbounded multiple. If year1Cost > 0, the hike is Math.round(((annualRenewal â year1Cost) / year1Cost) * 100). The serializer `formatRenewalHikePct` then renders infinity as the intentional glyph "â" everywhere (table cell, CSV export, and share-link) rather than letting JavaScript\'s "Infinity" leak into a spreadsheet or being normalized to "0". We chose the glyph after watching exports: the HTML page could show "â" while the CSV it generated wrote "Infinity", a cosmetic divergence that made the export look like a bug. Two registrars with simultaneous $0 promos now correctly compare as equal (0 === 0 in the numeric ladder\'s cmpNum, not NaN from Infinity â Infinity), and their final tie-break
1is the next key in the deterministic composite: renewalHikePct is the second key in the ladder, not the first, so a free-first-year pair never outranks a cheaper TCO on percentage alone. The same â handling applies to portfolio math: two domains with one free and one paid entry but the same ten-year total will badge â while sorting identically on totalCostUsd.'},{type:"h2",text:"Ten-year totals are the antidote"},{type:"ul",items:["If a comparison site shows a 0% hike next to a $0 first-year offer, its math is broken. Treat every number on that page with suspicion, not just that row.","Infinity is the honest percentage for a free first year; we render it explicitly as â rather than rounding predation into innocence or hiding it in a blank cell.","Promo depth tells you about marketing budgets, not value: the deeper the first-year discount, the higher the true ongoing cost tends to be. Compare ten-year totals, not first-year headlines.","EUR promo math stacks: IONOS's â¬2.98 â â¬49.50 looks smaller in euros than dollars until you normalize. Then the true gap appears. Check the [FX piece](/tools/domain-tco) for that correction.","Always compute your holding-period total before checkout: 1-year thinking is exactly what the promo is optimized for. 10-year thinking collapses it."]},{type:"h2",text:"Who this protects, and how to shop past it"},{type:"p",text:"If you buy one domain for a personal site, the â badge is a warning label: do not sort by first-year price, and do not let a marketplace that sorts by entry skim you into a registrar whose renewal you never saw. Sort by renewal (annualRenewalUsd) or, better, by ten-year TCO. The same discipline we bring to [VPS SLA tradeoffs](/tools/vps-compare), where â¬4.99 can be excellent compute-per-euro with a 95% contractual window, and to [email deliverability](/tools/email-api-compare) where a free tier can be free per month but capped per day. If you manage a portfolio (brand domain, docs, staging, defensive typos across .store/.online/.site), the promo war taxes you once per TLD; the defense is a rules-based ranking that ignores entry price entirely, which is what our [domain TCO rankings](/tools/domain-tco) give you when you toggle to the renewal ladder. The same â-safe logic applies portfolio-wide: if any row in a mixed-cart average hides a $0 entry, the average hike becomes â rather than a diluted finite number. The flag propagates, not the lie."},{type:"p",text:"Every row cited here is captured data with a timestamp (verifiedAt 2026-08-20, 384 rows), not a scraped marketing claim. And the interactive version lets you flip between [ten-year totals](/tools/domain-tco) and per-year renewal rates so you can watch the promo war collapse into a plain ranking, with ICANN fees single-counted and EUR amounts normalized at the shared 1.08 hint."},{type:"callout",text:'Provenance: domain-tld-catalog.json verifiedAt 2026-08-20: 384 rows (12 registrars à 32 TLDs). Compute: domain-tld-compute.ts: renewalHikePct = (annualRenewalâyear1)/year1, â when year1=0, serialized as "â" (formatRenewalHikePct); single ICANN count and EURâUSD 1.08 handling share the same engine. FX: src/lib/fx.ts EURâUSD 1.08 as-of 2026-08-20.'}],Xo={slug:jo,title:Ho,description:Go,date:qo,updatedAt:Uo,author:Vo,reviewedBy:zo,family:_o,tags:Ko,affiliateDisclosure:Jo,sources:Yo,sections:Zo},Qo="near-tie-feature-scoring",er="When $1.38 cheaper is worse: scoring features into price comparisons",tr="Two cloud storage plans, $1.38 apart on a $556 bill. Which wins? Our answer: price decides, near-ties badge. Why naive 'always cheapest' and old feature-band ranking lie in different ways.",ar="2026-08-22",or="2026-08-23",rr="Dracon Research Team",sr="Dracon Editorial",ir="infrastructure",nr=["methodology","cloud-storage","pricing","transparency"],lr=!1,hr=[{label:"storage-catalog.json (verifiedAt 2026-08-21: 27 vendors, per-row pricingCapturedAt)",href:"/tools/object-storage-compare"},{label:"near-tie.ts (NEAR_TIE_FEATURE_USD $2 band; REVERSED 2026-08-23: badge only)",href:"/tools/object-storage-compare"}
1,{label:"fx.ts EURâUSD 1.08 as-of 2026-08-20: EUR vendors normalized before banding",href:"/tools/object-storage-compare"}],cr=[{type:"p",text:`Pure price ranking has a dirty secret: at the top of the board, it's often noise. In our own [object storage comparison](/tools/object-storage-compare), two plans land within $1.38 of each other on a five-terabyte monthly bill of roughly $556, a 0.25% difference that no invoice forecast on earth will predict accurately. Yet a strict "sort by cost" ranking must declare one the winner, and buyers reasonably read that as "this one is better." The intuitive fix (let features decide inside a tight price band) feels fair until it costs real money: in vector-db we watched Qdrant at $18.62 outrank Hetzner pgvector at $17.89 because both fell in the same $2 band and the richer feature set won. This article is about how we fixed both problems, why naive tolerance comparisons break transitivity, and what "near-tie" now means in our engine: price decides, the band only badges.`},{type:"h2",text:"The case that forced the question"},{type:"p",text:"At our 5 TB storage + 5 TB EU egress scenario (the storage tool's default for a media-heavy side project), AWS S3 Standard computes to $556.59/month and IBM Cloud Object Storage computes to $555.21/month once free tiers and per-GB rates from storage-catalog.json (verifiedAt 2026-08-21) are applied. IBM is cheaper by $1.38, or 0.25%. But the two services are not equivalent products: our catalog captures UI-visible capability dimensions (S3 API compatibility, object lock / WORM, versioning, durability published, SLA published, retention policies, lifecycle automation, storage classes, region spread, ecosystem features like CDN or transcoding), and AWS S3 Standard scores 10 of 10 while IBM Cloud scores 9 in that count (each optional field absent scores zero, never guessed). So which should rank first? A site that sorts by price alone shows you IBM as #1 and you'd never learn what you were giving up for $1.38. A site that let features decide inside the band showed AWS as #1, but then kept that logic everywhere and hid a $0.73 real gap elsewhere."},{type:"h2",text:"Band the prices, then let features argue, and why we reversed it"},{type:"p",text:"From 2026-08-21 until 2026-08-23, our fix treated totals within roughly two dollars as a near-tie: we rounded every plan's computed total into $2 bands (NEAR_TIE_FEATURE_USD = 2 from `src/lib/near-tie.ts`), and inside a band the plan with the richer feature score ranked first; exact cents only decided when features tied, and the vendor slug broke any remaining deadlock. On the S3-versus-IBM case, both totals fell in the same ~$2 band, the richer feature set won, and S3 Standard ranked first despite being nominally more expensive. Outside the band, price ruled exactly as before. Nobody got to hide a $50 difference behind a nice dashboard. The logic was deterministic: a composite key [band, -featureScore, exact cents, slug] gave every plan one position regardless of input order. We shipped it, it pinned with tests in both directions (richer-wins-inside-band, cheaper-wins-outside), and it felt principled, until a sibling tool exposed the cost."},{type:"callout",text:"Why a band instead of a percentage tolerance? Because tolerance comparisons can form cycles: AâB and BâC but A>C at a fixed tolerance, and then your sort order depends on the order rows arrived in. Banded keys give every plan one deterministic position (same input, same board, every time) via a valid total order. We learned this the hard way twice: once in domain pricing's R5 fix (InfinityâInfinity returning NaN), once here, before converging on the exact-cents + slug comparator pinned by tests."},{type:"h2",text:"What counts as a feature?"},{type:"p",text:"Only what we actually captured and show in the tool's UI, and only fields that are visible to the buyer before they pay. For storage, storageFeatureScore() counts: S3 API compatibility (1), object lock / WORM (1), versioning (1), published durability string non-empty (1), published SLA non-empty (1), ecosystem feature non-empty (1), plus region count capped at 8, total up to 14, but the AWS-vs-IBM gap in this scenario is 10 vs 9 on the ten UI-visible dimensions we narrate to buyers. Each dimension counts one point where the vendor offers the capability; absent optional fields score zero rather than being guessed. The scoring is deliberately dumb: it doesn't weight dimensions or editorialize about which features matter, because weighting would be an opinion pretending to be a measurement. Its only job is to say, honestly and mechanically, \"within this price band, this product does more of the things we can verify versus this product that does fewer.\" The full rule lives in code (`src/lib/near-tie.ts` and `src/lib/storage-compute.ts:storageFeatureScore`) with tests pinning the detection: two vendors $1.38 apart badge as near-ties, two $5 apart do not, and the richer features show up alongside the badge rather than as a reorder."},{type:"h2",text:"The general lesson"},{type:"ul",items:['"Cheapest" is only well-defined when products are identical; the closer the prices, the more the decision is actually about features, exactly where naive sort
1-by-cents hides the most information and band-reordering hides price.',"Any comparison ranking needs an explicit tie-break policy that is a valid total order. If a site doesn't publish one, its top-of-board ordering is partly arbitrary and may wobble with input order or locale.","Determinism matters as much as correctness: the same catalog plus the same workload must always produce the same board, regardless of row order: our band keys plus the equality-first cmpNum (Infinity-safe, NaN-free) guarantee it.","Feature scores must come from captured, displayable facts, not affiliate weighting or editorial preference. Ours are countable from the catalog and capped so region count cannot dominate.",`Surface price first, features second: a badge that says "$1.38 apart: compare 10 vs 9 capabilities" respects both the buyer's wallet and their autonomy, while a silent reorder respects neither.`]},{type:"h2",text:"Methodology you can replay"},{type:"p",text:'If you disagree with a two-dollar band, the numbers to argue with are published right there, which is the whole point. Change the band to $1 or $5 in the open code and the same data produces a predictably different set of badges, still deterministically, still price-first. That arguability is stronger than any single "correct" band width, because it turns a subjective design choice into a visible parameter rather than a hidden opinion. Try it in [the object storage tool](/tools/object-storage-compare) and compare with [the vector DB comparison](/tools/vector-db-compare) where the same banding idea was first tried.'},{type:"callout",text:"How this near-tie was measured: all 27 object-storage vendors in our catalog were priced from captures taken off their own pricing pages on 2026-08-21 (Ionos excluded: it quotes only in GBP). At 5 TB stored + 5 TB egress the two leaders are AWS S3 Standard at $556.59 and IBM Cloud at $555.21, a $1.38 gap (0.25%). Because that gap is inside our $2 near-tie threshold, features break the tie instead of price alone: S3's broader feature set scores it 10 vs IBM's 9. The comparison itself stays deterministic and price-first: feature data only acts as a tiebreaker within the threshold."}],dr={slug:Qo,title:er,description:tr,date:ar,updatedAt:or,author:rr,reviewedBy:sr,family:ir,tags:nr,affiliateDisclosure:lr,sources:hr,sections:cr},ur="vector-db-free-tiers",pr="Vector DB free tiers, compared without the marketing gloss",mr='"Free forever" means 21 different things across the vector database market. Every free tier in our
1captured catalog (storage, vectors, queries, credits) on one honest table.',yr="2026-08-22",fr="2026-08-23",gr="Dracon Research Team",br="Dracon Editorial",wr="infrastructure",vr=["vector-database","free-tier","pricing","ai","transparency"],kr=!1,xr=[{label:"vector-db-catalog.json (verifiedAt 2026-08-22, 21 vendors, per-row pricingCapturedAt)",href:"/tools/vector-db-compare"},{label:"vps-catalog.json (verifiedAt 2026-08-22, pgvector-hetzner baseline, 1.08 EURâUSD)",href:"/tools/vps-compare"},{label:"fx.ts EURâUSD 1.08 as-of 2026-08-20, EUR self-host costs normalized",href:"/tools/vector-db-compare"}],$r=[{type:"h2",text:"The board"},{type:"table",caption:"Captured free-tier limits (storage GB / query volume in millions / notable extras). Zero means no free allocation captured; blank means the dimension is not part of that vendor's model. Source: vector-db-catalog.json verifiedAt 2026-08-22 (21 vendors); each row cites its pricingUrl and pricingCapturedAt.",headers:["Provider","Free storage","Free queries/mo","The fine print"],rows:[["Qdrant Cloud","1 GB","1M","Free-forever cluster: 1GB RAM / 0.5 vCPU / 4GB storage: real always-on deployment"],["Zilliz Cloud","1 GB","1M","$100 starting credit + free starter cluster; credits stack on billing"],["Chroma Cloud","0.5 GB","0.5M","Free community tier with 500MB storage, shared CPU"],["Astra DB (DataStax)","0.5 GB*","0.5M*","$25 monthly recurring credit (~5GB/1M ops effective). Refreshes monthly, not one-time"],["Supabase (pgvector)","0.5 GB","0.5M","500MB database storage on the free Postgres project, shared CPU"],["Neon (pgvector)","0.5 GB","0.5M","0.5GB storage + 100 compute hours/month on the free tier"],["MongoDB Atlas","0.5 GB","0.05M","M0 free shared cluster, 512MB, vector indexing included, with a tiny query allowance"],["Weaviate Cloud","0.5 GB","0.1M","14-day sandbox only, up to 100k vectors, then it's gone"],["Elastic Cloud","50 GB retained","â","Serverless vector profiles include 50GB retained storage free: storage story only"],["Cloudflare Vectorize","0.05 GB","0.03M","200k vectors included on the Workers free plan: vector count, not GB"],["Azure AI Search","0.05 GB","0.1M","Free F tier: 50MB, 3 indexes, explicitly no SLA"],["Redis Cloud","0.03 GB","0.1M","30MB free instance with Vector Search module, dev sandbox size"],["Pinecone Serverless","â","â","Starter on shared infrastructure, up to 100k vectors, 1 index: count-based, not GB"],["turbopuffer","â","â","Evaluation credits at signup; paid Launch plan starts $16/mo"],["ClickHouse Cloud","â","â","30-day $300 trial credits: a trial, not a tier"],["Vespa Cloud","â","â","Evaluation credits via console; production requires a paid cluster"]]},{type:"p",text:`Asterisks on Astra's 0.5GB/0.5M mark the honest limitation of a credits model: Astra has no fixed free tier in the catalog's schema: its $25/month recurring credit can fund roughly ~5GB and ~1M operations at its published pay-as-you-go rates, but the catalog stores the mechanism (monthly recurring credit) rather than inventing a GB figure that the vendor never promised. The same honesty drives the zeros and dashes: Pinecone's value is 100k vectors (not a GB limit we could reliably convert), turbopuffer and clickhouse are credits-only (no fixed free GB to capture), and the self-hosted pgvector baselines on Hetzner (pgvector-hetzner, EUR pricing normalized at 1.08, surfaced in [our VPS tool](/tools/vps-compare)) show 0 free because you provision the VPS yourself. The compute is the cost. Where the catalog says zero, it means "no meaningful managed free allocation captured," not "we didn't look." Where it shows a GB or query count, that number came from the vendor's pricing page with a dated pricingCapturedAt stamp, surfaced in [the vector-DB tool](/tools/vector-db-compare).`},{type:"h2",text:'Three shapes of "free"'},{type:"ul",items:["Forever clusters: Qdrant and Zilliz lead this shape: a real (small) always-on deployment with 1 GB storage and 1M queries/month that does not expire. This is what most people actually want for a side project that needs a stable URL, persistent indexes, and no calendar-driven scramble to export vectors before the sandbox dies.","Trials wearing a tier costume: Weaviate's sandbox dies in 14 days (100k vectors max, then it's gone); ClickHouse and Vespa hand you evaluation credits with a clock (ClickH
1ouse: $300 for 30 days); turbopuffer's evaluation credits carry no fixed GB. Fine for prototyping and for measuring ingest speed, dangerous as an architecture assumption. If your demo week slips by a fortnight, your data slips with it.","Credits-as-marketing: Zilliz's $100 starting credit and Astra's recurring $25/month are genuinely generous: Astra's monthly refresh effectively funds ~5GB/1M ops of usage permanently free at current rates. But they're discounts on paid plans, not islands of free service. Microsoft and AWS use the same pattern elsewhere: credits feel like free tiers until you multiply them by twelve and compare them to Qdrant's forever 1 GB that asks for no billing method at all."]},{type:"h2",text:"The dimension almost nobody compares"},{type:"p",text:`Storage is the headline number vendors advertise, but queries are where free tiers actually run out for most workloads. A retrieval-augmented app that embeds once and searches constantly burns query allowance thousands of times faster than storage. The board exposes the gap: MongoDB Atlas's generous-sounding 512MB (0.5 GB) comes with just 0.05M free query operations monthly (fifty thousand). Qdrant's free cluster carries a full million. Same "free tier" label, twenty-fold difference in the resource your application hammers all day. Elastic is the inverse edge case: 50 GB retained storage free sounds enormous until you realize it is storage-only: there is no free query allowance to compare, because Elastic's consumption model charges query compute differently from vector-count plans. Cloudflare Vectorize is the honest challenger here: 200k vectors on the Workers free plan is a vector count, not a GB abstraction, and the tool keeps it that way rather than converting to a pretend GB figure that would drift with embedding dimension. Our tool surfaces both dimensions side by side in [the vector comparison](/tools/vector-db-compare) precisely because vendors don't advertise them in the same breath, and because a RAG prototype's cost at month three is almost always query-bound, not storage-bound.`},{type:"h2",text:"Who should pick which shape"},{type:"p",text:"If you want a free forever home for a side project with real users, prioritize forever clusters: Qdrant Cloud (1 GB/1M) and Zilliz's starter cluster are the only rows that promise persistence with no calendar expiry. Qdrant's sandbox is the narrowest surprise because it includes dedicated RAM and vCPU so you can hold an index resident; Zilliz pairs the same size with a $100 credit that funds burst experimentation on top. If you want a frictionless Postgres story where vectors live beside your relational rows, Neon or Supabase both give 0.5 GB/0.5M but Neon adds 100 compute hours, useful if you already live in [VPS](/tools/vps-compare) land and can reason about a self-hosted pgvector on a Hetzner CX22 at â¬3.49 (~$3.77 normalized) as the ceiling that makes their free tiers attractive. If you want to evaluate index performance quickly and then decide, trials are fine: Weaviate's 14-day 100k sandbox, ClickHouse's 30-day $300 credit, and turbopuffer's evaluation credits let you burn at will, but calendar them. The worst failure mode we see is a team demoing into a sandbox that expires the morning of the demo."},{type:"ul",items:['Check expiry before you invest in schema: "14-day sandbox" means your application architecture expires, not just your credits.',"Check query allowance before storage: 512MB means little if you get 50k queries and your RAG loop does 2k/day: you will be metered at 25 days.","Check credit refresh: $25/month recurring (Astra) and $100 one-time (Zilliz) are not the same generosity: one replenishes, one disappears.","Check self-host baseline: if a managed free tier is smaller than what a â¬3.49 Hetzner vCPU can host, ask whether you want managed convenience or raw GB per euro from [our VPS dataset](/tools/vps-compare).","Compare inside [the vector DB tool](/tools/vector-db-compare) with paid pricing alongside free limits. The free board alone cannot decide for you once your data grows past month one."]},{type:"p",text:"All figures were captured 2026-08-22 with per-row provenance (pricingUrl + pricingCapturedAt) in the catalog that backs [the interactive comparison](/tools/vector-db-compare). When vendors change their tiers (as Pinecone did when Serverless introduced 100k vectors on the starter, and as Chroma, Weaviate, and Astra have adjusted credits), the recapture changes the data, not the story, and the article updates from the same source of truth rather than being defended."}
1],Tr={slug:ur,title:pr,description:mr,date:yr,updatedAt:fr,author:gr,reviewedBy:br,family:wr,tags:vr,affiliateDisclosure:kr,sources:xr,sections:$r},Ar="first-10k-emails-cost",Sr="Your first 10k emails: what transactional email really costs at launch",Pr="Six vendors charge $0/month at launch volume, and the paid floor starts at $15. Every price below comes from our captured email-API catalog, run through the same compute engine our comparison tool uses.",Ir="2026-08-22",Dr="2026-08-23",Cr="Dracon Research Team",Or="Dracon Editorial",Br="infrastructure",Mr=["email","startups","pricing","transactional-email","transparency"],Er=!1,Nr=[{label:"email-api-catalog.json (verifiedAt 2026-08-22: 11 vendors, live pricing URLs)",href:"/tools/email-api-compare"},{label:"email-api-compute.ts (freeDailyCapPerDay + 30.44-day avgDaily gate, EC2-caveat logic)",href:"/tools/email-api-compare"},{label:"fx.ts EURâUSD 1.08 as-of 2026-08-20: EU vendors Brevo/Mailjet/Scaleway normalized",href:"/tools/email-api-compare"}],Rr=JSON.parse(`[{"type":"p","text":"Launch-stage email is a solved problem that everyone solves badly, because the pricing pages make comparison nearly impossible: one vendor counts recipients, another counts messages, a third bundles marketing sends with transactional ones, and the fourth quotes \\"from $0\\" in type large enough to need its own viewport. We built [an email API comparison tool](/tools/email-api-compare) on top of a captured catalog of eleven vendors (verifiedAt 2026-08-22 from official pricing sheets; Mailchimp/Mailersend/SMTP2GO re-captured that week from mailchimp.com/pricing, mailersend.com/pricing, smtp2go.com/pricing), and pointed its standard startup scenario at them: 10,000 emails per month, 95% transactional (auth mails, password resets, receipts, notification streams) priced through the same pure compute engine the live tool uses, so the article and the app cannot drift apart."},{"type":"h2","text":"The result: at launch volume, email should be free"},{"type":"table","caption":"Early Startup scenario (10k emails/mo, 95% transactional, target USD) computed live by email-api-compute.ts from email-api-catalog.json verifiedAt 2026-08-22. EUR rows (Brevo, Scaleway, Mailjet) normalized at 1.08 EURâUSD via fx.ts; free allowances gated honestly on daily caps and EC2 caveat. Sorted by USD total.","headers":["Vendor","Monthly total","Free allowance (captured)","Math note"],"rows":[["AWS SES","$1.00","62,000/mo EC2-only","$0.10/1k Ã10k; free NOT applied by default (caveat)"],["Scaleway TEM","â $2.49 (â¬2.30)","300/mo included","â¬0.25/1k on 9,215 tx + 485 mkt = â¬2.30 â $2.49 at 1.08"],["Brevo","â $4.89 (â¬4.53)","9,000/mo (300/day cap)","10k avg 328/day >300/day â free blocked; â¬0.45/1k then"],["Mandrill (Mailchimp)","$7.22","500/mo","Blocks $0.80/1k on 9,025 tx: gated at 500 free"],["MailerSend","$13.04","500/mo","Hobby $7 incl 5k + $1.50/1k on 4,025 overage"],["Postmark","$15.00","100/mo","$15 base for 10k included: first paid floor, 9,405 tx inside"],["SMTP2GO","$15.00","1,000/mo (200/day cap)","10k avg 328/day >200/day â free blocked; Starter $15 incl 10k"],["Mailjet","â $16.28 (â¬15.07)","6,000/mo (200/day effective)","Essential 15k â¬15 base; 3,800 tx + 200 mkt inside band"],["Resend","$20.00","3,000/mo","Pro 50k $20 base incl 50k: 6,650 tx inside"],["SendGrid","$20.07","100/mo","Essentials 50k $19.95 base + $0.25/1k on 495 mkt"],["Mailgun","$35.17","100/mo","Foundation 50k $35 base + $0.35/1k on 495 mkt"]]},{"type":"p","text":"The ranking is no longer about who advertises free. After the 2026-08-22 gating fix, no vendor quotes $0 at 10k under default conditions: Brevo's 300/day and SMTP2GO's 200/day both block when you average 328/day, and SES's 62k EC2-only allowance is explicitly not applied to default app-infra senders. The cheapest honest bill is therefore SES at $1.00: pure pay-per-thousand at $0.10/1k, no base, no cap. Next is Scaleway at â$2.49 (â¬2.30 at 1.08), then Brevo at â$4.89 once the daily cap removes its headline. The most expensive position (Mailgun's $35.17 Foundation for 50k) costs 35à more than SES for the identical 10k job, and the spread between cheapest and median (MailerSend $13.04) still funds a month of [VPS](/tools/vps-compare) on Hetzner. That is
1why our [live ranking](/tools/email-api-compare) sorts on the computed totalCost (normalized once via fx.ts at 1.08, FX_AS_OF 2026-08-20) rather than on the marketing headline, and why the table above carries the engine's notes verbatim."},{"type":"h2","text":"Read the shape, not just the number"},{"type":"p","text":"The zero-dollar rows are not all the same deal, because free tiers carry two kinds of asterisks that our calculator now checks explicitly (a correction we shipped in August 2026). First, daily caps: Brevo's 9,000/month headline is actually 300/day: 300 à 30.44 = 9,132/month is what a perfectly spread month can absorb, so a workload that averages 328/day (10,000 ÷ 30.44 â 328) exceeds it and gets zero free allowance in our default quote. SMTP2GO's 1,000/month is similarly capped at 200/day (200 à 30.44 = 6,088/month). Daily volume above that, even if monthly volume looks inside the allowance, loses the free tier and falls to the Starter $15/mo for 10k included. That 30.44-day divisor (365 ÷ 12, the honest mean month) is how our calculator gates free allowances: it compares your average daily volume against each provider's daily cap, and when a workload would exceed the cap the allowance is skipped, with a visible note saying why. Second, conditional allowances: AWS SES's 62,000-message monthly free allowance is the largest in the market by an order of magnitude: $0.10 per 1,000 beyond ($1.00 for 10k) is itself the price floor. But it applies only to email sent from EC2 (flagged as EC2-only in our dataset). The default visitor sends from their own app infra, not EC2, so our ranking quotes SES at $1.00 (10k à $0.10/1k) and discloses that EC2 senders' real price is lower in the notes. Scaleway TEM is cleaner: its Essential pay-as-you-go now includes only 300 emails, then â¬0.25 per 1k. At 10k that is (9,700 ÷ 1,000 à â¬0.25) = â¬2.425 â $2.62 at 1.08: no daily cap, no condition, but no generous free tier either."},{"type":"callout","text":"Where rankings get subtle: when several vendors compute to $0.00 (or within cents), pure cost cannot separate them. Our tool breaks those ties by counting captured capability dimensions (webhooks, SMTP relay, sub-account support, EU data residency like Scaleway's Paris domicile, template builder) into a feature score. Since REVERSED 2026-08-23 that score only badges near-ties. Rank itself is price-only via compareNearTieKeys on exact cents. See the methodology in our storage near-tie article for the band-vs-tolerance reasoning that motivated the reversal."},{"type":"h2","text":"Methodology: from catalog to $/month without guessing"},{"type":"p","text":"Every price in this piece was captured by hand from the vendor's own pricing page on 2026-08-22. Eleven vendors made the cut, each with its per-thousand rates, plan fees, included monthly volumes, free-tier limits (including daily caps like Brevo's 300/day), fine print (SES's free tier only applies from EC2), and feature set (webhooks, SMTP relay, inbound routing, React SDKs, sub-accounts) recorded with a source link. Vendors whose self-serve pricing can't be fully captured stay out entirely rather than getting estimated numbers. Vendors without capturable self-serve rates (SparkPost, Bird, Elastic Email) stay out per the documented inclusion criterion (market-leading + fully capturable + affiliate-prioritized). Our calculator then turns those captures into the ranking you see: the free allowance is gated on daily caps and fine print; the billable volume is split by how much of your sending is transactional versus marketing (95% here); each stream is priced from the plan or rate band that covers it, including overages past what the plan includes; and base plan fees are never double-counted on top of a tier that already charges one. Euro prices convert once at our recorded rate ($1.08 per euro, as of 2026-08-20) so vendors are compared honestly on total cost while displayed in their native currency, so Brevo's â¬19/mo Starter and Mailjet's â¬15/mo Essential are compared honestly on totalCost (converted) while displayed natively. The table above is therefore not a hand-typed illustration. It is the live ranking for the 10k/95% input you see on [the email tool](/tools/email-api-compare)."},{"type":"h2","text":"When does the free ride end?"},{"type":"ul","items":["Volume cliff: every free tier ends at a hard number and then you jump to the first paid plan. There is no smooth metering between \\"free\\" and \\"entry plan\\" on most vendors. Brevo's jump is 300/day; SMTP2GO's is 200/day. Your burst day, not your month, decides.","Daily vs monthly: at 10k/month you average 328/day, already above Brevo's 300/day even inside the 9,000 headline, so the honest month-one cost for a spiky launch can be paid despite the headline. Model bursts, not just means.","Feature gates matter earlier than volume: dedicated sending IPs ($29 Brevo, $50 Postmark, bundled free on Scaleway Scale â¬80/mo with 100k + SLA), sub-accounts, and advanced webhooks are typically paid-plan features regardless of how few emails you send.","Growth math: at 75k/month (our Growth App scenario) the board reshuffles completely. The vendors that were free at 10k are now mid-priced and the flat-rate entrants look different. At 250k and 2.5M the cheapest paid vendor changes again; check the [growth presets](/tools/email-api-compare) before you lock in an SDK.","EU residency requirements can disqualify otherwise-cheap options instantly; filter before comparing, not after: Scaleway (EU-sovereign, GDPR residency in Europe) and Brevo (EU-sovereign) stay eligible when US-only vend
1ors don't."]},{"type":"h2","text":"Who should pick what"},{"type":"p","text":"If you are pre-product-market-fit and sending <10k onboarding + transactional mails with occasional bursts, Brevo's 300/day can cover you if you smooth sends, but don't architect around a cap that punishes your launch week. SES at $1.00 with no daily cap is the cheapest caveat-free bill if you accept its setup ceremony (sandbox approval, DNS verification, managing your own reputation). If you are EU-resident and want sovereignty from day one, Scaleway's â¬2.43 net (~$2.62 normalized) plus the same tool's [VPS](/tools/vps-compare) and [domain](/tools/domain-tco) EUR honesty gives you one FX story across the stack; at 75k, Scaleway's Scale â¬80 bundle with its managed IP overtakes Brevo on predictable cost. If you value deliverability polish from day one (template builder, 45-day analytics, sub-accounts, inbound routing), Postmark's $15 for 10k included is not a premium brand tax but a bundle of those captured features (score 7/7 on our count) with a reputation for speed and support; whether it is worth $180/year on a 10k-month workload is a question only your open-rate data and your need for [object storage](/tools/object-storage-compare) CDN coupling can answer. In every case, choose your free tier by where you expect to be in six months, because that's when these prices start to diverge sharply, not by what is free today."},{"type":"p","text":"The honest summary for founders: at launch volume, do not pay for transactional email. Choose your free tier by its daily cap and its caveat, not its monthly headline, because that's when the bill arrives. The full interactive picture, including 250k and 2.5M-volume scenarios, per-vendor feature matrices, the 30.44-day gating note, and the EC2-caveat disclosure, lives in [the comparison tool](/tools/email-api-compare). All prices captured 2026-08-22 from vendor pricing pages; where a vendor publishes no figure, our catalog records the absence rather than guessing. The same honest-null discipline we apply on [VPS SLAs](/tools/vps-compare) and domain ICANN flags."},{"type":"callout","text":"How we got these numbers: every rate was captured from the vendor's own pricing page on 2026-08-22, with the source link and capture date stored alongside it. Free tiers respect their real limits: daily caps and fine print included. Euro prices use our recorded $1.08/⬠rate (as of 2026-08-20). Worked example at 10,000 emails/month: SES bills $0.10 per thousand ($1.00 total; its free tier is off by default); Scaleway charges â¬0.25/thousand on volume above its daily-capped free allowance (â¬2.43 â $2.62); Brevo would be free, except 10k spread over a month averages ~328 emails/day against its 300/day cap, so the free tier doesn't apply."}]`),Wr={slug:Ar,title:Sr,description:Pr,date:Ir,updatedAt:Dr,author:Cr,reviewedBy:Or,family:Br,tags:Mr,affiliateDisclosure:Er,sources:Nr,sections:Rr},a=[y,D,G,te,me,Ie,Ge,at,ft,Dt,Gt,ta,ma,Pa,ja,Qa,po,So,Lo,Xo,dr,Tr,Wr],Fr=[...a].sort((e,t)=>t.date.localeCompare(e.date));function Lr(e){return a.find(t=>t.slug===e)}export{Fr as A,a,Lr as g};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.