You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: blueprints/per-user-dev-environments.html.md
+3-2
Original file line number
Diff line number
Diff line change
@@ -16,7 +16,7 @@ This blueprint explains how to use Fly Machines to securely host ephemeral devel
16
16
Your architecture should include:
17
17
18
18
-**Router app(s)**
19
-
- A Fly.io app to handle requests to wildcard subdomains (`*.example.com`). Uses `fly-replay` headers to transparently redirect each request to the correct app and machine. If you have clusters of users (or robots) in different geographic regions, you can spin up a router app in multiple regions (you might also want to consider a globally distributed datastore like [Upstash for Redis](https://fly.io/docs/upstash/redis/#what-you-should-know)).
19
+
- A Fly.io app to handle requests to wildcard subdomains (`*.example.com`). Uses `fly-replay` headers to transparently redirect each request to the correct app and machine. If you have clusters of users (or robots) in different geographic regions, you can spin up a router app in multiple region to increase reliability and reduce latency (you might also want to consider a globally distributed datastore like [Upstash for Redis](https://fly.io/docs/upstash/redis/#what-you-should-know)).
20
20
-**User apps (pre-created)**
21
21
- Dedicated per-user (or per-robot) Fly apps, each containing isolated Fly Machines. App and Machine creation is not instantaneous, so we recommend provisioning a pool of these before you need them so you can quickly assign upon request.
22
22
-**Fly Machines (with optional volumes)**
@@ -32,7 +32,8 @@ Your router app handles all incoming wildcard traffic. Its responsibility is sim
- Look up the correct app (and optionally machine ID) for that user.
35
-
- Issue a `fly-replay` header directing the Fly Proxy to [internally redirect the request](https://fly.io/docs/networking/dynamic-request-routing) (this should add no more than ~10 milliseconds of latency).
35
+
- Issue a `fly-replay` header directing the Fly Proxy to [internally redirect the request](https://fly.io/docs/networking/dynamic-request-routing) (this should add no more than ~10 milliseconds of latency if the router app is deployed close to the user).
36
+
- When appropriate, use [replay caching](https://fly.io/docs/networking/dynamic-request-routing/#replay-caching) to further reduce latency and load on the router app.
36
37
- Make sure you've added [a wildcard domain](https://fly.io/docs/networking/custom-domain/#get-certified) (*.example.com) to your router app (read more about the [certificate management endpoint here](https://fly.io/docs/networking/custom-domain-api/)).
Copy file name to clipboardExpand all lines: networking/dynamic-request-routing.html.markerb
+28
Original file line number
Diff line number
Diff line change
@@ -55,6 +55,26 @@ You can combine multiple fields:
55
55
fly-replay: region=sjc;app=app-in-same-org
56
56
```
57
57
58
+
## Replay Caching
59
+
60
+
In cases where the replay target does not change often, you can use the `fly-replay-cache` mechanism to relieve the original app of some load. Here's how it works:
61
+
- Issue a `fly-replay` header as usual
62
+
- Set `fly-replay-cache: example.com/some/path/*`
63
+
- This needs to be a path-matching pattern ending with a wildcard `/*`. This is where the cached replay is applied.
64
+
- The domain part should not include ports; use `example.com`, not `example.com:80`.
65
+
- The pattern must also match the current path of the request.
66
+
- Set `fly-replay-cache-ttl-secs: number_of_seconds`
67
+
68
+
If the replay target does eventually change, the replay target may proactively invalidate the cache by
69
+
- Issuing a `fly-replay` back to the origin
70
+
- Setting `fly-replay-cache: invalidate`
71
+
72
+
<div class="note icon">
73
+
**Note**: Replay caching is an optimization, not a guarantee. Your app should _not_ depend on this mechanism to function.
74
+
The app issuing `fly-replay` still serves as the ultimate source of truth, and we may decide to consult that app at any moment even if a replay cache has previously been set.
75
+
To ensure reliable operation, the app issuing `fly-replay` should still have multiple instances deployed in multiple regions.
76
+
</div>
77
+
58
78
## Implementation Details
59
79
60
80
### Requirements and Limitations
@@ -67,6 +87,12 @@ For large uploads that exceed the 1MB limit, consider:
67
87
- Using direct-to-storage uploads where possible
68
88
- Using the [fly-prefer-region](#the-fly-prefer-region-request-header) header instead
69
89
90
+
For `fly-replay-cache`, the following limitations apply:
91
+
- The `state` field cannot be set in the `fly-replay` intended to be cached
92
+
- The TTL needs to be a minimum of 10 seconds
93
+
- Only one step of lookup is performed in the cache; as such, if the target app issues another `fly-replay-cache`, the caching behavior in this case is undefined
94
+
- The `fly-replay-src` header (described below) will _not_ be set for requests replayed through the cache
95
+
70
96
### The fly-replay-src Header
71
97
72
98
When a request is replayed, Fly Proxy adds a `fly-replay-src` header containing metadata about the original request:
@@ -80,6 +106,8 @@ When a request is replayed, Fly Proxy adds a `fly-replay-src` header containing
80
106
81
107
This header is useful for tracking request paths and implementing consistency patterns. See the [official Ruby client](https://github.com/superfly/fly-ruby/blob/main/lib/fly-ruby/regional_database.rb#L74-L76+external) for an example of using these fields to prevent read-your-write inconsistency.
82
108
109
+
This header is not set when the request is replayed through a cached `fly-replay` entry (`fly-replay-cache`).
110
+
83
111
## Alternative Routing Headers
84
112
85
113
For cases where `fly-replay` isn't suitable, Fly.io provides two alternative request headers:
0 commit comments