Fly.io

Fly.io runs applications on Fly Machines, with networking and storage choices that affect where requests execute and where data survives. Begin with a stateless service, understand its routing and health behavior, and add persistence only after deciding how writes, replication, and recovery will work.

A global application needs more than a second regional process. If every request still crosses an ocean to reach its database, moving the web server closer to users may not improve the part of the request that matters.

TL;DR

Quick Example

This stateless teaching fixture requires Node 24 and no external packages. Save it as server.cjs. It serves a health endpoint and a small response without writing data or contacting another service.

For local checks, use HOST=127.0.0.1 through your shell's environment syntax and request /, /health, and an unknown path. The default listener is suitable for an external service interface; loopback alone would not serve Fly Proxy traffic to the application.

The companion fly.toml below illustrates a Fly Launch HTTP service. Replace the fictional app name with an available name belonging to your authorized test app. The iad primary region is an example, not a placement recommendation. This configuration is not a full deployable package: supply a reviewed container image/build definition that starts node server.cjs before provisioning anything.

The configuration reference documents these fields. The minimum applies in the primary region when autostop is enabled; it does not create a second Machine or guarantee redundant capacity. Health checks target the service within the private network. Local HTTP and TOML checks cannot establish that Fly Proxy, regional placement, autostart, or deployment health works.

Core Concepts

Machines are the compute boundary

Fly Machines are VMs controlled through an API; Fly Launch uses that API for its application orchestration. The Machines introduction describes the relationship. Distinguish the running instance, its image and configuration, and the app that groups it. A reproducible image is easier to replace than undocumented state accumulated in a running filesystem.

Region selection follows the complete request

Map the client, request handler, database, and any remote API on one path. For a read-heavy service with replicated data, another region may shorten useful work. For a transactional service tied to one writer, the consistency path can dominate. Treat these as hypotheses to measure with representative requests, including writes and cache misses.

Storage determines replacement options

The root filesystem is ephemeral; a Fly Volume is persistent local storage tied to a server and region. Volumes do not automatically synchronize their contents. The volume overview explains placement and redundancy limits. Adding a second Machine with an independent empty volume is not database replication.

Choose a State Model Before Scaling

This decision table is editorial guidance. Use it to expose assumptions, then test the selected design. If a service cannot tolerate the recovery time of its local state, changing a region setting will not repair that requirement. Evaluate a managed datastore or a replication system appropriate to the database, with clear ownership for its operation.

For a volume-backed app, inventory the mount path, writer process, replication topology, and replacement procedure. Check whether an operation runs on the normal application Machine or a temporary release Machine: do not assume the application's volume is available to every phase of a deployment. Keep migrations and data repair within their actual storage boundary.

Networking Has Its Own Trust Boundary

Fly's default organization private network uses IPv6 over WireGuard, and .internal names provide discovery for other apps in that network. The private-networking documentation explains the scope and address behavior. A service bound only to IPv4 is not automatically a reachable private IPv6 endpoint; configure and test the intended listener separately.

Private connectivity does not decide which caller may perform a business operation. Retain application authentication and authorization appropriate to the service. Review organization membership, secret access, and tenant boundaries alongside networking. If isolation requirements exceed the default network grouping, inspect supported isolation options before onboarding the workload.

Test the real client library's DNS and connection behavior. A hostname that returns several addresses does not prove the client balances requests or retries correctly. Observe an actual failing connection and a replacement instance, then record the application's recovery behavior rather than inferring it from an address list.

Make Recovery a Demonstrated Procedure

A snapshot is a point-in-time copy, so writes after that point may be missing from a restore. Fly's snapshot guide describes restoring into a new volume and recommends additional backup or replication methods for frequently changing data. Choose recovery-point and recovery-time objectives from the business requirement, then test whether the proposed system meets them.

In a controlled drill, identify the backup, restore to an isolated destination, start the application against the restored data, and inspect representative records and invariants. Measure elapsed time and missing data. Keep restored workers from sending real notifications or repeating external side effects while validating the copy.

Record how traffic would move, how a failed writer is fenced, and how the team avoids two independent writers after recovery. A backup listing establishes that an artifact exists. It does not demonstrate application consistency, usable credentials, correct mounts, or a successful return to service. Do not delete the original to make a rehearsal feel more realistic.

Best Practices

Keep the first pilot stateless

Verify image startup, service reachability, health checks, logs, and rollback before adding persistent state. This narrows the source of a failed deployment. Add a database only after its persistence and recovery tests have their own acceptance conditions.

Give health endpoints a bounded purpose

The fixture proves only that its HTTP handler responds. For a real app, decide whether the check represents startup, readiness, or another health signal. A check that always returns success can hide an unusable service; an overly broad dependency check can remove all instances during a shared outage.

Measure cold and warm request paths

Include request arrival after idle time, instance startup, and connection establishment. If the observed latency is unacceptable, retain suitable running capacity or revise the architecture. Autostart is a behavior to verify, not an instantaneous-response promise.

Review total operating cost

Compare the required compute, storage, traffic, backups, observability, and operational effort using current account-specific terms. This article supplies no price estimate or guaranteed savings. A smaller idle compute footprint can coexist with a more demanding recovery design.

Common Mistakes

Bad: Store the only durable copy of customer data in the root filesystem.

Correct: Select an appropriate persistent datastore and test its recovery path.

Bad: Treat a new regional volume as a synchronized copy.

Correct: Configure and verify replication explicitly, including write ownership and lag.

Bad: Count a green local /health response as a successful cloud deployment.

Correct: Check the actual service through Fly's routing and deployment mechanisms in the authorized environment.

FAQ

Is one running Machine highly available?

It remains a single instance with failure and maintenance consequences. Choose redundancy from the workload requirement and test the complete stateful path, rather than treating a minimum count as an availability guarantee.

Do volumes replicate automatically?

No. The application or datastore needs an explicit replication design. Check that another instance has current usable data before relying on it during failure.

Are snapshots enough for a database?

That depends on the database's consistency and recovery requirements. Validate an isolated restore and measure data loss and recovery time; use additional backup or replication methods where the objectives require them.

What did the local example verify?

Its HTTP routes and configuration structure can be checked locally. Fly account setup, builds, Machines, health routing, autostart, volumes, private networking, and recovery remain separate integration work.

Related Topics

References