The Morning the Checkout Button Turned into a Loading Spinner

The Morning the Checkout Button Turned into a Loading Spinner

The first time I noticed something was off, I was standing in a hawker center in Toa Payoh, sweating through my shirt, waiting for a nasi lemak that cost $3.50. It was a Tuesday in late June, maybe 11:30 in the morning, and the humidity was doing that thing where it doesn’t just sit on you but wraps around every breath. I was running a small e-commerce store selling custom-printed t-shirts—nothing fancy, just designs a friend of mine drew on napkins during lunch breaks—and I’d been checking orders on my phone between bites of fried chicken wing.

The order came through at 11:34 AM. From a customer in Bedok. A simple single-color print, nothing complicated. But when I hit refresh on the admin panel, the page hung for a good four seconds before anything happened. I watched the little loading spinner spin, and I remember thinking: that’s not right. The server was in Singapore, I was in Singapore, the customer was in Singapore. What was taking so long?

I didn’t think much of it then. I finished my lunch, walked back to the MRT, and went home. But over the next few weeks, I started noticing a pattern. Orders from customers in the eastern part of Singapore—Bedok, Tampines, Pasir Ris—seemed to take just a little longer to complete. And when I looked at the abandoned cart rate in my analytics, it was sitting at 78%. That’s not a typo. Seventy-eight percent of people who added a shirt to their cart never finished checking out.

At first I blamed the design of the site. I redid the checkout flow twice, rearranged buttons, simplified the form. Nothing budged that number. Then I moved the hosting from a shared plan to a VPS with a local provider—$49 a month, Singapore data center. That helped a little. The admin panel felt snappier. But the abandoned cart rate dropped maybe two points, to 76%. Still a disaster.

That’s when a friend who runs a small electronics shop in Sim Lim Square told me something I hadn’t considered. He said, “Your server’s in Singapore. But are all of your images and scripts coming from Singapore?” I didn’t even know how to check. He laughed, not meanly, and said, “You’d be surprised how many local stores don’t realize their checkout form is talking to a server in Oregon every time someone clicks ‘Pay Now.'”

What I Actually Found When I Dug Into the Network Traffic

I’m not a network engineer. I’m a guy who draws t-shirts and hopes people like them enough to pay $25 for one. But I learned how to open the browser’s developer tools, and once I did, I saw something that made me close the laptop and stare at the wall for a minute.

Every time someone visited my store, the page was pulling in JavaScript libraries from a CDN that had its primary node in California. Not Singapore. California. The images—product photos I’d taken myself, compressed and resized to under 200KB each—were being served from the same CDN, which routed them through a server in Tokyo that then hit a second node in Los Angeles before coming back to Singapore. Round-trip latency for a single 150KB image was averaging 280 milliseconds. That doesn’t sound like much, right? It’s less than a third of a second. But when you have 12 images on a product page, two custom fonts loading from Google Fonts, a payment gateway that pings a server in the US for address verification, and the checkout script itself—you’re looking at somewhere between 4 and 6 seconds of cumulative loading time before the customer can even start filling in their shipping details.

I tested it myself. I opened the store on my phone, connected to my home Wi-Fi in Singapore, and timed it. From clicking the link on Instagram to the page being fully interactive: 8.7 seconds. I did it again, this time on 4G data: 11.2 seconds. And I was the store owner. I wasn’t even shopping. I was just trying to load the page.

There’s a number I kept coming back to. Every 100 milliseconds of extra load time can reduce conversion rates by about 1%—that’s a well-studied figure, not a guess. But what I think gets lost in those numbers is what it feels like from the buyer’s side. You’re on your phone, maybe standing in a queue at the kopitiam, and you see a t-shirt you like. You tap the link. The screen starts loading. You wait. The checkout button appears but the page is still doing something—it has that jittery, half-rendered look where text boxes are empty and the layout shifts. You wait another two seconds. Then the free shipping calculator kicks in and takes three more seconds. By the time the page is ready, the queue has moved, the person behind you is waiting, and you’ve already thought: I’ll come back to this later. Except you never do.

I went through my abandoned cart records for the past three months. Out of 647 abandoned carts, the average time spent on the checkout page before leaving was 14 seconds. Fourteen seconds. That’s not enough time to even type your address on a phone. So these people weren’t looking at the price and changing their minds. They were never even shown the option to pay.

