# Beta Feature: Try Out App-scoped Egress IPs

**URL:** <https://community.fly.io/t/beta-feature-try-out-app-scoped-egress-ips/26536>\
**Category:** Fresh Produce\
**Created:** [November 28, 2025, 8:09pm UTC](https://community.fly.io/t/beta-feature-try-out-app-scoped-egress-ips/26536 "2025-11-28T20:09:47Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![PeterCxy](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/petercxy/32/36155_2.png) [@PeterCxy](https://community.fly.io/u/PeterCxy)\
**Post date:** [November 28, 2025, 8:09pm UTC](https://community.fly.io/t/beta-feature-try-out-app-scoped-egress-ips/26536/1 "2025-11-28T20:09:47Z")

</div>

Since we launched our [machine egress IPs](https://fly.io/docs/networking/egress-ips/) feature, we’ve received numerous feedback about how this felt a bit clunky to use. Not only do you need one per machine, they are also permanently bound to a _specific_ machine with no easy way to “transfer” between them: if you ran a bluegreen deployment, for example, _all_ the newly-created machines will not have egress IPs, and all currently assigned egress IPs will be released when the old machines get destroyed during the bluegreen deployment process. We hear you: it is frankly quite weird to have a platform feature that _restricts_ the use of other core features in this way. The original intention was that egress IPs will be mostly used through some kind of [proxy app](https://fly.io/docs/networking/egress-ips/#the-proxy-pattern), but even that comes with its own drawbacks.

To solve this, in the past little while, we have been working on a new kind of egress IPs that are scoped to an (app, region) tuple. Yes, I lied a little bit in the title: due to the way egress IPs are usually used (accessing external resources under GeoIP restrictions, for example), and the fact that “Anycast”-ing these IPs will be quite complicated routing-wise (we’ll essentially have to replicate egress flow tables globally), you still need separate egress IPs per region if you have machines in multiple regions. But: they are no longer bound to single machines, and you are free to use bluegreen deployments without fear of losing egress IPs. If you have an app-scoped egress IP assigned in a region, _every machine_ in your app in that region will use that same egress IP (with some caveats applied – see below). They are only released when you explicitly release the IP via a command, not automatically when a machine is destroyed.

This feature is currently **beta** , meaning that despite we think it _should_ work, it _might_ not! And there will probably be rough edges which we will gradually polish up in the next little while. We can’t do that without you, the user, and this is why we’re shipping it right now so that you can try it out!

# How do I use it?

The `flyctl` version `0.3.227` ([released](https://github.com/superfly/flyctl/releases/tag/v0.3.227) today) contains initial support for managing app-scoped egress IPs. Since these new egress IPs belong to apps rather than machines, they share the same `ip` subcommand as our regular Anycast IPs (used for ingress).

To allocate one for a specific region:

```auto
flyctl ip allocate-egress -r <region>

```

To view the list of all egress IPs (in fact, all IPs _except_ for the old machine-scoped egress, which uses a different subcommand):

```auto
flyctl ip list

```

This command is now also explicit about ingress vs. egress IPs. Unfortunately, we still cannot “just” use the ingress IPs for egress purposes (for mostly the same reasons why egress IPs are regional, plus the existence of Fly Proxy as a load balancer on all Anycast IPs).

To release app-scoped egress IPs:

```auto
flyctl ip release-egress <egress_ip_1> [egress_ip_2] ...

```

Managing app-scoped egress IPs is not currently supported by our web control panel, and our documentation has not been updated to reflect this new feature yet. We will be working on that in the coming weeks.

# What are the caveats?

1. These IPs are associated with regions, so if your app spans multiple regions, you will need multiple egress IPs. Only machines located in the same region as an egress IP can make use of that egress IP.
2. These IPs aren’t implemented as managed virtual gateways (yet). Rather, we semi-statically assign source port ranges to each machine, propagate state and resolve conflicts via [Corrosion](https://github.com/superfly/corrosion). This means that:
  - There can be a delay between when a machine is created or when a new egress IP is assigned and when the egress IP is usable.
  - When there are conflicts between port assignment among machines (e.g. when creating a large amount of machines at once), internet may be temporarily unavailable for some machines while the conflict is resolved. You can reduce the chance of this happening by allocating more egress IPs.
  - There’s a maximum number of machines each egress IP can support. Currently, that number is 64. Do note that if you use bluegreen deployments, your number of machines will double while a deployment is in progress. The solution is however simple: you can allocate more than 1 egress IPs per app per region. Each machine will pick one randomly out of all that are available.
  - There’s a maximum number of connections each one of your machines can create to _each destination IP_. That number is currently 1024 (this does **not** mean each machine can only create 1024 connections in total! And it does **not** apply to the ingress direction either). We do not expect this to be a problem for most use cases requiring egress IPs, though: databases normally use ~100 - 200 connections at most, and HTTP endpoints generally come with multiple IP addresses. Combined with connection pooling and/or HTTP/2 multiplexing, most use cases should not require a lot of simultaneous outgoing TCP connections _targetting one single IP_. If this does become a problem, let us know and we’re happy to look at what we can do about it as the next step.

For most of these caveats, we have built some sanity checks and warnings into `flyctl` to bring them to your attention during machine creation, deployments, and IP assignment / release.

# How does it interact with machine-scoped egress IPs?

They are not intended to be used together. However, if you do assign a machine-scoped egress IP via `flyctl m egress-ip allocate`, as of now, the machine-scoped egress IP will override the app-scoped one.

We intend to eventually deprecate machine-scoped egress IPs in favor of app-scoped ones once they are stable – having both is going to be _very_ confusing. As a result, this behavior is not guaranteed to continue after app-scoped egress IPs are out of beta.

# How much does it cost?

While in beta, app-scoped egress IPs are free. We intend for the beta period to last a month or so. That means we will likely start billing for it around the time of the new year.

We’re still finalizing the pricing details, but an app-scoped egress IPv4 address will likely cost the same as a machine-scoped one, $3.60/mo billed hourly. IPv6 addresses are always assigned together with an IPv4, but they will likely not be billed for independently. If you do release _all_ of your egress IPv4 addresses but not all of the IPv6s, though, we may bill for the price of 1 IPv4 anyway (there will be a warning in `flyctl` if you did that!).

---

<div class="post-metadata">

**Author:** ![amo](https://avatars.discourse-cdn.com/v4/letter/a/73ab20/32.png) [@amo](https://community.fly.io/u/amo)\
**Post date:** [November 29, 2025, 2:07pm UTC](https://community.fly.io/t/beta-feature-try-out-app-scoped-egress-ips/26536/2 "2025-11-29T14:07:49Z")

</div>

Thank you for developing and sharing this new feature.

Unfortunately, I think I might miss the per-machine way of configuring static egress IPs. My use case: I have many machines for many clients kept in a single fly app. For single machines, I need a way to set a static IP without affecting all the others. Will there be a way to achieve that withthe new egress IP system?

---

<div class="post-metadata">

**Author:** ![vasallius](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/vasallius/32/43537_2.png) [@vasallius](https://community.fly.io/u/vasallius)\
**Post date:** [November 29, 2025, 6:04pm UTC](https://community.fly.io/t/beta-feature-try-out-app-scoped-egress-ips/26536/3 "2025-11-29T18:04:09Z")

</div>

from my understanding, don’t you just provision more than 1 static egress IP because a machine will randomly pick one?

---

<div class="post-metadata">

**Author:** ![PeterCxy](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/petercxy/32/36155_2.png) [@PeterCxy](https://community.fly.io/u/PeterCxy)\
**Post date:** [November 29, 2025, 6:06pm UTC](https://community.fly.io/t/beta-feature-try-out-app-scoped-egress-ips/26536/4 "2025-11-29T18:06:54Z")

</div>

There’s no guarantee each machine will pick a different one though. We may be able to look at whether we can special-case this if you have a _ton_ of egress IPs, for example 😃

---

<div class="post-metadata">

**Author:** ![vasallius](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/vasallius/32/43537_2.png) [@vasallius](https://community.fly.io/u/vasallius)\
**Post date:** [November 29, 2025, 6:09pm UTC](https://community.fly.io/t/beta-feature-try-out-app-scoped-egress-ips/26536/5 "2025-11-29T18:09:14Z")

</div>

so i guess work around for now if ever is one app - one machine - 1 static egress IP to guarantee and then just keep duplicating that app (since we shouldn’t use machine scoped ip because will be deprecated(?))

---

<div class="post-metadata">

**Author:** ![PeterCxy](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/petercxy/32/36155_2.png) [@PeterCxy](https://community.fly.io/u/PeterCxy)\
**Post date:** [November 29, 2025, 6:12pm UTC](https://community.fly.io/t/beta-feature-try-out-app-scoped-egress-ips/26536/6 "2025-11-29T18:12:33Z")

</div>

We do in general recommend app-per-customer instead of machine-per-customer for this type of use cases since machines don’t really isolate the 6PN network unlike apps (with a different network ID set for each customer). See: [One App Per Customer - Why? · Fly Docs](https://fly.io/docs/machines/guides-examples/one-app-per-user-why/)

---

<div class="post-metadata">

**Author:** ![vasallius](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/vasallius/32/43537_2.png) [@vasallius](https://community.fly.io/u/vasallius)\
**Post date:** [November 29, 2025, 6:13pm UTC](https://community.fly.io/t/beta-feature-try-out-app-scoped-egress-ips/26536/7 "2025-11-29T18:13:42Z")

</div>

the post mentions only the -r flag, but also mentioned it was per (app,region) tuple, so do we just use the -a flag to specify the app as well?

---

<div class="post-metadata">

**Author:** ![PeterCxy](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/petercxy/32/36155_2.png) [@PeterCxy](https://community.fly.io/u/PeterCxy)\
**Post date:** [November 29, 2025, 6:14pm UTC](https://community.fly.io/t/beta-feature-try-out-app-scoped-egress-ips/26536/8 "2025-11-29T18:14:41Z")

</div>

The `-a` flag is not needed if you’re executing the command under the directory with your app’s `fly.toml` 😃 That’s the case for most `flyctl` commands.

---

<div class="post-metadata">

**Author:** ![vasallius](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/vasallius/32/43537_2.png) [@vasallius](https://community.fly.io/u/vasallius)\
**Post date:** [November 29, 2025, 6:15pm UTC](https://community.fly.io/t/beta-feature-try-out-app-scoped-egress-ips/26536/9 "2025-11-29T18:15:15Z")

</div>

ah im reusing the same code and fly.toml and deploying in multiple apps so i usually pass in the -a flag haha! thanks!

---

<div class="post-metadata">

**Author:** ![erlangga](https://avatars.discourse-cdn.com/v4/letter/e/73ab20/32.png) [@erlangga](https://community.fly.io/u/erlangga)\
**Post date:** [December 1, 2025, 8:07am UTC](https://community.fly.io/t/beta-feature-try-out-app-scoped-egress-ips/26536/10 "2025-12-01T08:07:13Z")

</div>

Nice this would help a lot

---

<div class="post-metadata">

**Author:** ![soren-hansen](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/soren-hansen/32/14304_2.png) [@soren-hansen](https://community.fly.io/u/soren-hansen)\
**Post date:** [December 27, 2025, 1:18am UTC](https://community.fly.io/t/beta-feature-try-out-app-scoped-egress-ips/26536/11 "2025-12-27T01:18:43Z")

</div>

That sounds pretty nice! When will this be available in trough the Machine API? 😃

---

<div class="post-metadata">

**Author:** ![PeterCxy](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/petercxy/32/36155_2.png) [@PeterCxy](https://community.fly.io/u/PeterCxy)\
**Post date:** [January 6, 2026, 3:19pm UTC](https://community.fly.io/t/beta-feature-try-out-app-scoped-egress-ips/26536/12 "2026-01-06T15:19:39Z")

</div>

It’s on my list of things to do but I don’t have a timeline yet 😆

---

<div class="post-metadata">

**Author:** ![PeterCxy](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/petercxy/32/36155_2.png) [@PeterCxy](https://community.fly.io/u/PeterCxy)\
**Post date:** [January 6, 2026, 3:19pm UTC](https://community.fly.io/t/beta-feature-try-out-app-scoped-egress-ips/26536/13 "2026-01-06T15:19:53Z")

</div>

Also: this feature is no longer considered beta!

---

<div class="post-metadata">

**Author:** ![OnlyC](https://avatars.discourse-cdn.com/v4/letter/o/9d8465/32.png) [@OnlyC](https://community.fly.io/u/OnlyC)\
**Post date:** [March 18, 2026, 4:23am UTC](https://community.fly.io/t/beta-feature-try-out-app-scoped-egress-ips/26536/14 "2026-03-18T04:23:49Z")

</div>

Hi,  
How long is the delay from machine created to egress usable? What happan if machine send request during that delay? How can we solve it?

---

<div class="post-metadata">

**Author:** ![PeterCxy](https://sea1.discourse-cdn.com/fly1/user_avatar/community.fly.io/petercxy/32/36155_2.png) [@PeterCxy](https://community.fly.io/u/PeterCxy)\
**Post date:** [March 18, 2026, 2:13pm UTC](https://community.fly.io/t/beta-feature-try-out-app-scoped-egress-ips/26536/15 "2026-03-18T14:13:15Z")

</div>

Typically for a new machine it should just be a few seconds unless your egress IPs are near saturation (in which case you should create more) or there is another bug somewhere. In the mean time your machine may not have internet access or may not use the assigned egress IP(s). Usually retrying a few times for any requests on first startup should be enough to work around that.
