Zero-Touch Neon Cost Control: Auto-Deleting Preview Databases on GitHub Branch Removal
TL;DR
Manual cleanup fixes yesterday’s mess. Automation prevents tomorrow’s invoice shock. This post documents how we wired GitHub branch deletion events directly to Neon preview database cleanup, ensuring zero orphaned branches, zero manual intervention, and predictable infrastructure costs.
This post focuses on preventive automation. For one-time cleanup and auditing, see Part 1.
Context: Why Manual Cleanup Is Not Enough
In the previous post, we covered how orphaned preview branches in Neon silently inflated our invoice—and how we cleaned them up safely with a script.
That solved the symptom.
This post solves the systemic failure.
As long as preview DB deletion is manual, cost leakage is guaranteed.
Modern teams move fast. Branches are created and deleted daily. Expecting humans to remember infra cleanup is operational fantasy.
Design Principle: GitHub Is the Source of Truth
If a GitHub branch no longer exists, its preview database should not exist either.
So the rule became simple:
Branch deleted in GitHub → Preview DB deleted in Neon
No dashboards.
No cron jobs.
No human decisions.
Just event-driven automation.
Why GitHub Actions Was the Right Control Plane
We evaluated multiple approaches. GitHub Actions won decisively:
Native access to branch lifecycle events
Secure secrets management
Zero external infra
Auditable execution logs
Team-wide visibility
Using GitHub Actions also ensured the solution stayed close to the code, not bolted on as an afterthought.
The Event That Matters: delete
GitHub emits a delete event whenever:
A branch is deleted
A tag is deleted
We explicitly scope this workflow to:
✅ Branches only
❌ Never tags
This avoids accidental or undefined behavior.
Guardrails First: Never Touch Protected Branches
Before touching Neon, the workflow enforces hard guardrails:
mainstagingproduction
If any of these are deleted (accidentally or otherwise), the workflow exits immediately.
No API calls.
No side effects.
No surprises.
This is not optional. This is table stakes for production safety.
The Automation Workflow (Production-Grade)
⚠️ Important
The workflow below is shared as-is. Nothing is removed, simplified, or abstracted.
Key Engineering Decisions (That Actually Matter)
1️⃣ Exact-Match First, Prefix Second
We attempt:
Exact branch name
preview/branch-name
This mirrors how most CI systems (Vercel, custom pipelines) name Neon branches.
2️⃣ Graceful Failure by Default
If the Neon branch:
Never existed
Was already deleted
Fails lookup
The workflow exits cleanly.
No red pipelines.
No alert fatigue.
No human intervention required.
3️⃣ Concurrency Control
The concurrency block ensures:
No race conditions
No double deletes
Predictable behavior under parallel branch deletions
This is critical in active repositories.
What This Gave Us Long-Term
🧾 Zero orphaned preview branches
💸 Predictable Neon invoices
🔒 Strong safety guarantees
🧠 One less thing engineers need to remember
Most importantly, we converted cost control into code.
Manual vs Automated Cleanup (Clear Distinction)
| Aspect | Manual Script | GitHub Action |
|---|---|---|
| Fix existing mess | ✅ | ❌ |
| Prevent future leaks | ❌ | ✅ |
| Human involvement | Required | None |
| Scalability | Limited | Unlimited |
| Operational maturity | Medium | High |
They are complementary—not substitutes.
Final Takeaway
Preview environments are powerful.
Unmanaged preview environments are expensive.
If your infrastructure lifecycle is not event-driven, you are paying a tax you don’t need to pay.
Automation is not an optimization. It’s governance.
