Fast origin transfer is the highest cost (by far) on our NextJS app at about 1GB per day. We're growing, and want to prevent this from causing a cost spike in the near future.
In our app, some pages fetch data directly from the server, while some others use API routes. The vast majority of the data fetch happens on the server. These are the expensive operations in terms of data transfer. We have inspected all of the queries and reduced the data transfer to a minimum. Most of this data can be cached for long periods of time (1 day or more), so the expensive computation and transfer from origin shouldn't be necessary in theory.
In an attempt to reduce fast origin transfer, we've tried a couple of things. Firstly, using ISR with dynamic params (since there's 25k+ possible routes and we can't precompute every single one at build time). However, this has 2 big problems: it is way more expensive than fast data transfer and the UX is pretty awful (when loading a route with params that haven't been loaded before, the loading state does not show up - feels stuck - there's open issues for this already on GH). Secondly, we wrapped all of the expensive operations with unstable_cache. The cache definitely works but fast origin transfer is not reduced by a single byte. I would expect the cache to not have to refetch from origin.
The biggest problem, however, is that we can see fast origin transfer in the Usage tab of our project, but we can't see anything specific to fast origin transfer in Observability. It's currently impossible to know what paths are the major culprits without extensive debugging and trial and error. If we were certain a specific path is the culprit, we can change data loading to happen via API and cache response headers as suggested in the docs. In any case, feels like we have to work around Vercel + NextJS to avoid huge costs.
