I was one step from ripping out my key-value store and putting in a real database. The reason I gave myself sounded responsible: "I'll want to query subscription data later." I have zero users. There is no data to query. I almost spent a day building a warehouse for an empty box.
Here's the setup. My extension's paid tier is validated by a tiny Cloudflare Worker. It stores exactly one kind of thing: given an email, is this person subscribed? That's it. email -> { active, plan, periodEnd }. A lookup by key, returning one record. No joins, no reporting, no "show me everyone who churned last month." Key-value storage (Cloudflare KV) does this in one line and costs nothing.
Then the thought crept in: "But what if I want to see all my subscribers? Revenue by month? Who's about to expire? KV can't do those queries. I should use a real database now, while it's early, so I don't have to migrate later."
That sentence — "so I don't have to migrate later" — is how solo devs talk themselves into building things nobody asked for. I was about to trade a working, free, zero-maintenance store for a heavier one (schemas, SQL, per-row billing) to serve reports I will not read, about customers I do not have.
Two things stopped me.
First: the reports I was worried about already exist, and someone else maintains them. It's called the Stripe dashboard. Revenue by month, active subscriptions, who churned, who's due to renew, MRR — it's all right there, built by a team, for free, better than anything I'd hand-roll off my own database. The "I need to query my data" itch was real; I'd just forgotten payments run through Stripe, and Stripe is the query layer. 90% of what I'd ever want to know is a tab I already have open.
Second: the migration I was avoiding is cheaper than the migration I'd be creating. Switching KV to a database now, before the logic is even verified end-to-end, means changing storage AND payment logic at the same time — two moving parts, more places to break, right before launch. Whereas if I ever genuinely outgrow KV, I'll migrate then, when I know exactly what tables I need because I'll have real queries real users are asking for. "Migrate later with knowledge" beats "migrate now on a guess."
So I kept KV. The whole detour cost me twenty minutes of doubt instead of a day of rewrite, and the product ships on the simple thing that already works.
The pattern I keep catching myself in: dressing up "I want to build the fancy version" as "I'm being responsible about the future." The future-proofing instinct is real and sometimes right — but at zero users, almost every "I'll need this later" is a guess, and guesses are the most expensive code you can write, because you maintain them forever and they were never needed.
The test I now run on myself: is this solving a problem I have, or a problem I imagine a future version of me might have? If it's the second one, and the cost is real today, I don't build it. I write it down and move on.
What's a piece of infrastructure you added "for later" that later never came for?
— building NotebookBloom in public, #11
Top comments (0)