Over the past few years, I’ve had to measure API and website load times across the world. To date, that’s meant doing multiple tests using tools like Pingdom's speed test or spinning up virtual machines, logging in, and executing scripts/using performance testing applications like JMeter to get the response times of applications. That’s a cumbersome process, with every new region requiring several manual steps.
That’s why I built Geofetcher. It’s a web application that allows you to get the load time for a website from 15+ locations in the world within seconds. Talk about a productivity gain!
You might think that this is a complex web application pinging many virtual machines in each region under the hood. It’s actually much simpler than that, much thanks to the Cloudflare developer platform (I'm biased, I work at Cloudflare, but Cloudflare Durable Objects are a truly powerful concept for "infinite on-demand globally distributed mini-servers"). Here’s how it’s built:
The first component is a Cloudflare Workers application. That application hosts the API that is responsible for coordinating a speed test, and the React application that provides the UI (using Workers Static Assets!). Since it’s deployed to Workers, the API and React app are hosted in each of Cloudflare’s edge locations, serving assets quickly and ready to coordinate a test.
The second component is a series of Durable Objects (the aforementioned "infinite on-demand globally distributed mini-servers"). These are periodically created using Durable Object's location hint feature (let durableObjectStub = OBJECT_NAMESPACE.get(id, { locationHint: "enam" });
). This ensures that many Durable Objects are created around the globe in various locations. And by routing our latency tests to each of these Durable Objects, we'll be able to coordinate our global latency test.
Third, a Workers KV store keeps a list of these Durable Objects and a D1 database keeps track of operations to ensure some limits are in place.
So putting it all together, this is the lifecycle of a website speed test:
- When you enter you test your website’s URL from the Geofetcher app, an API request is made to the Workers application.
- Upon receiving the API request, the Workers application reads a list of Durable Objects from Workers KV.
- The Workers application makes parallel RPC calls to each geo-distributed Durable Object.
- Upon receiving the RPC request, each Durable Object makes a simple fetch request to the website being tested, and measures the amount of time needed for the response to be returned.
- The Workers application returns the result of each Durable Objects instance to the React app.
- The React app displays the results and keeps a history of requests to show analytics over requests.
That’s it! What would have previously required spinning up virtual machines or containers in each region is easily done with a single command with Durable Objects. This is a neat simple tool that helps me test global response times for APIs and websites. It's been great to see the reception so far and see folks try it out with their own websites and APIs (and it's giving me ideas for future iterations 👀).