05 Feb

Cloudflare issues in South Korea

Over the last months I have tried Cloudflare’s service for one of my websites. Cloudflare is a “Content Delivery Network” or CDN in short. At first I was very excited about it and championed it’s usage to the other executives at our business because of all the advantages a CDN is supposed to give you. After 3 months of using it with their Professional plan (200$ per month) we decided to turn it off as it hasn’t delivered the benefits we would have expected.

The setup

  • The site is hosted on a single DigitalOcean droplet.
  • It is forcing users to use HTTPS. This is done via a .htaccess redirect
  • The homepage has about 60 resources
  • Total file sizeis about 1.2 MB

The website didn’t experience grave performance problems, but it wasn’t exactly fast either. Additionally, we were serving high quality images to our visitors that sometimes took a long time to load.

Speed differences with Cloudflare

From my location in Cambodia, the time for loading the site went down significantly to around one second to load every piece of content.

But for some reasons, the people in South Korea kept reporting to me that the website sometimes loads very slow or even can’t load some images. A few weeks later I was back in South Korea and could expierience all the problems by myself. Sometimes the pages were taking 5-10 seconds to load for no obvious reasons.

In one case I checked together with a customer through skype and looked at his screen. The website was so slow, it would take the 30 seconds before the homepage appeared. And then another full minute until the CSS and most of the images were loaded so that it actually looked similar to what it should look like.

Over the next weeks I could identify three separate problems.

Problem 1: The “Pro Plan” doesn’t work in South Korea

I contacted cloudflare about this issue and got an answer after some back and forth.

Unfortunately I have bad news for you. Being on the Pro plan, almost all KR traffic will be routed through LAX, so you will see increased latency for those requests.

We discuss this here: https://blog.cloudflare.com/bandwidth-costs-around-the-world/

and include a link to ask KT to peer with us in Seoul: http://www.kt.com/eng/etc/contact.jsp

Summary: Traffic in South Korea is much more expensive than in any other region. That’s why Cloudflare reroutes all traffic from the Free and Pro plans through Los Angeles, USA. This should -in the long run- increase costs for Korean ISPs and pressure them and the government to play ball with international companies. To allow peering and speed up the internet around the world.

If you want to have your content be served from their node in Incheon, South Korea, you will need to upgrade to the Business plan which costs 200$ instead of 20$.


Problem 2: Korea Telecom has routing problems

What I found when running some networking tools on different connections, was this.


On the left side is the result when pinging our webserver directly. On the right side is the result when pinging cloudflares server. I was using a regular home wifi and a LG U+ connection.

After some more back and forth with Cloudflare’s support team, I was told that this is an issue of Korea Telecom and therefore I should talk with them. (I did not talk to them)

Problem 3: Slow TTFB

We opted to upgrade to their Business Plan. At first it looked like it was showing some improvements. But after a while, I can now say it didn’t speed up our website loading times overall. This is most likely caused by Korean ISP’s routing problems, but nevertheless it isn’t helping us so that’s why I decided to stop using cloudflare at all for now. And the increased latency for AJAX calls was becoming a serious issue for us.

Here I’ll break down the different parts of the connection that take place when a page loads.

  1. DNS resolution and connection time
    This was much faster than before. In exact numbers, this metric went down from 150ms to about 20ms.
  2. Download Time
    The time it took for the user to download the HTML page stayed roughly the same. It always stayed between 30ms to 60ms. The larger content such as images started loading significantly faster. A 500 kb image would load in 40ms instead of a very variable 80ms to 400ms.
  3. Server Response Time (TTFB)
    This one went UP from about 250ms to a whopping 900ms.

Here are the metrics collected by Google Analytics. While it might not be the best tool to monitor the site speed, it’s the only one I have for now and it confirms that I’m not the only one with these results.


Does the Server Response time (TTFB) matter?

Cloudflare says on an often shared post that you should stop worrying about TTFB.


Sure, it’s not always the most important thing. If your images are takig 3 seconds to download, you have bigger problems than 300ms connection times. But saying it is meaningless is just wrong too.

Our website has a shopping cart feature that is using AJAX. So whenever a user clicks on the “Add to Cart” button we are doing two requests.

  1. Send a request to the server that adds the item to the shopping cart
  2. Reload the basket from the server and display it to the user