The Afternoon I Drove Across the Island to Test Something Stupid

I wanted to understand what was actually happening, not just read about it. So one Saturday afternoon in July, I took my laptop and my phone and I went to four different places across Singapore—Changi Airport’s Terminal 3, the CBD near Raffles Place, a residential area in Jurong West, and a coffee shop in Katong. At each spot, I connected to the internet and loaded my store, timing every single request with the developer tools open.

It was a hot day, maybe 33 degrees. At Changi, I sat near the waterfall in Jewel, which is ridiculous because it’s packed with tourists and families, but the Wi-Fi there is surprisingly fast—I tested it at 175 Mbps download. My store loaded in 6.2 seconds from that connection. Six point two seconds, on a 175 Mbps connection. That’s when I knew the problem wasn’t internet speed. It was distance.

At the Katong coffee shop, I ordered an iced kopi and sat down to run the test again. The Wi-Fi there was slower—maybe 40 Mbps—but the store actually loaded slightly faster: 5.8 seconds. I checked the network trace. Because the coffee shop’s connection had a different routing path, some assets were being pulled from a CDN edge that happened to be closer. But even then, the payment gateway’s verification call was still going to a server in Virginia. That single call was taking 1.4 seconds, on average, to make the round trip. One point four seconds, every time, just to check if a credit card number looked valid.

I sat there and watched the trace log scroll by. Each line was a request, and each line had a time column. The longest ones were the ones that left Singapore and came back. And every time a request left Singapore, the page stopped rendering. The button went grey. The spinner appeared. The customer waited.

It was a Wednesday a week later that I got the decisive data point. I’d been running a Facebook ad campaign for a new design—a Merlion eating a durian, which I thought was funny—and it had cost me about $200 over four days. The ad got 4,100 clicks. Three people completed a purchase. Three out of four thousand one hundred. That’s a conversion rate of 0.07%. The industry average for apparel e-commerce is around 1.5%. I was off by a factor of twenty.

I’m not a numbers guy, but even I can do that math. If the conversion rate had been even 1%, I’d have made about 40 sales from that campaign. At $25 per shirt, that’s $1,000 in revenue, minus the ad spend and the cost of goods. Instead, I made about $75. I lost somewhere around $800 in potential revenue because the checkout page couldn’t load fast enough for 4,097 people.

The Two Days I Spent Switching to a Local CDN and What Changed

I called a hosting company I’d heard about—located in Singapore, specifically built for local SMEs. The guy who answered the phone immediately knew what I was describing. He didn’t need me to explain latency or CDN routing. He laughed and said, “Let me guess: your checkout calls a US server for fraud detection, and your images are on a global CDN that didn’t route you to a local edge.” I told him yes to both, and he said, “I see this every week. Fix that and you’ll probably see your conversion rate double overnight.”

He was exaggerating, but not by much. The switch itself took about two days. I moved my entire asset library to a Singapore-based CDN that had edge nodes not just in Singapore but in Malaysia, Indonesia, and Thailand. I changed the payment gateway to one that had a local processing server. I hosted my fonts on the same CDN instead of calling Google’s servers. The total cost increase: $12 a month more than I’d been paying for the US CDN. Twelve dollars a month. A single t-shirt sale basically covered it.

I ran the same tests I’d done in Changi and Katong. The first one, from my home Wi-Fi: the store loaded in 1.4 seconds. From 4G on the MRT: 1.8 seconds. From a coffee shop in Tiong Bahru: 1.5 seconds. The payment gateway call that used to take 1.4 seconds now took 200 milliseconds. Everything was local. The route from my server to the customer’s phone never left the island.

I should pause here and say that I didn’t fix everything. Some things are just out of your control—the customer’s own connection quality, the traffic at their ISP’s exchange point, the fact that people abandon carts for reasons that have nothing to do with speed. But the numbers shifted immediately. Within two weeks, the abandoned cart rate dropped from 76% to 54%. That’s a 22 percentage point improvement. In real terms: where I used to lose 19 out of 20 people who clicked “Add to Cart,” I was now keeping about 1 in 2. The revenue from that Facebook ad campaign I’d run before? I ran the same ad again, same budget, same audience targeting. This time, 31 people bought something. That’s a conversion rate of 0.76%, still below the national average but ten times better than it had been two weeks earlier.

