Harnessing Heroku Review Apps: A Practical Guide to PR Environments
Discover how Heroku Review Apps spin up per‑PR environments, configure them via app.json, and balance dyno usage for a smooth CI/CD workflow.
17 Oct 2025, 12:13 UTC

Problem: How to Spin Up Reliable, Ephemeral Environments for Every Pull Request?
When a team pushes a new feature to a branch, the question is: how do we test that change in a real, isolated environment that mirrors production? Manual staging or duplicated servers can be costly and error‑prone. Heroku’s Review Apps promise an automated, per‑PR deployment that lives in the same ecosystem as your main app. The challenge is to understand the feature’s mechanics, configure it correctly, and keep an eye on hidden costs.
Thesis: Review Apps are a powerful, but bounded, tool that integrates tightly with Heroku Pipelines and GitHub. They work best when you treat them as first‑class CI artifacts rather than permanent services.
1. Review Apps 101 – What They Are and How They Work
When you enable Review Apps on a Heroku Pipeline, every open pull request triggers the creation of a new Heroku app. The new app uses the same buildpacks, add‑ons, and config vars defined in the repository’s app.json file. Heroku injects three special config vars:
HEROKU_PR_NUMBER– the pull‑request numberHEROKU_APP_NAME– the generated app name (e.g.,myapp-12-abcd)HEROKU_BRANCH– the branch that opened the PR
These vars allow your code to build URLs or subdomains that are guaranteed to be unique to the PR. Once the PR is merged or closed, Heroku automatically tears down the app, freeing resources.
2. Crafting app.json for a Review App
The app.json file is the single source of truth for a Review App’s shape. Below is a minimal, yet functional, example for a Rails application that needs a database, a worker dyno, and a seed script.
{
"name": "myapp",
"formation": {
"web": { "quantity": 1 },
"worker": { "quantity": 1 }
},
"addons": [
"heroku-postgresql:hobby-dev"
],
"scripts": {
"postdeploy": "bundle exec rake db:migrate db:seed"
},
"env": {
"RAILS_ENV": { "value": "production" }
},
"required": ["DATABASE_URL"]
}
Key points:
- The
addonssection pulls the same add‑on plan for Review, Staging, and Production unless you override it elsewhere. - Post‑deploy scripts run only once, on the first creation of the Review App. Subsequent pushes to the same PR will reuse the slug, so schema changes must be handled manually.
- Marking a var as
requiredforces the pipeline owner to set it in the pipeline settings before the first Review App spins up.
3. Automating the Flow with the CLI
Below is a quick checklist of Heroku CLI commands you’ll need to set up a pipeline that automatically creates Review Apps.
# Create a new pipeline and connect it to GitHub
heroku pipelines:create --app myapp-prod --stage production
heroku pipelines:connect --app myapp-prod --repo myorg/myrepo
# Enable Review Apps on the pipeline
heroku pipelines:review-apps:enable --app myapp-prod
# Optionally set the inactivity timeout (default 5 days)
heroku pipelines:review-apps:set --app myapp-prod --inactivity-interval 7d
Run these commands from the machine that has the Heroku CLI installed and is authenticated with an account that owns the target app.
4. Lifecycle and Cleanup
Review Apps stay alive as long as the pull request is open. If a PR is merged or closed, Heroku deletes the associated app immediately. If a PR remains open for more than the inactivity interval (default 5 days), Heroku automatically destroys the Review App to reclaim dyno hours and add‑on credits.
Because Review Apps share the same slug as the main app, you can promote a Review App to Staging or Production by simply moving the slug through the pipeline. This guarantees that the code tested in the PR is exactly what ships.
5. Trade‑offs & Limitations
- Dyno Hours & Add‑On Quota: Every Review App consumes a dyno and any add‑ons you declare. A repo with dozens of concurrent PRs can quickly exhaust free‑tier limits.
- No Conditional Add‑Ons:
app.jsoncannot specify different add‑on plans for Review versus Production. You must manage this manually if you need a smaller plan for previews. - Postdeploy Scripts Only Once: Schema migrations or seed data run only on the first deployment. Later changes require a manual rebuild or a custom release phase script.
- Private Spaces & Shield: These Heroku tiers do not support Review Apps. Teams on those plans must use alternative preview strategies.
- Ephemeral Databases: Each Review App gets its own fresh database. Seed data should be idempotent and quick; otherwise, the build can hit the 90‑minute timeout.
- CI Integration Needed: Heroku does not run tests automatically. You must hook your CI system (GitHub Actions, CircleCI, etc.) to hit the Review App’s URL and assert correctness.
6. Actionable Checklist for Your Team
- Enable Review Apps on your pipeline and confirm the
app.jsonis in the repo root. - Verify that the
HEROKU_PR_NUMBERandHEROKU_APP_NAMEvars appear in the Settings → Config Vars of a newly created Review App. - Integrate a CI job that curls the Review App’s URL and checks for expected content.
- Monitor Account Settings → Billing for dyno-hour usage. If you hit limits, consider reducing the inactivity interval or scaling down add‑on plans for Review Apps.
- Document the rebuild process: if a PR’s schema changes after the first deployment, run
heroku review-apps:rebuild --app myapp-pr-123to force a new slug.
By treating Review Apps as part of your CI/CD pipeline, you gain instant, production‑like previews for every PR while keeping costs predictable. The key is to understand the lifecycle, configure app.json thoughtfully, and monitor resource consumption.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.