Deploying NextJS to multiple regions using Fly.io

As the title suggests, I need to know if its possible to deploy a single NextJS App, with serverless functions, into two regions, namely, us-west and singapore. And have it so there’s one url and the users get routed to the closest deployment?

I’m asking because Vercel doesn’t allow this without forking out huge amounts of cash per month.

Please, if anybody can explain how to do this task, or if its even possible here. I’d greatly appreciate it.

Thank you!

Can you clarify what you mean by serverless? Serverless on Vercel (ie AWS) is slightly different than Fly (which are full servers.)

If you need the traditional serverless sense (AWS) then you might find Get Started - OpenNext interesting.

But you can achieve 99% of what Vercel offers by running your next app in a container on Fly. The 1% would be the Vercel specific functionality: distributed ISR caching, PPR, and next/after.

So like, in NextJS, /api endpoints are run as serverless functions. On Vercel, you can specify multiple regions for those serverless functions, but by default its just one.

I just have users in two regions so it should theoretically be as easy as just adding another region. If I can get that going I’d be happy.

Some more context: I have a CockroachDB cluster with regions in my two targeted areas. So just trying to put NextJS at those areas so as to make queries to /api as fast as possible for my users

Yes it’s possible. Instead of a “serverless” function, Fly boots up a container, runs the next app, and serves the request closest to your user (uswest or singapore).

If you configure your app to autostop, it’ll shutdown after 5-10minutes of idling.

1 Like

Would cold start times be of concern here? Is there a way to set minimum instances?

Fly uses the same firecracker runtime as AWS, so it should be similar. Might be faster/slower if one of them did some custom optimization.

Yea, check out the docs on fly to see all the configs.

1 Like

This all sounds good to me. How would I go about doing this with fly? Like can it all be done with the fly webapp? Deploying the project to whatever regions I choose then setting up some sort of loadbalancer (if necessary) to route the users to the closest deployment?

Most of it will be via the flyctl CLI, see Getting started · Fly Docs you have to learn to walk before you fly
You don’t have to worry about any load balancing, fly handles all that.

2 Likes

I really appreciate the help. I’ll take a look and try deploying a test app and see how it goes.

1 Like

Another good place to start: Deploy a Next.js app close to your users · Fly

And again confirming: “one url and the users get routed to the closest deployment” - you don’t have to do anything to get that. Start in one region, use fly scale count to add a second region, and you are done.

So the process of deploying to fly with multiple regions has been a breeze! Although I’m a little confused.

So, to test the regional deployment, I used a proxy ip in philippines, and called an api endpoint within my nextjs app that simply returns the ip address of the caller.

Something weird is happening though. For some reason the ip address being returned is based out of chicago???

I did confirm that when visiting the website from the proxy the signapore machine did spin up. But why is my api invocation being routed to chicago?

IP of Function call when done from Philippines: 2605:4c40:158:9902::6d6b:9f22:1
IP of Function call when done from Toronto: 2605:4c40:92:522a::e86e:a01e:1

Interestingly, this is also showing the only machine active during the testing in philippines is the Singapore one?

That’s expected? Philippines is closer to Singapore than Toroto.

This is in context to the original concern I mentioned. The Singapore machine is live, but in NextJS there is an /api route I call that returns me the ip of where the endpoint is being executed. So I connected to Philippines proxy, got the Singapore machine to boot up and loaded the website, but then hit the API from that, and it got executed in Chicago instead of Singapore?

Possibly the VPN service you’re using is routing the request from Chicago.
You only have YYZ and SIN right?

Yeah just YYZ and SIN. Hmm, makes me wonder if it is the VPN. But why would the VPN successfully load the site from Singapore and not route the api call correctly.

Instead of logging the IP, which isn’t always accurate (geolocation), log process.env.FLY_REGION to see if is indeed in SIN.

1 Like

Alright, will try that and report back

Try without a proxy ip. If you have access to curl:

curl --header "Fly-Prefer-Region: yyz" https://yourapp.fly.dev/

You can also pass this header from your client app. Or if you want to get really fancy, create an ephemeral machine in any region and run curl from there:

fly console --image curlimages/curl -C sh --region syd

Instead of (or in addition to) displaying the ip address, there are a number of interesting request headers: Public Network Services · Fly Docs

Your API server can also route requests to other regions: Dynamic Request Routing · Fly Docs

You can even VPN into your application’s private network: Jack into your private network with WireGuard · Fly Docs

1 Like