Scaling Asana.com
This post isn’t about the Asana app – it’s about Asana.com, our “content site” – the place where we sign up new users, market the app & ecosystem, publish help and other content, recruit new Asanas, and more. Ultimately, it is the place where we tell our story to the world.
When people think about web scalability, they often think about requests, servers, and load balancers. We use (and love) Elastic Beanstalk, so this isn’t a problem for us. The real issue is people: as Asana has grown from 20 to 60, and soon to 100, the challenge is creating a system where many people from different teams can contribute to the various parts of our site.
Every team that reaches a certain size has this problem, and it is a much harder scaling challenge than adding servers. Teams that overcome it have great websites – where content is updated and the story evolves effortlessly with the team.
At Asana, we’ve figured out a way to rapidly deploy changes to our content site. Non-technical teammates can jump right in and see their updates realtime, without bottlenecks, and without requests to developers. Everything we do is version controlled with Git – even copy changes. Virtually every team is contributing in some way to the site every week, and we do it all without a dedicated web developer. We’re saving so much time that we can write blog posts about it.
Here is how we do it:
Everyone learns Markdown; all content is in Markdown
Markdown is the minimum required skill to contribute to Asana.com. You don’t have to know code. Luckily, if you can write, you can write Markdown. Everyone at Asana reads this Daring Fireball article to get familiar with the conventions. If you need to use an HTML snippet, such as a video embed code, Markdown parses it without a problem.
Every page on our site is based on a Markdown file: every landing page, every help article, every job listing, and every showcase app. Literally every word on our site is in a Markdown file where anyone on our team can edit it.
We put the Markdown in Statamic, a file-based CMS
Statamic has an intuitive folder structure that anyone can understand. Content contributors know they can jump right into the _content folder and edit the Markdown files. Designers and developers know they can use templates and partials in virtually unlimited ways – we’ve never had to say “no” to a design because of limitations related to our CMS.
We make our changes in Github
Our content site is in a private Github repository that all Asanas have access to. We create and edit the Markdown files directly through their web interface. Technical teammates can clone the repo locally and use whatever tool stack they choose.
Non-technical teammates don’t need to know Git – they just need to know that “commit” basically equals “save” – and that they can’t break anything because it’s all version controlled. The Github editor renders the Markdown for you when you commit – so you can see that your styling worked. But even better than that, we’ve found a way to show Asanas their changes immediately on the website itself. Here’s how…
Our staging server is realtime
Using Github’s Post-Receive Hooks, every time anyone commits, we ping our staging server to pull and deploy a fresh version of our master branch. The person who added content can immediately see their change live on our staging server – and share it with the team if it requires feedback.
Why is this such a big deal? The vast majority of contributors don’t need a local development environment – they just need a Github account and a web browser. In fact, they don’t need technical skills of any kind.
The work in Github is linked to Asana
Not surprisingly, we use Asana to track all the work we’re doing across the company. Using the Asana Service Hook (available to everyone), we seamlessly connect Asana to Github. Anytime anyone commits, they add the relevant Asana #task_id to the commit message; this comments on the associated task in Asana with a link to the commit in Github, showing the whole team that the work has been done.
Before deploying, we test the site with CasperJS
CasperJS is a web testing utility written on top of PhantomJS. Before we push any change to our production server, we run a quick suite of tests to make sure that links resolve, resources load, and there are no Javascript errors. CasperJS can also do CSS regression testing by comparing screenshots.
Deploy daily
After running tests, I review the changes to the master branch since our last deployment (which are mainly Markdown changes – PHP/MySQL, HTML, JS, or CSS changes require a more thorough code review). We deploy daily to our production servers using the Elastic Beanstalk CLI.
What it all means
This process has profound effects on our team and our site. Adding content to Asana.com is exciting – a recruiter presses “commit” and sees a new job listing; someone on user operations improves a support article and immediately sees the results on a staging server. This decentralizes responsibility, makes peoples’ jobs more fun, and gives Asanas a strong sense of ownership over the content that relates to their function.
It also gives us tremendous leverage (and we’re all about that). This January, we completely redesigned a large portion of our site called the Asana Guide. The effort involved a dozen people writing, editing, changing design, updating links and navigation, and adjusting our CMS – at the same time. We tracked the work in Asana, did much of the work in Github, and watched it all unfold on a staging server… and we launched the site ontime without any issues.
We are frequently asked by other startups (and our customers) how we keep our content site so up to date. The answer is simple: with the right tools, it’s a team effort.