Setting the metering question aside: 42,000 words of Markdown is not a language model problem. git diff, or diff -u, or any three-way merge tool gives you a perfect answer for free in about forty milliseconds.
Use the model on the output of that. "Here are the changed hunks, tell me what changed semantically and what it means for the implementation" costs you maybe two percent of what today cost, and the result is better because the model is reasoning about meaning instead of playing spot-the-difference.
If it is genuinely a hobby project, the cheapest fix is architectural rather than administrative.
Delete the VPC-with-NAT arrangement completely. Put the application on Lambda behind an HTTP endpoint, DynamoDB on demand for state, S3 plus CloudFront for anything static. At hobby traffic that sits inside the always-free allowances and, more importantly, there is nothing billed per hour left to forget about.
The pattern behind every one of these threads is the same: the bill that hurts is always something charged per hour that you are not using. Get rid of the per-hour things and the surprise disappears with them.
Acknowledge inline, in seconds, never in a batch. The flow that works:
client receives the purchase and sends the token to your backend immediately
backend verifies the token against the API
backend acknowledges on success, then writes the entitlement
client also re-queries on every launch and re-sends anything that still looks unacknowledged
Acknowledgement must never live in something that can be delayed, because delay is the entire failure mode. There is no retry budget - the clock belongs to someone else.
Then turn on real-time developer notifications through Pub/Sub. That is how you learn about renewals, cancellations, refunds and grace period without polling, and it is the thing that would have told you about the 22 on day one.
Specifically for the RDS snapshot: get it off RDS entirely while you have access. Export the snapshot to S3, then pull it down locally or push it to different storage.
Restoring a snapshot you actually hold into a fresh account is an afternoon of moderately dull work. Not having the snapshot at all is a project with no defined end. The gap between those two outcomes is about twenty minutes of effort today.
One, on Ollama the only tag published for glm-5.2 is glm-5.2:cloud. There is no local weight tag to pull, so "run it locally" is not a one-line change to your setup: you are going outside Ollama's library to do it.
Two, the model is listed at 756B parameters. The weights being openly licensed does not make them fit. Running something in that class locally means a server with hundreds of gigabytes of fast memory, and once you are renting or buying that, "free" has quietly become the most expensive option in the thread.
Ship the approved build. Manual release exists for exactly this and you have already done the hard part.
Apple's own line is that most submissions are reviewed inside a day, but that is an average across a pile of trivial updates from established accounts, and it says nothing about the week you happen to submit in. Planning a public date against it is planning against a distribution you cannot see. There have been stretches where reviews visibly slowed for everyone.
The pattern I use now: freeze the launch build about a week out, submit it, hold it with manual release, and keep working on 1.0.1 in a branch. The day after launch you submit the patch with the fixes that accumulated. Nobody downloading on day one knows or cares that three refinements landed 48 hours later.
For the connected boxes, resist the urge. Hand-carrying .msu files is a habit that scales badly and drifts your estate apart, you end up with three servers on a package nobody else has.
Keep manual .msu handling for the genuinely isolated machines and for emergency rollbacks. Everything else goes through the ring, even when the ring is slower than you would like.
Pull the customer emails and invoice PDFs out before you delete anything else. People lose access to their own billing history the moment you close the portal, and then they ask you for it in April.
Shared staging plus parallel PRs means two runs truncating each other's tables, and you will chase that flake for a month before you work out it was never your code. It also means any test anyone writes can now delete staging data, and someone eventually writes that test.
Isolation is the entire point of the exercise. Realistic data is a separate problem, solved by seeding an anonymised snapshot into the branch.
Name first, address second, verify third. Never skip to guessing addresses for a person you have not identified, that is where bounces come from.
Getting the name on companies like these: professional association member listings, trade show exhibitor lists from the last three years, local business award writeups, company registry filings where directors are public, industry podcast guest lists, and the byline on any press release. For family manufacturers the registry route works startlingly often because the person you want is frequently a named director.
Address pattern: find any one real address at that domain, which is usually in a press release or a PDF spec sheet, and that tells you the convention. Then verify before sending. Bounces are the thing that quietly damages your ability to reach anyone at all, so keep them low, and treat every bounce as feedback that the guess was wrong rather than as free.
For the things you open on purpose, use the teardown hooks rather than hoping. globalSetup can return a function that runs at the very end - that is where servers and pools you started deliberately get closed. Anything per-file goes in afterAll in a setup file.
The rule I use: if a test file imports it and it has a close() or end(), something in that file is responsible for calling it.
Learned this by leaking about forty orphaned volumes over a few weeks. Force deleting stuck pods became a habit and nobody noticed until the bill arrived.
One codebase, one deployment, config per tenant, and the bespoke bits behind flags you charge for. Never fork. A fork feels faster for six weeks and then it is a second job.
Worth noting most of these tools can be configured to send plain replies from your own address with no ticket number and no portal, so the robot tone is a settings problem rather than an inherent one. But the fact that the defaults produce it, and that you have to know to turn it off, rather proves your point.
Rough numbers: lockDuration around twice your p99, stalledInterval under that. And remember every stalled recovery is a full re-run of 90 seconds of image processing, so a bad setting shows up on the compute bill as well as in the logs.
Did this exercise last month and found something dumb worth checking: I was paying for a staging environment on the same tier as production. Same database size, same instance, running 24/7, used maybe four hours a week. Dropped it to the smallest tier and put it on a schedule so it sleeps overnight. Saved about $30 a month and nothing broke.
Also found two subscriptions from a project I killed in 2024 that were still quietly charging.
3.1x annual profit was already near the top of the range for this size. The realistic band is roughly 2.5-4x annual profit, and every risk factor eats into it: concentration, churn, whether the stack is something a buyer can hire for, whether you are the only person who has ever deployed it.
You did not lose $150k. You had a number in your head that assumed no risk existed.
Put the ownership in writing before you start, in one sentence: you are being paid for the work, the resulting code remains yours, they get a licence to use it. Without that line you can spend three weeks building an asset you are not allowed to sell to anyone else, which is the worst version of every outcome here.
Said yes to three of these in my first year and I want to describe the drag rather than tell you not to.
None of them was a disaster individually. Together they meant that by month fourteen I had three code paths that only one account used, a test suite I could not run against real data, and a genuine reluctance to refactor anything near the import layer. Roadmap work slowed by maybe a fifth and I could not point at any single decision as the cause.
My rule now is one bespoke commitment live at a time, written down with a review date, and the next one does not start until the previous one is either generalised into the product or retired. Having a number - one - made saying no to the fourth easy in a way that principles never did.
Film him getting up from lying down, tonight and tomorrow. Limps have an infuriating habit of vanishing on the consulting room floor and a ten second video has saved me a second appointment more than once.
If your platform gives you a dead letter queue for three lines of config, take it - the cost is near zero and failed messages stop being log lines with a seven day life. Just wire the alert on non-empty at the same time, and go and look at it weekly until you trust it.
Intermediate step that helped me more than it should have: a template repository and a checklist document per client, with the exact steps in order and the commands to paste. It is not automation, it is just not thinking. Went from about ninety minutes to fifty, made the two most annoying steps obvious because they were the ones I dreaded on the list, and gave me something to hand to someone else eventually. Took an afternoon.
Changing bank details on your account is not transferring the account to another company, and doing the former to fake the latter is how accounts get frozen with a balance sitting in them. There is a real documented path for moving customers and stored payment methods between two accounts, and that is the one to ask about. It takes weeks and it involves both sides.