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:
- The address is usually shared. On the entry tiers of most proxy services the fixed address is shared with other customers of that service. For a vendor allow-list that is often fine. For a bank, a payment processor or anybody performing a security review, “this address also belongs to an unknown number of other companies” is a question you will have to answer. The dedicated-address tiers exist and cost more.
- The quota is the product. These are priced by request volume or bandwidth. That suits a few thousand partner API calls and suits a high-volume data pipeline much less well. Read the tier limits against your actual call volume rather than your peak-hour guess.
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:
- You are adding a hop and a machine you have to keep running. An add-on is somebody else's to operate, and on a platform chosen specifically so you do not run machines, that is a real argument against us.
- It suits specific named calls, not “all outbound traffic from my app”.
Choosing between them
- Private Space if you are already on Heroku Enterprise, or you need every outbound connection from the app to come from a fixed address.
- A proxy add-on if you want it working this afternoon with no machine to own, your volume fits a tier comfortably, and a shared address passes whatever review you face.
- An address you hold if the reviewer will ask who else uses the address, if the same source needs to work from somewhere other than Heroku, or if you already run a small box anyway.
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:
- AWS Lambda — VPC and NAT Gateway, and what that really costs
- Vercel — $100/month per project, and Vercel documents the IPs as shared
- Netlify Functions — no list exists — what to try before building anything
- Supabase Edge Functions — Supabase documents that there is no static egress IP
- Render — shared by default, genuinely dedicated on Pro
- Railway — a Pro-plan toggle, and the “may be shared” caveat
- GitHub Actions — larger runners, or the free self-hosted answer
- Zapier — included on Professional, absent on Free
And the general case, if your platform is not listed: