Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 20 additions & 6 deletions networking/egress-ips.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@
- You can allocate **static egress IPs** for an app (both IPv4 and IPv6) via `fly ips allocate-egress`.
- App-scoped static egress IPs are per-region: you need one for each region where you have machines.
- Static egress IPs come with trade-offs: they cost more, and limit how many machines you can run at once.
- Legacy machine-scoped static egress IPs are still availble, but are no longer recommended due to their limitations and quirks.
- Legacy machine-scoped static egress IPs are still available, but are no longer recommended due to their limitations and quirks.

---

## Why Egress IPs Matter

Some external services—APIs, databases, payment providers—require allowlisting source IPs. Without static egress IPs, outbound IPs from Fly machines may change due to machine lifecycle or infrastructure changes.

Check warning on line 21 in networking/egress-ips.html.md

View workflow job for this annotation

GitHub Actions / Vale linter

[vale] reported by reviewdog 🐶 [Fly.Spelling] Is 'allowlisting' a typo? Raw Output: {"message": "[Fly.Spelling] Is 'allowlisting' a typo?", "location": {"path": "networking/egress-ips.html.md", "range": {"start": {"line": 21, "column": 67}}}, "severity": "INFO"}

- Machines often egress over IPv6 when the destination has an AAAA record and the application prefers it. For example, `curl` will try IPv6 first if available, then fall back to IPv4 if needed. Fly doesn’t force IPv6, but many apps will use it when it's available.
- IPv4 traffic is NAT'd and may vary. This means the source IP address is rewritten by the host, and which IP you get can change depending on where the machine runs or is restarted.

Check warning on line 24 in networking/egress-ips.html.md

View workflow job for this annotation

GitHub Actions / Vale linter

[vale] reported by reviewdog 🐶 [Fly.Spelling] Is 'NAT'd' a typo? Raw Output: {"message": "[Fly.Spelling] Is 'NAT'd' a typo?", "location": {"path": "networking/egress-ips.html.md", "range": {"start": {"line": 24, "column": 19}}}, "severity": "INFO"}
- You need static egress if you're allowlisting IPs with third-party services.

Check warning on line 25 in networking/egress-ips.html.md

View workflow job for this annotation

GitHub Actions / Vale linter

[vale] reported by reviewdog 🐶 [Fly.Spelling] Is 'allowlisting' a typo? Raw Output: {"message": "[Fly.Spelling] Is 'allowlisting' a typo?", "location": {"path": "networking/egress-ips.html.md", "range": {"start": {"line": 25, "column": 36}}}, "severity": "INFO"}

---

