Using Heroku Review Apps to Test Pull Requests Without Breaking the Bank
Learn how Heroku Review Apps give every pull request its own test environment, how to configure them with app.json, and how to keep costs under control.
19 Aug 2026, 20:19 UTC

When a team relies on pull requests for code reviews, developers often need a place to run the changes before they hit main. Without an isolated environment, bugs slip through, and local setups can diverge from production. Heroku Review Apps solve this by spinning up a temporary app for each PR, using the same buildpacks and configuration as the parent pipeline.
How Review Apps Fit Into a Pipeline
Review Apps are created automatically when a pull request is opened against a GitHub‑connected Heroku Pipeline. They inherit the pipeline’s dyno type, config vars, and add‑ons, but you can override specifics via an app.json manifest. When the PR is merged or closed, the review app is destroyed; you can also set an inactivity timeout to clean up stale environments.
Configuring Review Apps with app.json
Place an app.json file at the root of your repository. The manifest controls which add‑ons are provisioned, environment variables, formation (dyno sizes), and lifecycle scripts.
{
"name": "my-service-review",
"description": "Review app for my-service PRs",
"keywords": ["node", "express"],
"env": {
"NODE_ENV": {
"value": "development"
},
"DATABASE_URL": {
"description": "Heroku Postgres URL",
"required": true
}
},
"addons": [
"heroku-postgresql:hobby-dev"
],
"formation": {
"web": {
"quantity": 1,
"size": "standard-1x"
}
},
"scripts": {
"postdeploy": "node ./seed.js"
}
}
This example provisions a hobby‑dev Postgres add‑on, sets NODE_ENV=development, and runs a seed script after the slug is built. Expensive add‑ons (e.g., heroku‑redis:premium) can be omitted or replaced with cheaper plans to keep costs predictable.
Managing Cost and Lifecycle
Review Apps consume dyno hours and add‑on usage while they exist. To avoid surprise bills:
- Set an inactivity timeout in the Pipeline settings (e.g., 24 hours) so idle apps are destroyed automatically.
- Use the
addonsarray inapp.jsonto exclude or downgrade non‑essential services. - Monitor usage by filtering the Heroku metrics dashboard for the review‑app name prefix (default:
pr-).
If a review app fails to destroy (e.g., due to a script error), the timeout will still trigger cleanup, but you should verify the setting.
Worked Example: Enabling Review Apps for a Repository
- Ensure you have pipeline admin rights in the Heroku Dashboard.
- From your local machine (or CI runner) run the Heroku CLI:
heroku pipelines:enable my-service-pipeline heroku pipelines:add --app my-service --pipeline my-service-pipeline heroku pipelines:reviewapps:enable my-service-pipelineReplace
my-service-pipelineandmy-servicewith your actual names. The commands requirepipeline:writescope on your Heroku account. - Push a branch and open a pull request on GitHub. Heroku will create a review app named something like
pr-123-my-service-review. - Verify the app is running:
heroku reviewapps:list --pipeline my-service-pipelineYou should see the new PR entry with a status of
completedonce the build finishes. - Check that the seed script ran by viewing logs:
heroku logs --app pr-123-my-service-review --source web - When the PR is merged or closed, the review app disappears automatically. You can also manually destroy it with
heroku apps:destroy -a pr-123-my-service-review -c pr-123-my-service-review(use with caution).
Trade‑offs and Limitations
Review Apps are not exact production replicas. They may run on a different dyno size, use a cheaper add‑on plan, or lack certain config vars that are set only in staging or production. Consequently, some bugs may only appear later. Additionally, Review Apps require GitHub integration; GitLab, Bitbucket, or self‑hosted Git do not trigger them natively without extra automation. Finally, because app.json is committed to the repository, never store production secrets there—use Heroku config vars or a secrets add‑on instead.
Actionable Closing
To start using Review Apps today:
- Add an
app.jsonto your repo that defines the minimal add‑ons and scripts you need for testing. - Enable the feature on your Heroku Pipeline via the CLI or Dashboard.
- Set an inactivity timeout to protect against forgotten apps.
- Review your usage metrics weekly to catch any unexpected spend.
With these steps, each pull request gets a disposable environment that catches integration issues early, while you retain control over costs and operational overhead.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.