Clean up Upstash preview databases after pull requests close
Every night, find the preview databases whose pull request closed days ago, delete only the ones that are safe, and report the savings in Slack.
Every night at 2am, sweep my Upstash account for preview and pull request Redis databases that outlived the branch they were created for. Forgotten preview databases are a silent cost leak, because Upstash bills storage per GB-month plus per command, so an orphaned database keeps charging me long after its branch is gone. Safety is the point of this workflow: it should always be far more willing to leave a database alone than to delete one.
Start with the Upstash List Redis Databases operation to pull every database in the account. Select only databases whose name matches my preview naming convention, meaning a pr- or preview- prefix carrying the pull request number, for example pr-1234-checkout or preview-1234. Treat this prefix list as a strict allowlist. Any database whose name does not start with one of those prefixes is out of scope completely: do not resolve it, do not treat it as a candidate, and never delete it under any circumstance. Production, staging, and everything else must go untouched. It is fine to report how many databases were ignored for not matching, but do not list them individually.
For each database that does match, parse the pull request number out of the name and resolve the corresponding pull request in GitHub. Use List Pull Requests, filtering by state so that open, closed, and merged pull requests are all visible, or Search Issues and Pull Requests with query qualifiers when the repository is not obvious from the database name. Use Get a Pull Request to read the merge status and the exact time the pull request was closed. Also call the Upstash Get Redis Database Stats operation for every candidate, so the report can show what each stale database is costing per month.
Delete a database with the Upstash Delete Redis Database operation only when every one of these conditions holds: the database name matched the preview prefix allowlist, the pull request was confidently resolved to exactly one pull request, that pull request is closed or merged, and it has been closed for at least three full days. The three day grace period is deliberate. Do not delete the instant a pull request merges, because people reopen pull requests and re-run previews shortly afterwards. A nightly sweep also catches databases whose pull request closed long before this workflow existed.
If a pull request cannot be confidently resolved, skip the database and leave it in place. Ambiguity always means skip, never delete. That covers a name with no parseable pull request number, a number that matches no pull request, a number that matches more than one pull request with no reliable way to tell which is correct, and any case where the GitHub lookup fails or errors. Every skipped database must appear in the summary with the specific reason it was skipped, so I can either fix the naming or remove it by hand.
The very first execution must be report only and must delete nothing, whatever it finds. I want to confirm that the naming convention actually matches my databases before anything is removed. That first summary should state plainly that it was a dry run and list exactly what it would have deleted. Once I have confirmed that report, deletion can be turned on for later runs.
Finish every run by posting a summary with the Slack Bot Send a Message operation. Show what was deleted, naming each database and its pull request, the estimated monthly saving for each one and the total saved across the sweep, and then every candidate database it deliberately left alone together with the reason, such as the pull request still being open, the database sitting inside the three day grace period, or the pull request not being resolvable. Post the summary even when nothing qualified for deletion, so I know the sweep ran.
Example output
What does this prompt do?
- Checks your Upstash account every night for preview databases that were created for a pull request which has since closed or merged.
- Matches each one back to its pull request in GitHub and works out what the leftover database is costing you each month.
- Deletes only the ones that are clearly safe to remove, and leaves anything uncertain exactly where it is.
- Posts a Slack summary showing what was removed, how much you are saving, and everything it chose not to touch along with the reason.
What do I need to use this?
- An Upstash account containing the preview databases you want cleaned up.
- A GitHub account with access to the repositories those preview databases belong to.
- A Slack workspace where the nightly summary can be posted.
- A naming convention for preview databases that includes the pull request number, such as pr-1234 or preview-1234.
How can I customize it?
- The naming pattern it treats as a preview database, if you use a prefix other than pr- or preview-.
- The waiting period after a pull request closes, which starts at three days.
- Whether it deletes at all, so you can keep it in report-only mode for as long as you want.
- What time it runs each night and which Slack channel receives the summary.
FAQs
Will this ever delete my production database?
What happens on the very first run?
What if it cannot tell which pull request a database belongs to?
Does it delete a database the moment the pull request merges?
How does it know what I am saving?
Related templates
When someone leaves, we check which shared passwords they used in their final months and post a ranked rotation list to your security channel.
Every Monday, check every S3 bucket for public exposure, missing encryption and weak backup settings, then get the risks ranked in Slack.
Twice every weekday, the conversations from your social inbox land on the right HubSpot contact timelines, with a Slack recap for sales.
Every morning, find the addresses that hard bounced or filed a spam complaint, update the matching HubSpot contacts, and post a short Slack recap.
Every weekday at 4pm, spot the threads that went quiet, stage a ready-to-send nudge in your mailbox, and get a ranked Slack recap.
When you merge a fix in GitHub, this agent checks the matching dead-letter queue, replays the failed messages, and reports back on the pull request and in Slack.
Stop paying for preview databases you forgot about.
Set up a nightly sweep that clears out the leftovers safely and tells you exactly what it saved.