# Monitoring latency: Cloudflare Workers vs Fly vs Koyeb vs Railway vs Render Source: https://www.openstatus.dev/blog/monitoring-latency-cf-workers-fly-koyeb-raylway-render ## Summary Openstatus compared latency across Cloudflare Workers, Fly.io, Koyeb, Railway and Render, using default or cheapest-tier settings and pinging each app every 10 minutes from six locations over two weeks in February 2024. Cloudflare Workers had the lowest average latency at 182ms with 100% uptime, though its Johannesburg checker was routed far from nearby data centers. Fly.io averaged 1,471ms because its machine cold-started, but its production instance, kept running, averaged 61ms. Railway averaged 381ms with one failure, and Render averaged 451ms with 12 failures, which the author attributed to cold starts. ## Article Feb 19, 2024 | by Thibault Le Ouay Ducasse | [education] ⚠️ We are using the default settings for each provider and conducting datacenter to datacenter requests. A real-world application's results are going to be different. ⚠️ You want to know which cloud providers offer the lowest latency? In this post, I compare the latency of Cloudflare Workers, Fly, Koyeb, Railway and Render using openstatus. I deployed the application on the cheapest or free tier offered by each provider. For this test, I used a basic Hono server that returns a simple text response. const app = new Hono(); app.use("*", logger()); app.use("*", poweredBy()); app.get("/", (c) => { return c.text( "Just return the desired http status code, e.g. /404 🀯 \nhttps://www.openstatus.dev", ); }); You can find the code in the status-code repository, it’s open source πŸ˜‰. Openstatus monitored our endpoint every 10 minutes from 6 locations located in Amsterdam, Ashburn, Hong Kong, Johannesburg, Sao Paulo and Sydney. It's a good way to test our own product and improve it. Let's analyze the data from the past two weeks. Cloudflare workers Cloudflare Workers is a serverless platform by Cloudflare. It lets you build new applications using JavaScript/Typescript. You can deploy up to 100 worker scripts for free, running on more than 275 network locations. Latency metrics 100% UPTIME 0# FAILS 10,956# PINGS 182ms AVG 138ms P75 695ms P90 778ms P95 991ms P99 Cloudflare avg. latency between 04. Feb and 18. Feb 2024 aggregated in a 1h window. RegionTrendP75P95P99 πŸ‡³πŸ‡± ams60ms88ms169ms πŸ‡ΊπŸ‡Έ iad120ms139ms177ms πŸ‡­πŸ‡° hkg92ms123ms158ms πŸ‡ΏπŸ‡¦ jnb705ms748ms1110ms πŸ‡¦πŸ‡Ί syd60ms287ms310ms πŸ‡§πŸ‡· gru60ms219ms296ms Timing metrics RegionDNS (ms)Connection (ms)TLS Handshake (ms)TTFB (ms)Transfert (ms) AMS17217270 GRU38213280 HKG19213290 IAD24114300 JNB1231681821850 SYD51111250 I can notice that Johannesburg's latency is about ten times higher than that of the other monitors. From the Cloudflare request I can get the location of the workers that handle the request, with Cf-ray in the headers response. Checker regionWorkers regionnumber of request HKGHKG1831 SYDSYD1831 AMSAMS1831 IADIAD1831 GRUGRU1791 GRUGIG40 JNBAMS741 JNBMUC4 JNBHKG5 JNBSIN6 JNBNRT8 JNBEWR10 JNBCDG82 JNBFRA276 JNBLHR699 JNBAMS741 I can see all the request from JNB is never routed to a nearby data-center. Apart from the strange routing error in Johannesburg, Cloudflare workers are fast worldwide. I have not experienced any cold start issues. Fly.io Fly.io simplifies deploying and running server-side applications globally. Developers can deploy their applications near users worldwide for low latency and high performance. It uses a lightweight Firecracker VM to easily deploy Docker images. Latency metrics 100% UPTIME 0# FAILS 10,952# PINGS 1,471ms AVG 1,514ms P75 1,555ms P90 1,626ms P95 2,547ms P99 Fly avg. latency between 04. Feb and 18. Feb 2024 aggregated in a 1h window. RegionTrendP75P95P99 πŸ‡³πŸ‡± ams1562ms1606ms1654ms πŸ‡ΊπŸ‡Έ iad1572ms1627ms1716ms πŸ‡­πŸ‡° hkg1556ms1624ms1975ms πŸ‡ΏπŸ‡¦ jnb1530ms1591ms1689ms πŸ‡¦πŸ‡Ί syd1514ms2560ms2641ms πŸ‡§πŸ‡· gru1510ms1567ms1878ms Timing metrics RegionDNS (ms)Connection (ms)TLS Handshake (ms)TTFB (ms)Transfert (ms) AMS61814690 GRU50414310 HKG40514730 IAD30514700 JNB240514230 SYD30314890 The DNS is fast, our checker is attempting to connect to a region in the same data center, but our machine's cold start is slowing us down, leading to the high TTFB. Here’s our config for Fly.io: app = 'statuscode' primary_region = 'ams' [build] dockerfile = "./Dockerfile" [http_service] internal_port = 3000 force_https = true auto_stop_machines = true auto_start_machines = true min_machines_running = 0 processes = ['app'] [[vm]] cpu_kind = 'shared' cpus = 1 memory_mb = 256 The primary region of our server is Amsterdam, and the fly instances is getting paused after a period of inactivity. The machine starts slowly, as indicated by the logs showing a start time of 1.513643778s. 2024-02-14T11:24:16.107 proxy[286560ea703108] ams [info] Starting machine 2024-02-14T11:24:16.322 app[286560ea703108] ams [info] [ 0.035736] PCI: Fatal: No config space access function found 2024-02-14T11:24:16.533 app[286560ea703108] ams [info] INFO Starting init (commit: bfa79be)... 2024-02-14T11:24:16.546 app[286560ea703108] ams [info] INFO Preparing to run: `/usr/local/bin/docker-entrypoint.sh bun start` as root 2024-02-14T11:24:16.558 app[286560ea703108] ams [info] INFO [fly api proxy] listening at /.fly/api 2024-02-14T11:24:16.565 app[286560ea703108] ams [info] 2024/02/14 11:24:16 listening on [fdaa:3:2ef:a7b:10c:3c9a:5b4:2]:22 (DNS: [fdaa::3]:53) 2024-02-14T11:24:16.611 app[286560ea703108] ams [info] $ bun src/index.ts 2024-02-14T11:24:16.618 runner[286560ea703108] ams [info] Machine started in 460ms 2024-02-14T11:24:17.621 proxy[286560ea703108] ams [info] machine started in 1.513643778s 2024-02-14T11:24:17.628 proxy[286560ea703108] ams [info] machine became reachable in 7.03669ms Openstatus Prod metrics If you update your fly.toml file to include the following, you can get the zero cold start and achieve a better latency. This is our data for our production server deploy on Fly.io. 100% UPTIME 0# FAILS 12,076# PINGS 61ms AVG 67ms P75 164ms P90 198ms P95 327ms P99 We use Fly.io in production, and the machine never sleeps, yielding much better results. Koyeb Koyeb is a developer-friendly serverless platform that allows for global app deployment without the need for operations, servers, or infrastructure management. Koyeb offers a free Starter plan that includes one Web Service, one Database service. The platform focuses on ease of deployment and scalability for developers Latency metrics 100% UPTIME 0# FAILS 10,955# PINGS 539ms AVG 738ms P75 881ms P90 1,013ms P95 1,525ms P99 Koyeb avg. latency between 04. Feb and 18. Feb 2024. RegionTrendP75P95P99 πŸ‡³πŸ‡± ams158ms225ms250ms πŸ‡ΊπŸ‡Έ iad173ms195ms213ms πŸ‡­πŸ‡° hkg372ms395ms416ms πŸ‡ΏπŸ‡¦ jnb1532ms1744ms1812ms πŸ‡¦πŸ‡Ί syd825ms869ms915ms πŸ‡§πŸ‡· gru705ms815ms989ms Timing metrics RegionDNS (ms)Connection (ms)TLS Handshake (ms)TTFB (ms)Transfert (ms) AMS502171070 GRU13965754070 HKG482133210 IAD351121290 JNB2981117200 SYD971107110 The request headers show that none of our requests are cached. They contain cf-cache-status: dynamic. Cloudflare handles the Koyeb edge layer. https://www.koyeb.com/blog/building-a-multi-region-service-mesh-with-kuma-envoy-anycast-bgp-and-mtls Our requests follow this route: Cf workers -> koyeb Global load balancer -> koyeb backend Let's see where did we hit the cf workers Checker regionWorkers regionnumber of request AMSAMS1866 GRUGRU504 GRUIAD38 GRUMIA688 GRUEWR337 GRUCIG299 HKGHKG1866 IADIAD1866 JNBJNB1861 JNBAMS1 SYDSYD1866 Koyeb Global Load Balancer region we hit: Checker regionKoyeb Global Load Balancernumber of request AMSFRA11866 GRUWAS11866 HKGSIN11866 IADWAS11866 JNBPAR14 JNBSIN11864 JNBFRA11 JNBSIN11866 I have deployed our app in the Frankfurt data-center. Railway Railway is a cloud platform designed for building, shipping, and monitoring applications without the need for Platform Engineers. It simplifies the application development process by offering seamless deployment and monitoring capabilities. Latency metrics 99.991% UPTIME 1# FAILS 10,955# PINGS 381ms AVG 469ms P75 653ms P90 661ms P95 850ms P99 Railway avg. latency between 04. Feb and 18. Feb 2024 aggregated in a 1h window. RegionTrendP75P95P99 πŸ‡³πŸ‡± ams181ms295ms316ms πŸ‡ΊπŸ‡Έ iad79ms107ms131ms πŸ‡­πŸ‡° hkg348ms443ms467ms πŸ‡ΏπŸ‡¦ jnb660ms786ms893ms πŸ‡¦πŸ‡Ί syd532ms620ms728ms πŸ‡§πŸ‡· gru417ms468ms541ms Timing metrics RegionDNS (ms)Connection (ms)TLS Handshake (ms)TTFB (ms)Transfert (ms) AMS921181580 GRU141151271780 HKG845542250 IAD7214650 JNB181931783190 SYD211081052800 The headers don't provide any information. Railway is using Google Cloud Platform. It’s the only service that does not allow us to pick a specific region on the free plan. Our test app will be located to us-west1 Portland, Oregon. We can see that the latency is the lowest in IAD. By default our app did not scale down to 0. It was always running. We don't have any cold start. Render Render is a platform that simplifies deploying and scaling web applications and services. It offers features like automated SSL, automatic scaling, native support for popular frameworks, and one-click deployments from Git. The platform focuses on simplicity and developer productivity. Latency metrics 99.89% UPTIME 12# FAILS 10,946# PINGS 451ms AVG 447ms P75 591ms P90 707ms P95 902ms P99 Render avg. latency between 04. Feb and 18. Feb 2024 aggregated in a 1h window. RegionTrendP75P95P99 πŸ‡³πŸ‡± ams95ms127ms16675ms πŸ‡ΊπŸ‡Έ iad165ms343ms16552ms πŸ‡­πŸ‡° hkg384ms746ms16681ms πŸ‡ΏπŸ‡¦ jnb587ms730ms16295ms πŸ‡¦πŸ‡Ί syd433ms945ms16696ms πŸ‡§πŸ‡· gru370ms753ms15979ms Timing metrics RegionDNS (ms)Connection (ms)TLS Handshake (ms)TTFB (ms)Transfert (ms) AMS20271070 GRU61264070 HKG76263210 IAD15151290 JNB361611677200 SYD103147110 The headers don't provide any information. I have deployed our app in the Frankfurt data-center. According to the Render docs, the free tier will shut down the service after 15 minutes of inactivity. However, our app is being accessed by a monitor every 10 minutes. We should never scale down to 0. Render spins down a Free web service that goes 15 minutes without receiving inbound traffic. Render spins the service back up whenever it next receives a request to process. I think the failures are due to the cold start of our app. We have a default timeout of 30s and the render app takes up to 50s to start.We might have hit an inflection point between cold and warm. Conclusion Here are the results of our test: ProviderUptimeFails PingTotal PingsAVG latency (ms)P75 (ms)P90 (ms)P95 (ms)P99 (ms) CF Workers100010956182138690778 Fly.io10001095214711514 Koyeb1000109555367388811 Railway99.991110955381469653661 Render99.891210946451447591707 If you value low latency, Cloudflare Workers are the best option for fast global performance without cold start issues. They deploy your app worldwide efficiently. For multi-region deployment, check out Koyeb and Fly.io. For specific region deployment, Railway and Render are good choices. Choosing a cloud provider involves considering not just latency but also user experience and pricing. We use Fly.io in production and are satisfied with it. Vercel I haven't included Vercel in this test. But we have a blog post comparing Vercel Serverless vs Edge vs Serverless. Want the same measurement for your own endpoint? Run it through the website speed test β€” 28 regions with the per-phase timing breakdown, and no account needed. If you want to monitor your API or website, create an account on openstatus. Frequently asked questions Which cloud provider has the lowest latency? In our benchmark, Cloudflare Workers had the lowest average latency of the providers left on their default configuration: 182ms across 6 global regions, with a P75 of 138ms. Fly.io was faster still when kept warm β€” 61ms with min_machines_running=1 β€” but averaged 1,471ms once cold starts were allowed. Does Fly.io have cold start issues? Yes. With auto_stop_machines enabled and min_machines_running=0, Fly.io averaged 1,471ms due to cold starts (~1.5s machine boot time). Setting min_machines_running=1 eliminates cold starts and brings the average down to 61ms. How does Cloudflare Workers latency compare to Railway and Render? Cloudflare Workers averaged 182ms with 100% uptime. Railway averaged 381ms with 99.991% uptime (1 failure). Render averaged 451ms with 99.89% uptime (12 failures). Cloudflare Workers deploy globally to 275+ locations, while Railway and Render run from a single region. Which cloud provider had the most downtime in the benchmark? Render had the most failures with 12 failed checks and 99.89% uptime over 2 weeks. Railway had 1 failure (99.991% uptime). Cloudflare Workers, Fly.io, and Koyeb all had 0 failures and 100% uptime. ## Comments **freeatnet.eth**: What struck me as odd here is how slow everything (apart from Cloudflare) is. I remember striving for a <=200ms P90 latency on API responses while building a large-scale platform about a decade ago; however, it now seems like that would get trumped by boot times of these platforms. Have we gone backwards in terms of speed? Am I misremembering something?