The pattern you described is not a billing bug, it is a product telling you something. Upgrade before a busy week, downgrade after, three times, is a customer with spiky demand paying you a flat rate designed for steady demand.
Sell them the spike. A one-off boost, or an add-on that expires, or metered overage on the cheap plan. You will make more than $38 and they will stop doing plan gymnastics.
Worth asking whether the toggle is earning its keep. If you drop the manual override and just use prefers-color-scheme with CSS variables, there is no script, no localStorage, no hydration mismatch and no flash, because the browser knows the answer before it asks you anything.
A lot of products have a theme toggle because it felt like table stakes, not because anyone asked.
Splitting the two symptoms is the useful part of this thread. Google's screen means the URI. Your error page means your app. Once you know which one you are looking at, both are twenty minutes.
Small thing that pays off exactly now: pass --message on every update with what changed and why. When you are looking at a dashboard at 2am trying to work out which one was good, a list of commit hashes is not a list of information.
The tool is not your bottleneck at thirty a week. Look at what the thirty are.
Tag them for two weeks and I would bet a large share are the same five questions. Five docs pages and one better empty state removes a meaningful chunk of them permanently, and that compounds while a help desk subscription does not. Answering faster is worth less than not being asked.
If after that you are still at thirty a week and they are all genuinely different, then buy the tool with a clear conscience.
Also worth knowing generally: a different local Node or JDK version is a common source of "green here, red there", and EAS pins those from your eas.json image. Set the same versions locally and one whole category of divergence disappears.
And add a line about feedback being collected from all stakeholders before a round starts. Half of my scope creep came from one person who only saw the work in week four.
Numbers side. Eleven replies from a hundred hand-picked emails is a good rate for personalised outreach and you should protect it rather than optimise it. Sending from a normal mailbox, twenty to thirty a day is a sensible ceiling for cold sends regardless of what your provider technically allows, because the provider limits are designed for people emailing colleagues.
The volume rules that get talked about publicly kick in for senders doing thousands a day to one provider, but the underlying signals apply to everyone: authenticate properly, keep complaints near zero, make it trivially easy to be left alone. At your scale complaint rate is the thing that will kill you and it takes very few annoyed recipients to do it.
Drop the TTL to 5 minutes and stop. Most teams build a whole revocation subsystem for a problem that a smaller number solves. The refresh call is already your natural revocation point.
Queue time is the same on every tier, you are only paying for concurrency. If you are one person building one thing at a time, the paid plan does nothing for you.
Worth checking the billing side before you optimise anything: some auth providers only meter users who come back after the first day, so a wave of one-time signups who never return costs you nothing. If yours bills that way, the 145 are a psychological problem rather than a financial one, which changes how much energy this deserves.
That is a defensible engineering position and it is not a rule. "Tokens are for identity only" is a preference that gets repeated as though it were in a specification somewhere. Signed authorisation claims are extremely normal and the entire industry runs on them; the discipline is about TTL and about having one place that reads the claim, not about purity.
If you look up membership per request you are back to a database read per request, which is a fine choice, but be honest that you chose it.
One: the claim is minted by you after checking membership, and is never taken from anywhere else. The leak in these systems almost never comes from the claim being in the token. It comes from one endpoint that reads req.body.orgId or an X-Org-Id header because it was easier that afternoon, and now a valid user of org A can address org B by editing a request.
Two: there is exactly one function in your codebase that produces the org id used by queries, and it reads the verified token and nothing else. Everything goes through it. Then "can this leak" is a question about one function rather than about 200 handlers.
And write the test. A token for org A, a request for a resource in org B, assert 404 (not 403 - do not confirm the resource exists). Ten lines, catches the entire class, and almost nobody writes it.
Charge. Two people asking unprompted what it costs is the rarest signal in this entire business and it has a shelf life. In two months they'll have built a workaround or forgotten.
You don't lose them by charging. You lose them by charging and then not shipping. Price it at $29, tell them exactly what's missing and when it lands, and give them that price permanently. "Founding price, $29, locked forever, export ships in three weeks" is a real offer with a real reason to say yes today rather than later.
And an unpaid daily user who won't pay $29 isn't a customer you lost, it's information you needed inside your four-month window.
Separate the two failure modes, because they need opposite responses.
Friendly fraud - they bought it, forgot, and their partner queried the statement - is fixed by everything above: recognisable descriptor, receipts, easy cancellation, fast replies.
Actual card fraud looks different: clusters of small charges within minutes, mismatched billing geography, disposable email domains, odd hours. That is a rules problem, and the fraud rules product on most processors costs a few cents per screened transaction. Blocking a country you do not sell to at all is a one-line rule and takes a minute.
Given all three of yours are people you think really did buy it, you are in the first category and rules will not help.
Withdraw in batches over a few days rather than all at once. Doing anything to hundreds of items in one session on that platform is how you get a temporary restriction for automated behaviour, even when you are doing it by hand.
Before any of the architecture, go and read the contracts you signed. In consulting agreements it is common for work product to belong to the client, sometimes including anything created during the engagement. If all three contracts say that, you do not have a product, you have three clients who each own a copy.
This is fixable and the fix is a conversation, not a lawsuit. Most clients will happily agree to a licence-back or a carve-out for reusable components because they do not want to be in the software business. But have that conversation before you launch a public product built on the same code, not after one of them notices.
What did the email actually say? If it opened with the new price it reads like a bill, and a bill is a thing people evaluate.
Order that works better: here is what shipped in the last twelve months, here is what is coming, here is the new price, here is exactly what happens if you do nothing and the date it happens. Same information, completely different reaction.
This is the one that ends deals later, too. A buyer doing diligence will ask who owns the code and whether any of it was created under a client agreement. Getting a two-line written acknowledgement from each of the three now is a fifteen minute job that is worth real money in three years.