These two requests have to happen in sequence, so their times add up. Without cloudflare, it takes around 250ms to send the first request and 250ms to reload the basket. That results in a 500ms time to complete the user action. With cloudflare’s increased TTFB each request takes 900ms to complete. So the total time required to add an item to the cart will take 1.8 seconds.

So what’s the solution?

I started optimizing things one by one instead of using the Cloudflare umbrealla solution.

  1. Cloudflare is now disabled
  2. Now all our user uploaded images are uploaded to an Amazon S3 bucket and then served through their Cloudfront service.
  3. I have yet to find a good solution for our static content like application specific images, Javascript and Stylesheets.

Uploaded images are now served faster than ever before. We do have a slower download time for application specific static content. But once those are cached on the customer’s browser, everything behaves much quicker.

18 Jan

Setting up Cloudflare for a DigitalOcean droplet

This is a quick recollection of the steps it took to set up Cloudflare for a website that is using Apache on a DigitalOcean Droplet.

What is a CDN and why do I need one?

If you’ve never heard of a CDN or have but are not sure what it is, here is a small explanation. A CDN is a global network of servers that helps distribute your website content to different places across the globe. Most websites start off on a single server. If you set up your own website, you will usually start with a hosting provider and a domain registrar. At the domain registrar you enter the address  of the hosting provider’s DNS servers and/or IP addresses. Sometimes you can have both services from a single company. This is so that when somebody types www.yourwebsite.com the request is correctly routed to your webserver.

In this setup, every visitor to your website will be served by your single server that you rented from your hosting provider. If your hosting provider is in Texas, and your website visitor is in Tokyo, Japan, it will naturally create a little bit of a delay in the communication that happens behind the scenes. The bigger the website you’re serving, the longer it will take to load everything between Texas and Tokyo. Now if you wanted to speed up the loading times for your Japanese visitors, you could set up another server in or close to Japan. But that would be a lot of work and it wouldn’t help your other visitors who might be in South Africa or in Norway.

A Content Distribution network will sit between your hosting provider and your visitors. Because it is a Network, it’s servers are distributed and it will be able to serve your content to much more places, and much faster than you could by setting up a server in every country. Here is an image that I took from Cloudflare’s website and it explains the setup very well I think.


How does the setup process work?

If you’re running a simple website with some information and pictures on it that are not using a secured connection, it’s fairly easy.

  1. Create a cloudflare account
  2. Get your new nameservers from cloudflare
  3. Enter your nameservers in your domain registrar‘s administration panel.
  4. Log in to cloudflare and set up your domains and subdomains
  5. Be sure you recreated all the DNS entries from your old domain registrar. For example, if you are using Google Apps for work, you also have to set up your MX records in your cloudflare account.

What if I use a secure connection over HTTPS?

This was the case for the site I was moving. Cloudflare has a couple of options in their management. They are mostly concerning what certificate to use (cloudflare vs. your own) and what part of the connection should be encrypted with with certificate. Because there are two parts in the connection.


Cloudflare's SSL options

Cloudflare’s SSL options

IMPORTANT: If you are using the option Full or Full (strict), cloudflare will require some time to issue a new certificate. I’m not 100% sure what happens behind the scenes, but in our case for the first 24 hours, our website was showing the scary “Your connection is not private” message in all browsers. During that time, the SSL settings in the cloudflare management screen were saying “Issuing new certificate” or something similar. It was eventually resolved automatically, but this is a very important factor if you’re migrating a live website.

21 Dec

Mixing Basic Authentication and custom API Authentication

Today I ran into a problem that cost me about two hours, so I thought I want to share this if there is someone googling for the same problem.

The situation

I have a self built admin form that uses a RESTful api to retrieve and store data. The endpoint would be something like http://www.myserver.com/api/book and it’s listening to the obvious methods GET, POST, PUT, DELETE. The form was using the  jQuery.ajax() method to send requests.

This was developed locally and it worked without a problem, as it should.

The problem

When I deployed this to my test server at http://test.myserver.com/api/book something was not working right. Whenever I tried to save a new book, it would show this little window saying “Authentication Required”.



The test server is protected by a simple Basic .htaccess authentication. So this was something I’m used to. Unfortunately, entering the username and password didn’t work. It kept asking for the authentication until I clicked cancel. Then it would show that I got a 401 status response (Unauthorized)

