VIBE is my own product: a multi-tenant CRM and lead engine for vertically integrated real-estate operators — the owner-operators running a brokerage, a mortgage line, and an investing arm out of the same office. On May 15 it went dark. Not because of a bug in my code. A hosting provider billing suspension took the deployment down, and while a domain transfer sat unresolved, it stayed down. For six weeks I had a dead SaaS.
On July 3 I brought the whole thing back in a single working session. Not just back online — further along than it was before it died. This is the full breakdown: what killed it, the resurrection checklist, and the four silent failures I found because the outage forced me to look at everything with fresh eyes.
How It Died: Your Code Can Be Fine and Your Site Still Dies
The failure had nothing to do with the application. The codebase was healthy. The database was healthy. A billing suspension at the hosting provider took the deployment offline, and a separately stuck domain transfer meant there was no quick path to standing it back up at the same address.
That is the uncomfortable part. Every dependency you rent — hosting, DNS, domain registrar — is a wire your product hangs from, and any one of them can be cut for reasons that have nothing to do with the quality of your engineering. VIBE was pre-launch, so the blast radius was small. If it had paying customers, six weeks dark would have been fatal.
The Resurrection Checklist
The July 3 session broke into two phases: get it live, then make it sellable. Phase one:
- Database restored from backup. All 3 tenants came back intact. Because the app was pre-launch when it went down, I could verify no customer data was lost — I checked anyway, table by table, rather than assuming.
- Hosting migrated from Vercel to self-hosted Coolify on a Hetzner VPS. Deploys on push, no platform billing dependency between my code and my uptime.
- Database moved to the same region as the VPS — Frankfurt. Health-check DB latency now reads around 26-33ms. App and database in the same region is the cheapest performance win there is.
- Stood up on a new subdomain, sidestepping the stuck domain transfer entirely instead of waiting on it.
At that point VIBE was live again. Most resurrection stories stop here. This is where the session actually got interesting.
Past "Back Online" to "Actually Sellable"
A SaaS that is up but cannot take money is a demo. The second half of the session wired the revenue path end to end.
Stripe billing, live
Three plans, webhook-driven. Checkout, subscription state, and plan changes all flow through webhook events rather than optimistic client-side state.
The bug that would have cost every sale
While testing the billing flow I found a real one: the public checkout endpoint was sitting behind the auth wall. An anonymous visitor clicking the buy CTA got redirected to sign-in instead of Stripe. Every single cold visitor who tried to pay would have bounced off a login screen for a product they did not have an account for yet — because they were trying to buy the account. The kind of bug that never shows up in your own testing, because you are always logged in.
Webhook-driven auto-provisioning
Fixing the checkout bug exposed the next gap: a paid checkout needs to produce a working account without a human in the loop. I shipped auto-provisioning off the payment webhook — a completed checkout headlessly creates the account, the organization, and the tenant, then sends a set-password email. Pay, click the email, you are in your CRM.
The email layer was silently failing
The email code only knew about one provider, and that provider was not configured in the new environment. No errors surfaced — sends just quietly went nowhere. I added a fallback cascade across providers, which un-broke three things at once: the drip-email cron, lead-form notifications, and welcome emails. Silent failure is the worst kind, and email is where it loves to live.
Crons that actually run
The old deployment listed its scheduled jobs in serverless cron config — config that meant nothing on the new host. I replaced it with real crontab entries on the VPS. A config file that lists crons is documentation, not automation. Something has to actually fire them.
The Outage Was a Free Audit
Here is the reframe that made the session productive instead of just stressful: six weeks of downtime meant I rebuilt the deployment from zero with fresh eyes, and every silent failure in the system surfaced at once. The checkout-behind-auth bug, the dead email layer, the crons that never ran — none of those were caused by the outage. They were all pre-existing. The outage just forced the kind of end-to-end walkthrough that running systems never get.
What I took from it:
- Platform billing failures take your site down whether your code works or not. Uptime is not only an engineering property. It is also a vendor-relationship property.
- "The config file lists crons" does not mean anything runs them. Verify the executor, not the manifest.
- The outage window is a free audit. If you ever have to bring a system back from dark, walk every flow like a stranger. You will find things.
- Self-hosting gave back control. Deploys on push, and no platform bill sitting between my product and its uptime.
Six Weeks Down, One Day Back
By the end of July 3, VIBE was live on new infrastructure, taking payments through three plans, provisioning accounts headlessly on paid checkout, sending email through a provider cascade, and running its scheduled jobs on a real scheduler. That is more than it did the day before it went dark.
The architecture behind the product is covered in the VIBE CRM case study, and the original zero-to-live build is in Shipping a Full CRM as a Solo Dev. If your product is down, half-dead, or held hostage by a platform, this exact playbook — restore, rehost, then audit every silent flow — is the work I do.