Expand Down Expand Up @@ -52,24 +52,38 @@
fly ips release-egress <ip-address>
```

App-scoped egress IPs are only released when you explicitly run `fly ips release-egress`. They persist across Machine destruction and deployments.

### Billing

Each app-scoped IPv4 static egress address costs $3.60/mo, billed hourly. IPv6 addresses are currently free, but must be allocated along with an IPv4.
Each app-scoped IPv4 static egress address costs $3.60/mo, billed hourly. IPv6 addresses are allocated alongside IPv4 and are not billed separately.

### Caveats

- Each static egress IP can support up to 64 Machines. If you need more than 64 Machines in one region, you will need to allocate multiple static egress IPs.
- When using App-scoped static egress IPs, a Machine can make up to 1000 connections to _each_ external IP address. There is no limit on the _total_ number of concurrent connections.
- We do not expect this to be a concern for most apps. However, feel free to talk to us if this limits your use case!
- When using app-scoped static egress IPs, a Machine can make up to 1024 concurrent connections to _each_ destination IP address. There is no limit on the _total_ number of concurrent connections.

<div class="note icon">
We do not expect this to be a concern for most apps. However, feel free to talk to us if this limits your use case!
</div>
- When you have multiple static egress IPs assigned in one region, there is currently no way to specify exactly which IP each machine will use.
- When new machines are created, there might be a brief window when an app-scoped egress IP is not applied to the machine. This may happen more often with more machines or during bluegreen deployment. Allocating multiple pairs of static egress IPs alleviates the issue.
- There may be delays when egress IPs are applied to Machines:
- Right after allocating a new egress IP, it will be applied to all existing Machines in the region after a short delay. Allocating multiple pairs of static egress IPs will not help in this case.
- When creating a new Machine in an app that already has an egress IP assigned, there may be a delay before the Machine can use the egress IP. This delay may be more noticeable with more Machines or during bluegreen deployments. Allocating multiple pairs of static egress IPs can help alleviate this issue.
- `flyctl` surfaces warnings when these limits are approached during Machine creation, deployments, and IP management.

### Interaction with Machine-Scoped Egress IPs

App-scoped and machine-scoped egress IPs are not intended to be used together.

If a Machine has a machine-scoped egress IP, it takes precedence over any app-scoped egress IP in the same region. This behavior may change in the future.

---

## Static Egress IPs (Machine-Scoped)

<div class="warning icon">
Machine-scoped static egress IPs are considered a legacy feature and may be removed in the future. This section is kept for reference purposes only. New apps should use [app-scoped static egress IPs](#static-egress-ips-app-scoped).

Check failure on line 86 in networking/egress-ips.html.md

View workflow job for this annotation

GitHub Actions / Vale linter

[vale] reported by reviewdog 🐶 [Vale.Terms] Use 'IPs' instead of 'ips'. Raw Output: {"message": "[Vale.Terms] Use 'IPs' instead of 'ips'.", "location": {"path": "networking/egress-ips.html.md", "range": {"start": {"line": 86, "column": 216}}}, "severity": "ERROR"}
</div>

### Allocate a Static Egress IP
Expand All @@ -93,7 +107,7 @@

- IPs are released when a machine is destroyed.
- IPs don’t automatically transfer across deploys.
- Blue/green deployments will replace machines—and their IPs.
- Bluegreen deployments will replace machines—and their IPs.

Check failure on line 110 in networking/egress-ips.html.md

View workflow job for this annotation

GitHub Actions / Vale linter

[vale] reported by reviewdog 🐶 [Vale.Terms] Use 'bluegreen' instead of 'Bluegreen'. Raw Output: {"message": "[Vale.Terms] Use 'bluegreen' instead of 'Bluegreen'.", "location": {"path": "networking/egress-ips.html.md", "range": {"start": {"line": 110, "column": 3}}}, "severity": "ERROR"}
- Deployment-time jobs may bypass egress routing.
- Extra latency and connectivity issues are possible in some regions.

Expand All @@ -106,7 +120,7 @@
## The Proxy Pattern (for Machine-Scoped Static Egress IPs)

<div class="warning icon">
This section only applies to existing apps using machine-scoped static egress IPs. New apps should use [app-scoped static egress IPs](#static-egress-ips-app-scoped) instead.

Check failure on line 123 in networking/egress-ips.html.md

View workflow job for this annotation

GitHub Actions / Vale linter

[vale] reported by reviewdog 🐶 [Vale.Terms] Use 'IPs' instead of 'ips'. Raw Output: {"message": "[Vale.Terms] Use 'IPs' instead of 'ips'.", "location": {"path": "networking/egress-ips.html.md", "range": {"start": {"line": 123, "column": 150}}}, "severity": "ERROR"}
</div>

To avoid assigning static IPs to every machine, route traffic through a shared proxy app.
Expand All @@ -122,7 +136,7 @@

- Fewer IPs to manage.
- Primary app machines can be ephemeral.
- Centralize allowlisting.

Check warning on line 139 in networking/egress-ips.html.md

View workflow job for this annotation

GitHub Actions / Vale linter

[vale] reported by reviewdog 🐶 [Fly.Spelling] Is 'allowlisting' a typo? Raw Output: {"message": "[Fly.Spelling] Is 'allowlisting' a typo?", "location": {"path": "networking/egress-ips.html.md", "range": {"start": {"line": 139, "column": 14}}}, "severity": "INFO"}

### Downsides

Expand Down
Loading