Google to the rescue. The things I googled for were:

  • jquery ajax with credentials
  • jquery http post request basic authentication
  • jquery post keeps asking for credentials

Nobody seemed to have the same problem. Some posts on Stackoverflow said you could set an option like this:

That made the Authentication window disappear. So Basic Authentication  seemed to work now. What I found then in Chrome’s Network tab was that the POST request was now returning a response with a status of 403 (Forbidden).

The reason why it sent that, was because my API methods to delete, update or create things require authentication. This is sent as an access token as you can see in the code above.

The cause of the problem

When using basic authentication, the client has to send an HTTP header like this:

But my code was already setting a header for my own API’s authorization mechanism. And that header was set by this line.

Now we have located the problem. I am setting the Authentication header two times. Once for the API and once for the server’s basie http authentication.

The solution

According to some more googling and stackoverflow, it is not allowed to have two authentication headers in the same request. I found somebody else’s answer on StackOverflow that actually had the same problem: http://stackoverflow.com/a/32350368/1838774

Luckily my API was still in an early development phase and not actively used by other applications. This means that I could take the easy route and change my API’s authentication mechanism to look for a custom header instead. I went for a specific one that hopefully nobody else is using.

So my ajax code now looks like this.


11 Oct

How to localize a website for South Korea

Like any culture, South Korea has its own challenges and pitfalls that you should keep in mind when you have to localize a website for the Korean market. This post is about the unique challenges I have encountered with my projects. I am aware that there are probably more things that are commonly overlooked.


Korean Names are short

The normal lenght of Korean names is 1 character for the last name, and 2 characters for the first name. There are some exceptions, like last names with more than one characters. But keep that in mind when you validate your forms.

Like other asian countries, they also generally write the Last name before the first name. So a typical name Lee Kyung-Su in a standard bootstrap form will look like this:


Keep that in mind when you design your signup, checkout or login forms.


Addresses are written upside down

Addresses in the west are usually written from small to large entity. In Korea, the order of these is inverted. Here is a comparison.

Street and Number
City and Postal Code
Street and Number
Postal Code


How do you talk to your users?

In everyday English you only use one form of politeness. “You”. The Korean language has a whole bunch of them divided into levels of politeness and formality. And which form you use to address your customers or users makes a huge difference. The common form to write is the Haeyo-che form also known to English speakers as the polite form. Refrain from using the impolite form, as users will definitely feel offended by that.

Another thing worth mentioning is that you can’t just address your users in the same way you would in English. If your app or website greets the user after login with “Hi John”, that could be a bad idea in Korea as calling someone by his/her first name is much less common and only done if the speakers are either very close, or if the speaker is talking to a child.


 Date and Time

The common formats of how dates are written in Korea are:

  • 2015.9.13
  • 2015/09/13
  • 2015년 9월 13일



The official currency in South Korea is the Korean Won. It uses the international abbreviation of KRW or the currency symbol ₩. Prices are written in the format #,###. Often the name of the currency “Won” is written out in Hangul as 원 to show prices. So if your website is in English and Korean, it would be a good idea to display prices a little different. For example like this:


One important thing to know is that the Korean language does not use blocks of three to separate numbers. They do have a word for thousand (cheon), but they also have a word for ten-thousand (man). 100,000 in english would be called one-hundred thousand. In Korea on the other hand it would be called ten-man. After that follows one-hundred man, one-thousand man and then one “eok”.

1,000 One thousand 1000 Cheon
10,000 Ten thousand 1,0000 Man
100,000 One hundred thousand 10,0000 Ship (ten) man
1,000,000 One million 100,0000 Baek (hundred) man
10,000,000 Ten million 1000,0000 Cheon (thousand) man
100,000,000 One hundred million 1,0000,0000 Eok


If I find more, I will keep posting things here. Or if you happen to know about more Korean localization topics I’m happy to include them here.

21 Jan

WordPress, the good parts

Ever since I started using WordPress as something different than just a blogging platform, there was a clear upside and a downside to it.

What I love about WordPress

It’s amazingly easy to manage your content. Mainly for two reasons.

  1. Firstly, the backend has proven itself over and over again. It can be learned by anyone in a few hours. Which makes it almost unnecessary to explain to even inexperienced users.
  2. And secondly, custom post types and taxonomies are a concept that is a bit hard to grasp in the beginning. But it allows for a lot of flexibility. Additionally to Posts and Pages, WordPress can be used to manage a lot more things. Products? Events? Movies? … Pets? You name it.