The money math: $200 in ads, 4,200 clicks, 31 sales at $25 each = $775 in revenue. Minus ad spend and costs, I cleared maybe $450 that week. From the same $200 ad budget I’d lost $800 worth of potential sales a month earlier. The whole thing—the switch, the testing, the phone call—cost me probably 15 hours of work and $12 a month. The ROI on that 15 hours, in the first month alone, was something like 30-to-1.

What I Learned About Local Infrastructure That I Wish I’d Known Earlier

I didn’t understand, before this, how much of the internet’s speed is determined by geography. I thought “the cloud” was a vague everywhere-at-once thing. It’s not. The cloud is just someone else’s computer in a specific building on a specific street in a specific country. If that building is in California and your customer is in Jurong West, every packet of data has to cross an ocean, pass through customs at the undersea cable landing station, get processed by a router in a different city, and then make its way to your customer’s phone. That takes time. It just does.

What surprised me most was the payment gateway. I assumed that the “local” payment gateway I was using before—the one that had a Singapore address on their website and a .sg domain—was actually processing payments in Singapore. It wasn’t. The physical server that handled the transaction was in Virginia. The Singapore office was probably just sales and support. The actual data path was: my customer’s phone to a Singapore ISP, across the Pacific to a US west coast data center, then to Virginia, then back across the Pacific to Singapore, then back to my store’s server. That’s 20,000 miles of travel for a single payment verification. At the speed of light—which is the fastest data can go—that’s about 100 milliseconds of transmission time just for the light to move, plus switching latency, queueing delays, and processing at each end. The real-world time was ten times that.

I think about this now when I see people talk about “cloud” infrastructure. It’s a convenient abstraction, but it hides real physical constraints. The distance between two data centers matters. The landing stations for undersea cables matter. The fact that Singapore’s main cable to the US goes through Guam before reaching California—that adds latency. A local CDN, with an edge node literally in the same building as the Singapore internet exchange, can deliver content in a fraction of the time because the data never leaves the building.

The Saturday I Saw the Difference in Real Time

A friend of mine runs a small bakery in Tampines. She sells pandan cakes online, mostly to local customers. I told her about the CDN switch and she was skeptical—her store was on Shopify, she said, and Shopify handles all that for you. I said not necessarily. We looked at her store’s performance together on a Saturday morning while she was pulling a tray of kaya rolls out of the oven. She logged into the admin panel, loaded the store on her phone, and we timed it. 5.2 seconds. She didn’t believe it until I showed her the network trace. The product images were on Shopify’s own CDN, which uses a global provider with no guarantee of local routing. Her payment gateway, like mine, was processing in the US. She wasn’t on a shared plan—she was paying $79 a month for the mid-tier Shopify plan, plus transaction fees.

She switched to a local CDN for her images and scripts—you can do that with Shopify, it’s just a setting change—and within a day, her store was loading in 1.9 seconds. She told me later that week that her conversion rate had gone from 1.1% to 2.8%. She said, “I thought it was the product photos. I spent $300 on a photographer. It was never the photos.”

We sat there eating kaya rolls and I thought about the $800 I’d lost from that single ad campaign, and the thousands more over the previous six months that I’d just accepted as “business costs.” I had attributed the low sales to bad products, bad marketing, bad luck. It was none of those things. It was a technical problem with a $12-a-month solution.

I’ve been running the store for almost a year now. Revenue is up about 40% from where it was before the switch, and I can’t attribute all of that to the CDN—I’ve also gotten better at designing shirts and running ads. But the timing of the improvement was immediate. It was like turning a valve. The customers who had been bouncing off the site because it was slow suddenly started staying, and finishing their purchases, and coming back for more. The abandoned cart rate still sits around 52%—some things you can’t fix—but that’s down from 78%. And every time I see the analytics dashboard with that number, I remember the loading spinner at the hawker center, and the iced kopi at Katong.

I still use that same CDN. I still check the network trace whenever something feels slow. And I still think about those 4,097 people who clicked on an ad and saw a spinner instead of a t-shirt. There are 31 people who actually got to buy the Merlion-eating-durian shirt. That’s not nothing.

📷 Photos: CHUTTERSNAP (Unsplash), Claudio Schwarz (Unsplash)

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *