Heroku Review Apps: Automate Pull‑Request Testing Without Messing Up Production
Heroku Review Apps let teams spin up a disposable environment for each GitHub pull request. This guide shows how to enable, configure, and manage Heroku Review Apps for GitHub PRs, so you never pay for a forgotten sandbox.
02 Jul 2025, 21:24 UTC

Why Review Apps Matter
When a developer opens a pull request (PR) on GitHub, the team wants to see a fully‑deployed instance of the proposed changes—ready for QA, demo, or client review—without touching the main staging or production environment. Heroku’s Review Apps give you that “instant sandbox” for every PR, but the feature is easy to mis‑use if you don’t understand its limits and how it ties into your pipeline.
Key Takeaway
Enable Review Apps only for the PR stage, keep app.json minimal, and audit the dyno and add‑on usage before the PR closes, otherwise you’ll pay for a dozen short‑lived apps and risk leaking production data into test environments.
Setting Up a Minimal Review App
At its core, a Review App is just a Heroku app created automatically when a PR is opened. The automation is triggered by the GitHub integration in a Heroku pipeline. The only file that tells Heroku how to build the app is app.json.
1. Connect GitHub to a Heroku Pipeline
# From the Heroku Dashboard → Pipelines → New Pipeline
# Select "GitHub" as the source, choose the repo, and click "Connect".
# In the pipeline view, enable "Automatic Review Apps" for the "Review" stage.
Only GitHub integration can trigger Review Apps. If you use Bitbucket or GitLab, the feature is unavailable.
2. Add a Basic app.json
{
"name": "myapp",
"buildpacks": [
"https://github.com/heroku/heroku-buildpack-nodejs"
],
"scripts": {
"postdeploy": "npm run db:migrate"
}
}
Place this file in the repository root. When a PR is opened, Heroku will create an app named pr-123-myapp (the number is the PR ID). The app inherits config vars and addons from the parent app unless you override them.
3. Open a PR and Verify the App
# After the PR is created, check the Heroku Dashboard → Pipeline → Review stage.
# The new app should appear with a link like https://pr-123-myapp.herokuapp.com.
# CLI check (requires Heroku CLI and logged‑in account):
heroku apps:info -a pr-123-myapp
The output will show the dyno formation, config vars, and attached addons. If you don’t see the app, confirm that automatic review apps are enabled and that app.json is present.
Managing Secrets and Add‑Ons
Review Apps inherit all config vars from the parent app. If a var contains a production API key, the test environment will hit the real service, potentially causing side effects or data leaks. To mitigate:
- Use
app.jsonto override config vars for the review stage:"config": { "API_KEY": "test-key-{{ PR_NUMBER }}" }. - Scope add‑ons to the review app by declaring them in
app.jsonwith theaddonskey. For example, a free plan Postgres database will be spun up per review app, keeping test data separate. - Remember that shared add‑ons (e.g., a paid Redis instance) will receive traffic from every review app unless you explicitly create a new instance.
Cost & Resource Considerations
Every review app consumes dyno hours and any addon resources it declares. If you have dozens of open PRs, the accumulated cost can be significant, especially if you use paid add‑ons. Heroku provides a heroku review-apps:destroy command to clean up forgotten apps, but it’s safer to let the automatic destruction run after a PR is merged or closed. You can also enable retainReviewApps in the pipeline settings if you need the app to persist for a longer review period.
Example: Destroying a Stale Review App
# List all review apps in the pipeline
heroku review-apps --app myapp --stage review
# Destroy a specific review app (requires the app name)
heroku review-apps:destroy --app pr-123-myapp
Run this command from a terminal with the Heroku CLI installed and logged into the account that owns the pipeline.
Limitations and Trade‑Offs
While Review Apps are great for quick functional checks, they are not a replacement for a dedicated staging environment:
- They share the same Heroku account limits (app count, dyno hours, add‑on quotas). A runaway PR can hit the account’s limits.
- Network topology and region are the same as the parent app, so performance testing against a geographically distant region may not be realistic.
- They are not automatically protected from accidental data loss. Closing a PR deletes the app and any attached add‑on data unless you have a backup strategy.
- Secrets are inherited by default; you must explicitly override them to avoid leaking production credentials.
Actionable Checklist
- Enable Automatic Review Apps only for the PR stage in the Heroku Dashboard.
- Include a minimal
app.jsonthat declares necessary buildpacks and optional addons. - Override config vars that contain secrets or point to production services.
- Monitor dyno usage via the Heroku Dashboard or CLI:
heroku ps:info -a pr-123-myapp. - Clean up stale review apps with
heroku review-apps:destroyor set a retention policy. - Document the review‑app process in your team's onboarding guide to avoid accidental cost spikes.
By following these steps, you can harness Heroku Review Apps to speed up pull‑request feedback while keeping costs predictable and data safe.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.