{"slug":"bill-spike-finder","name":"Bill Spike Finder","version":"1.0.0","updated_at":"2026-10-04T11:05:57.449Z","use_when":"Finds the loops behind a bill spike or an unexpected bill. Reviews a web app's code and config for loops and repeats that run up the bill on their own on Vercel, Turso, Cloudflare Workers and D1 and paid AI APIs. Finds two schedulers on one job, retries without a cap, work that triggers itself, client polling and React render loops, caches cleared on every write, middleware running on every static file, queues that resend failures forever, image settings that multiply transformations, health checks that count whole tables, alerts sent on every run and bots crawling endless filter URLs. Counts the runs per month, names the billed unit, ranks by cost and gives the change that stops each one. Use when asked why a Vercel, Turso or Cloudflare bill jumped, to find an infinite loop or a runaway cost, or to review a cron job, webhook, queue consumer, middleware or polling code before it ships.","not_for":"Cloud bills on AWS, GCP or Kubernetes; reading your live usage dashboards for you; choosing a plan or a provider. It reviews the code and config you show it, so a caller it cannot see, such as a monitor or a script on another machine, is named as an assumption rather than found.","languages":["en","bg"],"tags":["cost-optimization","vercel","turso","cloudflare-workers","infinite-loop","cron","rows-read"],"category":"code","category_url":"https://aiskills402.com/categories/code","keywords":["bill spike","unexpected bill","infinite loop","runaway cost","cron job"],"faq":[{"q":"Do I need my usage numbers?","a":"No, but they help. Without them it lists every trigger it can see in the code and config, counts the runs a month and states what it assumed about traffic and table sizes. With a top-routes or top-queries list from the platform it starts from the code those numbers point to."},{"q":"What does it add for Claude Sonnet?","a":"Claude Sonnet found every planted loop in our short cases with or without the skill, and on a real site's code it named five of the six causes either way. The skill changed the numbers: with it, Sonnet put the costliest query at 498 million rows a month against about 500 million measured; without it, at 125 to 250 million."},{"q":"How does it do with a small model?","a":"On short pieces of code it helps: Claude Haiku passed twelve of twelve with the skill and nine of twelve without. On a whole project it did worse with the skill than without, fixing on one endpoint and assuming a caller that was not there. For a whole-project review, run it on a strong model."},{"q":"Can a budget alert do the same job?","a":"No. An alert arrives after the money is spent, often a day later. Each finding here comes with a change on the path, such as one scheduler, a cap or a shared cache, and an alert is mentioned only as a second line after the fix."}],"examples":[{"lang":"en","model":"claude-sonnet-5-5","input_excerpt":"Notes: Next.js on Vercel (Pro), database on Turso (Developer plan).\n\nvercel.json:\n{ \"crons\": [{ \"path\": \"/api/tick\", \"schedule\": \"* * * * *\" }] }\n\nAfter an outage in July we also added an external cron service that calls https://example.com/api/tick every minute, as a backup.\n\napp/api/tick/route.ts:\nimport { db } from \"@/lib/db\";\nimport { JOBS } from \"@/lib/jobs\";\n\nexport async function GET() {…","output_excerpt":"# Review: surprise-bill-loops\n\nTwo findings, ranked by cost. The first is the bigger one and also makes the second four times worse.\n\n**[DOUBLE-SCHEDULER]** `vercel.json` cron plus the external cron service, both calling `/api/tick`\n\nRuns:\n- Each scheduler fires 1,440 times a day, so 43,200 a month each and 86,400 together.…"},{"lang":"bg","model":"claude-sonnet-5-5","input_excerpt":"Бележки: Cloudflare Workers Paid, D1. Езиков модел по API, плаща се на токен. Новини идват средно 6 пъти на ден.\n\nwrangler.jsonc (извадка):\n\"triggers\": { \"crons\": [\"* * * * *\"] }\n\nsrc/index.ts:\nexport default {\n  async scheduled(_e: ScheduledEvent, env: Env) {\n    const { results } = await env.DB.prepare(\n      \"SELECT id, title, body FROM news ORDER BY published_at DESC LIMIT 30\"\n    ).all();…","output_excerpt":"## Находки\n\n**[AI-IN-LOOP]** `src/index.ts`, `scheduled()`: `callModel(...)` се вика при всяко изпълнение\nRuns: cron `* * * * *` е 60 × 24 × 30 = 43 200 изпълнения на месец. Новини идват 6 пъти на ден, около 180 на месец, така че само около 180 от 43 200 повиквания (0,4%) имат нов вход. Останалите 43 020 плащат за същия обзор на същите 30 новини.\nMeter: токени на модела.…"}],"page_url":"https://aiskills402.com/skills/bill-spike-finder","markdown_url":"https://aiskills402.com/skills/bill-spike-finder.md","image_url":"https://cdn.aiskills402.com/og/skills/bill-spike-finder/e8da930f.png","related_url":"https://api.aiskills402.com/v1/skills/bill-spike-finder/related","purchases_count":null,"tested":{"date":"2026-10-04","strong":{"model":"claude-sonnet-5-5 (Claude Code alias \"sonnet\")","verdict":"Found the planted loop in all 11 cases that had one and answered 'No findings.' for the clean code. Each finding carried runs a month, the billed unit and a fix on the path: one scheduler plus a run key, a shared server cache for a polled route, a matcher that skips static files, a cap and a dead-letter queue, and removing a cache clear that ran on every page view. On the whole code of a real site (an earlier text of the skill) it named 5 of the 6 main causes behind 561 million rows read and put the costliest query at 498 million rows a month, against about 500 million measured."},"weak":{"model":"claude-haiku-4-5-20251001 (Claude Code alias \"haiku\")","verdict":"Found the planted loop in all 11 cases that had one and answered 'No findings.' for the clean code; once it gave the right fix without the finding's code name, and one Bulgarian answer used a Russian word. On the whole code of a real site it did worse: 3 of the 6 main causes without the skill, 0 with an earlier text and 1 to 2 with this one. It latched onto a health endpoint, assumed an uptime monitor the code does not show, and once proposed a cleanup whose condition would delete the newest rows. For a whole-project review, use a strong model."},"note":"Twelve short fictional cases: eleven with one planted loop each (two schedulers, client polling, retries in layers around a paid AI call, a cache cleared on every view, a page that fetches its own API, middleware on every static file, a render loop, a queue that resends forever, an AI summary on a schedule far faster than the news, image widths, a health check that counts a whole table and alerts on every run) and one clean; two requests in Bulgarian. One run per model and case on the final text of the skill. Plus one real case: the whole code of one of our sites as it was before a fix (150 files), with the question 'our database read 561 million rows this month with almost no visitors, why?', scored by reading against the six causes found then; four runs, and two more for Haiku after a change to the skill.","baseline":{"date":"2026-10-04","rows":[{"label":"Short cases passed","better":"higher","strong":{"with":{"n":12,"of":12},"without":{"n":12,"of":12}},"weak":{"with":{"n":12,"of":12},"without":{"n":9,"of":12}}}],"note":"One run per model and case, the same checks for both sides, every failed answer read. Without the skill Haiku missed client polling, a page that fetches its own API and middleware that runs on every static file. Sonnet found every loop without the skill too; what the skill adds there is the arithmetic. On the real site's code both models found as much or more WITHOUT the skill: Sonnet 5 of 6 either way (without it the costliest query was put at 125 to 250 million rows a month, with it at 498 million), Haiku 3 of 6 without, 1 to 2 with."},"report_url":null},"price_usd":"0.05","price_micro":50000,"size_bytes":16280,"sha256":"e5652d066348ecb7f5db3ff3289ad522f4a1dd3dbbe32818e91fc4e607de85dc","outline":["Hard rules","What each platform bills (checked October 2026; prices change, the mechanisms rarely do)","Finding codes","Report format","Work in this order","Short example"],"license":{"summary":"Perpetual, non-exclusive; use and modify for yourself incl. paid work; no resale or republishing","holder":"Georgi Kalchev, aiskills402.com","url":"https://aiskills402.com/docs#license"},"buy_url":"https://api.aiskills402.com/v1/skills/bill-spike-finder/file","redownload_url_template":"https://api.aiskills402.com/v1/purchases/{token}","mcp_tool":null,"payment":{"protocol":"x402","scheme":"exact","asset":"USDC","selling":true,"network":"base","network_caip2":"eip155:8453","pay_to":"0x8e37022edcf0f21cf3c9f93fee9d4d32519f36f4","facilitator":"cdp"},"seo_title":"Find the Loops Behind a Vercel Bill Spike","seo_description":"Review your app's code for loops that run up Vercel, Turso, Cloudflare and AI API bills. Counts runs, ranks by cost and gives each fix. $0.05 once.","versions":[{"version":"1.0.0","date":"2026-10-04","changelog":"# Changelog\n\n## 1.0.0 — 2026-10-04\n\nFirst release: reviews a web app's code and config for loops and repeats that run up the bill on Vercel, Turso, Cloudflare Workers and D1 and paid AI APIs; eighteen finding codes, each with runs a month, the billed unit and a fix on the path, ranked by cost and added up against the bill the buyer reports.\n"}]}