Guide

A Static Outbound IP for Heroku

On the Heroku Common Runtime your dyno's outbound address changes whenever the dyno restarts, redeploys, scales or is cycled — which is at least daily. There is no setting that fixes it. The three real options are a Private Space (Heroku Enterprise), a proxy add-on, or routing the one allow-listed call through an address you hold. Which is right depends almost entirely on whether you are already paying for Enterprise.

Why the address moves

Common Runtime dynos run on shared infrastructure and take whatever outbound address the underlying instance has. Heroku cycles dynos roughly every 24 hours as a matter of routine, and any deploy, restart, scale or platform maintenance moves your code to a different instance. The address goes with it.

Heroku does not publish a usable range for this either, and if it did, the range would cover every Common Runtime customer — which is not an allow-list any security reviewer should accept.

The failure mode is nastier than a hard outage: everything works when you test it, and the integration breaks hours later when the dyno cycles, at a time nobody is watching. If you are reading this after an integration failed overnight for no apparent reason, that is very likely what happened.

Heroku's own answer: Private Spaces

A Private Space runs your dynos in an isolated network with stable outbound addresses that you can hand to a partner. This is the supported, first-party fix and it is genuinely the right answer — if you are on it. Private Spaces are a Heroku Enterprise feature, priced accordingly, and nobody buys Enterprise to solve one allow-listing problem.

If your company is already on Heroku Enterprise with a Private Space, use it and stop reading. It is included, it is operated by Heroku, and adding a third-party hop to infrastructure you are already paying to have run for you is a step backwards.

The add-on market, and what you are actually buying

Several add-ons on Heroku Elements — QuotaGuard Static, QuotaGuard Shield, Fixie and others — solve this by giving you a proxy endpoint with a fixed address and having your app send the relevant requests through it. They are mature, they install in minutes, and for many people they are the correct purchase.

Two things worth understanding before you buy, neither of which is a criticism:

We wrote a longer comparison of that trade-off in dedicated IP vs shared proxy.

The third option: an address you hold

If you are on the Common Runtime, not on Enterprise, and the requirement is a handful of named partner endpoints, you can attach a dedicated address to a small always-on box (a $5 VPS, a machine you already own) and have the dyno make those calls through it.

What the partner sees is your dedicated address from 23.187.152.0/24, announced by AS396500. It does not move when the dyno cycles, it is not shared with anybody, and it is not tied to Heroku — which matters if this app is one platform migration away from being somewhere else. Heroku apps move; the allow-list entry should not have to move with them.

Two honest caveats:

Choosing between them

Verify the source address before you file it

Whichever route you take, do not tell the partner the address you configured. Tell them the address a remote server actually sees, from the code path that will really make the call:

curl -4 https://api.ipify.org

Run it through the proxy or from the box the dyno will call through, and check it a second way (curl -4 https://ifconfig.co). Then run it again after a dyno restart — on Heroku specifically, a source address that is correct once and wrong tomorrow is the entire problem, so the second measurement is the one that matters.

What this costs with us

A dedicated address is $20/month on TunnelNet Full, inbound and outbound on the same address, attached to a machine you already have. TunnelNet Business is $100/month for the same address with a written 8-working-hour response commitment (09:00–17:00 US Central, Monday to Friday), onboarding done with a person who verifies the source address from outside our network before you file it, and our measured uptime published — incidents included.

Plainly, because you are about to put a partner integration on this: we have no SLA and will not offer one until we have six months of measured history, 21 February 2027 at the earliest. A hub failure that withdraws routes takes about 25 seconds to recover, measured — and a hub that stays up while it stops forwarding is not failed over automatically at all. Heroku will quote you better availability numbers than that, and they will be true. Weigh it against what the address itself is worth to you.

Static IP for your platform

The same question, answered for each platform it comes up on most. Every one of them leads with that platform's own native or free answer:

And the general case, if your platform is not listed: