Launch a website with 1M users within 2 days with $0 cost
All the magic began on 26th Jan, 2020. The original idea started with a simple question. “Why don’t we build a website that gathers ALL information about the coronavirus in Hong Kong?” together with a list of bullet points of how to achieve an MVP. Shortly after, a telegram group was formed and some of us from the group spent their Chinese New Year holiday with the stacks of Gatsby and Kintohub, at 11 pm, on 28th Jan 2020 our site https://wars.vote4.hk/en went online… Within 24 hours we reached almost 1M users (983k to be exact) and our stack didn’t crash and was completely free!!!
Building Scale Without Thinking Scale
We expected a soft launch with minimal traffic. Which really means, we didn’t think too much about scale aside from exploring new technologies and creating more awareness for the people of Hong Kong. The first version website itself was designed to be simple:
- Show Accident and Emergency wait times in HK (Thanks to the Hospital Authority for the csv)
- Show a list of dubious pharmacies exploiting people with marked-up prices (Thanks to this form it was easy)
- Provide tips for hygiene
- Display confirmed cases and figures for Coronavirus (Thanks to the CHP for this pdf) (P.S. they released an API in csv format in recent days)
- Some automations for the rapid development
After knowing where the source of information was going to come from, we then broke down our project requirements into the following:
- Using Google spreadsheet as a simple CMS to allow our helpers putting some articles about tips for hygiene
- A scheduled program that gathers the Accident & Emergency wait times and put it to google form
- A scheduled program that gathers the PDF and put it to google form
- A scheduled program that triggers new builds every 10 minutes
- A simple continuous deployment (CD) setting that deploys the project with the latest changes upon a successful build
Why Gatsby & How We Used It?
Gatsby is a free and open-source framework based on React that helps developers build static websites
In order to survive high traffic at a low cost, building a static website is the best solution. Gatsby is an awesome tool for that. Using Gatsby we downloaded our data in CSV (this spreadsheet is deprecated tho since we decided to break it into different sheets) format, and using this Gatsby API we can easily turn the data into Graphql, in which we can use it within our project. With this we can put our focus on the UI without having to spend too much time around data fetching.
Since our requirements aren’t realtime, we could generate a single result that shows very recent information that all users can view. This can be done by fetching data at the time you build which may sound foreign to people who have not used Gatsby or static website generators. In order to do this, we needed to have a cronjob scheduled to build every 10 minutes. This job would get the latest data, regenerate the static website and push it to the users so they can see the newly updated results.
Gatsby also provides many plugins that made it easy to bootstrap our project which vastly reduced our development time. To name a few:
- gatsby-plugin-sitemap for sitemap generation
- gatsby-plugin-google-analytics for google analytics
- gatsby-plugin-robots-txt for generating robots.txt
Why Kintohub & How We Used It?
KintoHub makes it simple to deploy and configure web apps, backend services, cron jobs and databases together in one or many environments.
Even with my experience on Kubernetes and different CI/CD tools, I find myself spending too much time configuring the tools for new projects when I have little time to invest in them. Even though you may have some sort of templates that fit your needs from a previous project, it rarely means you can easily reuse them to lower development time. KintoHub helps out a lot here.
You can deploy your full stack from frontend web apps, backend APIs, message queues or even databases of your choice. On Kintohub there is a free tier allowing you to deploy any service up to a total of 512MB memory.
To deploy our project, we used KintoHub to link our github repos, configured various settings (e.g. build arguments or environment variables), and BOOM — the whole stack was up and live!
There are several advanced features on Kintohub that help you easily scale
- Environment Promotion (Allow us to simply promote our `dev` environment to `production` environment)
- Rolling Deployment (With automated health check to ensures no downtime when deploying a new release)
- Tagged Builds (Allows us to easily rollback to previous releases)
- High Availability (Multi-AZ, Multi-Instance redundancy)
- Let’s Encrypt by default (https/ssl certificates for our custom domain name)
Tagged builds are especially useful for us. Since we do not have enough time to set up unit tests and e2e tests (which we should🧐), sometimes we may release an unstable version (which we shouldn’t 🧐). But luckily we are able to tag our builds on the platform. We tag our builds once we try to deploy any breaking changes, and if something really bad happens, we can still rollback to the previous stable version easily within seconds.
Doing a time-attack project is challenging. But with the right stack you can do the thing without hesitation. Explore the modern software era and pick your stack wisely!
We are so proud that we spent only two days building the website. It could (at the moment) survive 25000+ concurrent users, with SEO, a simple CMS using google spreadsheet, a fully automated CI/CD pipeline, running with multiple cronjobs & services completely free! You could not do this 10 years ago when I started my software career. The software world has truly evolved into abstracting powerful technologies into simple & intuitive tools to help millions of people on the WWW.
Here are some links that will hopefully help others do the same:
PS. Full disclosure, my day job is hammering away at engineering Kintohub by day and hacking away side projects at night. Kintohub aims to be a powerful simplistic way to deploy anything into the cloud (and soon, to any cloud of your choice 😉)