Now that we've finally completed our migration off Medium and onto a self-hosted Ghost instance, I wanted to take the time to explain why we made the switch and how we decided on Ghost as our software of choice, as is tradition (see HackerNoon, FreeCodeCamp, and Signal v Noise).
When we first started Plan A Magazine we were looking to get started with minimal overhead and investment. We didn't have a business plan, we didn't have wild ambitions, we didn't even necessarily have a mission statement (though we do now). What we did have was something to say and nowhere to say it.
So we decided to start an online magazine and began looking for a platform. We chose Medium for a few reasons:
- Free with no ads
- Smooth writing experience and interface
- Community & network effects
- Support for publications & custom domains (we got lucky here)
This worked out great for us in the beginning. Medium enabled us to get writing right away with a presentable site and custom domain. A couple of our articles benefitted from Medium's network effects so we were excited for what the future might hold.
Cracks Start Showing
As we built up our reader base and started getting more serious about building up Plan A, we started noticing Medium's shortcomings. Some of it due to the nature of our site being hosted by an external party, some of it by Medium's design.
- Lack of control over appearance
- Lack of extensibility
- Poor performance & analytics
- Medium inserting itself at every possible point in our reader's experience
Some of these shortcomings are expected when your website is hosted (for free) by an external party. However, aside from the lack of control over appearance, what mattered most to us was that our content was available and accessible. Unfortunately Medium failed us in that regard.
With a Google PageSpeed Insights score of 12 (out of 100!) performance metrics for our Medium publication were terrible:
- First Contentful Paint: 4.5s
- First Meaningful Paint: 8.9s
- First CPU Idle: 15.3s
- Time to Interactive: 15.9s
- Max Potential First Input Delay: 6,160ms
Some of the factors behind Medium's abysmal performance were:
- Multiple page redirects averaging 1.56s
- Medium's JS weighing a whopping 927kb
- Main thread blocking of 13.9s on script evaluation and 1.9s on garbage collection
This was just not going to cut it so we started looking for a new platform.
Since we all have day jobs and operate Plan A as a side project, we took our time discussing the migration plan. We were growing our reader base and we didn't want to rush into it. Unfortunately Medium forced our hand.
Medium decided to set up a membership service giving its members access to paywalled articles hosted on Medium. Medium would go on to share that revenue with the authors of paywalled articles based on page views. That's a good thing right?
On its own that's a great thing (we pay our writers too) but we wanted our content to be freely available. Should be fine because participation was opt-in right? Wrong, it seemed to be opt-out not opt-in, and this lead to confusion among our writers and a consequently a worse experience for our readers.
In addition to memberships, Medium began buying out established publications and featuring them on Medium. This presents an obvious conflict of interest. Perhaps it's cynical of me, but I imagine this change greatly reduces any potential benefit of our content being discoverable through Medium's network.
This pretty much put the nail in the coffin on any future with Medium. There simply were no remaining benefits to staying on their platform. With 78% of our traffic coming from organic searches and social media shares, and another 16% of our traffic coming to us directly, we wouldn't miss Medium's network much.
A Brighter Future
After reviewing our options we decided to self-host a Ghost server (more on why we chose Ghost later). After a long finger numbing manual migration (Medium does not make it easy to export your content) here's what we were able to accomplish:
- First Contentful Paint: 2.1s (~54% reduction)
- First Meaningful Paint: 2.1s (~76% reduction)
- First CPU Idle: 3.2s (~80% reduction)
- Time to Interactive: 4.1s (~75% reduction)
- Max Potential First Input Delay: 150ms (~98% reduction)
With a Google PageSpeed Insight score of 93, moving onto Ghost gave us some serious performance improvements! Not only did we greatly improve our reader's experience, we also gained full control over content. By moving to Ghost we also gained control over our site's presentation and layout as you've no doubt noticed by now. Major wins all around.
Ghost has been a pleasure to work with and the small but active community is great. Setting up Ghost on a DigitalOcean droplet was really easy and it doesn't require high end specs either.
The hardest part was exporting our content off Medium. Their only option is to export html files and parsing those files for your raw content is not an easy task. There are pictures to download and re-insert, metadata to add, and redirects to be set up (to handle any links to our old slugs). This is fine for 50, maybe a 100 articles, but we had 300+ articles to migrate and it was growing day by day. After this experience I have a greatly increased appreciation for common standards.
After that it was just a matter of updating DNS records and we were on our way. With our current daily volume Ghost is keeping up just fine, I don't think we're anywhere near its limits. It's probably earning a degree on the side and not breaking a sweat.
Why We Chose Ghost
If you've made it this far, you might be wondering why we chose Ghost over other platforms such as WordPress. When we thought about what we wanted out of the new site here's what we prioritized:
- Strong SEO & social features
- Good UI for editors and contributors
- Performant and efficient
Ghost hit all of those priorities. SEO and social media features are baked in (built-in AMP pages too), Ghost's Koenig editor reminds me very much of Medium's editor, and Ghost runs well on a VPS with entry-level specs. I'm sure we could have made a number of the available solutions work for us, but Ghost gave us what we wanted out of the box at a very manageable cost and it's open source.
Ghost is written in Node.js which is a language and ecosystem I'm more familiar with than PHP. Nice to know if I ever want to make changes to the core software. If the built-in Handlebars templates can't keep up, the option to use Ghost as a headless CMS is nice to have, allowing for a wide range possibilities including static site generators. Articles are stored as plain text, HTML, and Mobiledoc and the articles along with all our data can be exported as a JSON file so if we do have to move platforms again, it should be possible to programmatically migrate our content.
All in all our move away from Medium has been a great success. Looking forward, the next immediate improvements we can make would be image optimization and using a CDN. Who knows what the future holds, maybe we decide we want to self-host our podcasts too...