Using Heroku Review Apps to Test Pull Requests Safely and Cost‑Effectively
Learn how Heroku Review Apps automatically create isolated, disposable environments for every pull request, and how to configure, test, and manage their cost and limits.
28 Jul 2026, 23:57 UTC

Problem: Pull requests need reliable, isolated environments without manual setup
When a team relies on a single staging server, every pull request (PR) must wait its turn or risk interfering with others’ tests. Manual creation of temporary apps is error‑prone and time‑consuming, slowing down feedback loops.
Thesis: Heroku Review Apps automate ephemeral environments that match your pipeline’s slug and buildpacks, giving each PR its own testable URL while controlling costs through automatic cleanup.
How Review Apps work
When you enable Review Apps for a Heroku pipeline, the platform watches the connected GitHub repository. On PR open, Heroku creates a new app using the same slug and buildpacks as the parent pipeline, copies configured config vars, and optionally shares selected add‑ons (e.g., Heroku Postgres, Redis). The app receives a unique URL like pr-123.example.com. When the PR is closed, merged, or idle beyond a timeout, Heroku destroys the app, freeing dyno hours.
Setting up Review Apps via the CLI
- Prerequisites: You need the Heroku CLI (
heroku) installed, login (heroku login), and permissions to manage the target pipeline (pipeline:admin or higher). - Ensure a pipeline exists (create if missing):
heroku pipelines:create my-app-pipeline \ --app my-app-prod # existing production app - Connect your GitHub repo to the pipeline:
heroku pipelines:connect my-app-pipeline \ --repo https://github.com/yourorg/your-repo - Enable Review Apps and optionally choose which add‑ons to share:
heroku pipelines:enable-review-apps my-app-pipeline \ --wait-for-ci # optional: wait for CI to pass before creating - Configure sharing and timeout (example: share Heroku Postgres hobby‑dev, destroy after 2 hours idle):
heroku pipelines:update-review-apps my-app-pipeline \ --addon-sharing heroku-postgresql:hobby-dev \ --idle-timeout 120 # minutes
Worked example: testing a feature branch
Assume a branch feature/login-ui opens PR #42 against main.
- After the PR is opened, Heroku provisions a review app. You can find its URL in the Dashboard under the pipeline’s “Review apps” tab or via CLI:
The output lists something likeheroku pipelines:review-apps my-app-pipelinepr-42.myapp.herokuapp.com. - Open that URL in a browser or run a smoke test (e.g.,
curl -s https://pr-42.myapp.herokuapp.com/health) to verify the branch’s code is running. - If you need to inspect logs, run:
heroku logs --app pr-42.myapp.herokuapp.com --tail - When the PR is merged or closed, Heroku automatically destroys the app. Confirm destruction with:
If the app is gone, the command returns an error likeheroku apps:info --app pr-42.myapp.herokuapp.comApp not found.
Trade‑offs and limitations
- Resource cost: Each review app runs on the same dyno type as the parent pipeline. If the parent uses performance‑L or Private dynos, every review app consumes equivalent dyno hours. Teams should set aggressive idle timeouts or limit concurrent PRs to avoid surprise bills.
- Add‑on sharing constraints: Not all Heroku Postgres plans allow followers. For example, standard‑0 tiers prohibit creating a follower, so a review app cannot get a full copy of the production database; it would receive an empty database or a dev‑only plan.
- Ephemeral state: Any data written to non‑shared add‑ons or the local filesystem disappears when the app is torn down. Review apps are unsuitable for long‑running stateful tests that require persistent storage beyond the test run.
- Idle timeout enforcement: If a PR stays open for days, the review app continues to drain dyno hours until the idle timeout triggers. Regularly reviewing open PRs and enforcing timeout policies mitigates wasted usage.
Actionable closing
To start using Review Apps today:
- Enable them for each pipeline with the CLI commands above.
- Define a sensible idle timeout (e.g., 60‑120 minutes) based on your team’s PR lifecycle.
- Document which add‑ons can be shared and communicate any limitations to developers.
- Monitor dyno usage via the Heroku Dashboard’s “Usage” view; set up alerts if consumption exceeds a threshold.
By treating each pull request as its own disposable environment, you gain faster, isolated feedback while keeping operational overhead low.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.