What I hate like a lot less about WordPress

  1. The template system and querying data is a mess. There is this magical thing called “The Loop” that sets up something like a context for your template. Then you can get things like “the_content()” which automatically prints it out to the frontend. This probably makes the learning curve a little bit less steep for newcomers. But for people who are used to work with MVC patterns and like the separation of data, logic and content, it is a nightmare.
  2. There’s no real business logic layer. If you want to build application like features into your website you have the choice of adding it either to your template, or putting it in a plugin.
  3. You want to add automatic unit tests for the code that you wrote for your application? Sorry, we don’t do that here.

Separating one from the other

With the last releases, WordPress has been adding a feature to it’s core that has transformed web development in the last decade or so. It now finally has it’s own API. Using this piece of technology, you can finally get the data out of WordPress and display it in any application you want. A mobile app, another website, anything with access to the internet can now show what you are managing in side your WordPress website.

This allowed the people at Bocoup to build an amazing project. They had to add content management to an existing web application. But instead of trying to create their own, they looked to the old but reliable and proven WordPress backend. Using the API they were then able to manage their content inside WordPress, but display it on their custom built web application. They even created an npm package to call WordPress API from node applications under https://github.com/kadamwhite/wordpress-rest-api. And it’s as easy as this:



I think this is the biggest step forward that WordPress has made in the recent years. The code architecture might still not be to everyone’s taste. The template engine is still the same. But the API is breaking up that monolithic piece of software that it was. Adding a lot of flexibility to it and ultimately paving the way for a brighter future. I am really excited to see what other applications for it are going to come out in the future. And I would love to build an application that makes full use of this.

Here is the whole presentation K. Adam White gave at Wordcamp San Francisco:

16 Dec

Sitefinity – The unboxing experience

This blog post is about my experience trying Sitefinity CMS for the first time. It’s always good to take a look at other applications and how they do things differently. Today I came across an advertisement for this particular CMS. Being able to work with and extend an existing CMS in C# and with all those cool features like EF, MVC sounded like an awesome new thing to learn and almost exactly aimed at me. I’ll try to document the most important impressions and steps while trying it out. A bit like an unboxing video on youtube if you like.


Sitefinity facebook ad


Fist I signed up for a free one month trial and downloaded the essentials. The installation of the SDK and files ran smooth even though the download of 400 MB took a while with my Cambodian connection. Sitefinity is conveniently installing a demo application called “Default”.



Initialization Error.


When navigating to the application, the browser tells me that setup is running some initialization and then suddenly: 1 error(s).



At least there’s a clear error message. But because I’m lazy I will just try to setup another application and see if the problem still exists. So I go to the “Sitefinity Project Manager” and select “Create New Project”. From here the process is very easy. Just select a name and folder to create my new “GardenGnomeBlog”. After the project is created, I right click and select “Browse” which launches a browser and gets me to the setup screen. Nice.

Sitefinity Project Manager

Sitefinity Project Manager

Database Setup

Database Setup

I select Microsoft SQL Express Server and click continue. Next it shows me a familiar error screen with the message that I am not allowed to connect to this MySQL server.

MySql Error

Didn’t I just select that I want SQL Express Server?  The file path of this config says that the problem is located under c:\windows\Microsoft.Net\Framework64\v4something so it seems that this is just because of my machine configuration and not really Telerik’s fault. Aha, blamed Sitefinity too early. Apparently my machine.config has an entry for a sitemap provider called MySqlSiteMapProvider.  Not really sure how it ever got in there and I definitely didn’t put it in there on purpose. After commenting out that line in my machine.config, I’m trying again. This time I start the server, it says it is initializing again and shows some turning wheels but nothing ever happens from there. After 3 minutes I decide to scrap this installation and try again. So enter the name, choose the database type, add some login details and voilà, it worked.
Now I am presented with the kind of dashboard I was expecting.

Finally, Sitefinity runs and is ready for a test drive.

Here I conclude this first blog post about Sitefinity CMS after the installation was completed and I got a first project up and running. I’m curious what’s next and will definitely try out some features and maybe even try to develop my own module in the future.