Skip to content

Regions

A region is a Fly.io datacenter. Machines, Volumes, Postgres clusters, and a Redis primary live in one. An App is global. It is not pinned to a region.

Alchemy defaults to iad (Ashburn, Virginia). Pass region to put a Service, Machine, or Postgres cluster somewhere else.

export default class Api extends Fly.Service<Api>()(
"Api",
{ main: import.meta.url, region: "lhr", port: 3000 },
Effect.gen(function* () {
return {
fetch: Effect.succeed(HttpServerResponse.text("hello")),
};
}),
) {}

count Machines run in that region.

const web = yield* Fly.Machine("Web", {
app: Site,
region: "syd",
image: "nginx:alpine",
});

Each Machine resource is one VM in one region. To run in two regions, declare two Machines.

A Volume is created in the parent Service or Machine’s region. It cannot move and cannot attach to a Machine in another region.

Restore into a new region from a VolumeSnapshot with snapshotId on the mount.

Pass a list to region to run the same Service in several regions behind one hostname. count Machines run in each region, and Fly’s Anycast proxy sends each request to the nearest healthy Machine.

export default class Api extends Fly.Service<Api>()(
"Api",
{ main: import.meta.url, region: ["iad", "lhr"], count: 2 },
Effect.gen(function* () {
return {
fetch: Effect.succeed(HttpServerResponse.text("hello")),
};
}),
) {}

This runs four Machines: two in iad and two in lhr. api.regions is ["iad", "lhr"], and api.url serves from both.

Adding or removing a region updates the Service in place. Its App and hostname stay the same, Machines in regions you keep are left alone, and a removed region’s Machines are deleted. A Volume from MountVolume is created in each Machine’s own region.

Fly sets FLY_REGION on the Machine. Read it in a Service with Config.

import * as Config from "effect/Config";
const region = yield* Config.String("FLY_REGION");

Codes are three letters. This list is what Fly published as of August 2026. Run fly platform regions or see Fly’s regions for the live set.

Code Location
ams Amsterdam, Netherlands
arn Stockholm, Sweden
bom Mumbai, India
cdg Paris, France
dfw Dallas, Texas (US)
ewr Secaucus, NJ (US)
fra Frankfurt, Germany
gru São Paulo, Brazil
iad Ashburn, Virginia (US)
jnb Johannesburg, South Africa
lax Los Angeles, California (US)
lhr London, United Kingdom
nrt Tokyo, Japan
ord Chicago, Illinois (US)
sin Singapore
sjc San Jose, California (US)
syd Sydney, Australia
yyz Toronto, Canada

A dedicated IpAssignment can take region too. Shared Anycast (shared_v4) ignores it.

The cluster lives in one region. Pass region on Fly.Postgres, not on the App.

const db = yield* Fly.Postgres("Db", {
region: "iad",
});

Fly.Redis takes primaryRegion. Default is iad. Read replicas are extra regions on readRegions.

const cache = yield* Fly.Redis("Cache", {
primaryRegion: "iad",
readRegions: ["sjc"],
});

Services pin region on the class. Machines pin it on the resource. Volumes follow the parent. Postgres is a billed cluster in one region. Redis pins primaryRegion.