Skip to content
9 min read
A computer circuit board traveling at warp speed through space with motion-blurred light streaks radiating outward, symbolizing high-performance computing and speed.

The Need for Speed: Why I Rebuilt My Blog with Astro

Two weekends ago, I quietly relaunched my blog. It was a heart transplant really, of the same design I’d launched in late March.

The First Iteration

Back in early November of last year, I re-platformed from WordPress to a home-grown, Cursor-made static site generator. I’d write in Markdown and push code to my GitHub repository and the post was published via Vercel’s continuous deployment feature. The design was simple and it was a great learning project for me.

Screenshot of Roger Wong's first blog design from November 2024, featuring a dark navy background with white text. The homepage shows a large hero section with Roger's bio and headshot, followed by a "Latest Posts" section displaying the essay "From Craft to Curation: Design Leadership in the Age of AI" with a stylized illustration of a person wearing glasses with orange and blue gradient reflections. A "Latest Links" section appears on the right side.

My first blog redesign from November 2024, built with Cursor as a static site generator. Simple, clean, and good enough to get me writing again.

As soon as I launched it, I got the bug to write more because the platform was shiny and new. And as soon as I started to write more essays, I also really wanted to write short-form comments on links in the vein of Jason Kottke and John Gruber. So in January of this year, I started to design a new version of the site.

Designing for a Feed

My idea was to create a feed-like experience, since the majority of the posts were likely going to be short and link off to external sites. I was heavily inspired by the design of Bluesky and by the aforementioned blogs. I don’t pretend to be Kottke or Gruber, but that’s the style of blog I wanted to have.

I put down my idea quickly in Figma, in bed, half-watching Top Chef with my wife.

Screenshot of a Figma design mockup showing a feed-style blog layout with a light gray background and minimal sidebar navigation on the left (Home, Posts, Linked, Search, About). The main content area displays a vertical feed of posts with colored preview cards - one coral/pink card about a Clamshell keyboard case, and one mint green card for an essay titled "Design's Purpose Remains Constant." The right sidebar shows author info and navigation links.

The initial Figma sketch done in bed while half-watching Top Chef. A feed-like layout inspired by Bluesky, optimized for short-form link posts with commentary.

The main content column is supposed to look like a social media app’s feed, a long list with link previews and commentary if I had any. I optimized the structure for mobile—though only 38% of my traffic from the last six months is mobile. I noodled on the design details for a few more nights before jumping into the tech solution.

Why I Chose a CMS

Markdown is great for writing, especially if there’s a good editor. For example, I use Ulysses for Mac (and sometimes for iPad). I can easily export MD files from Ulysses.

But because I came from WordPress, it seemed conceptually silly to me to rebuild the whole site every time I published a post. Granted, that’s how Movable Type used to do it in the old days (and I guess they still do!). So I looked around and found Payload CMS, which was built by designers and developers coming from the WordPress ecosystem. And it made sense to me: render a template and fill in the content slots with data from the database. (I’m sure the developers out there have lots of arguments for the static files. I know! As you’ll see, I learned my lesson.)

I tapped Cursor again to help me build the site that would be on Next.js with Payload as the CMS. I spent three months on it, building custom functionality, perfecting all the details, and launched quietly with my first official post on March 27, linking to a lovely visual essay from Amelia Wattenberger.

And I loved the site. Workflow was easy and that encouraged me to post regularly. It worked great. Until it didn’t.

When Things Started Breaking

The database I used to power the site was MongoDB, a modern cloud-based database that’s recommended by Payload. It worked great initially. I did a lot of performance tuning to make the site feel snappy and it did mostly. Or I got used to the lag.

But as the post count grew, three things started going wrong:

  1. List pages sometimes wouldn’t load and result in an error.
  2. Search results would sometimes take forever, like 10 seconds to return something.
  3. In the admin UI, when clicking on a post lookup menu to link to a related post, it often errored out.

Despite additional optimizations I did to minimize the database connections and usage, I couldn’t solve it. The only solution was to upgrade from the lowest plan, which cost me about $10 per month, to the next level up at $60 per month. A six-times increase for a hobby blog. I didn’t think that was a prudent financial decision.

Enter Astro.

The Migration to Astro

I looked around for a more performant content framework. Astro had come up in my initial search, but after learning about it more, it became clear to me this was the way to go. So I spent about a week (nights only) migrating my Next.js/Payload site to Astro. Since many of the components in the original site were written in TypeScript, it was actually not that hard to tell Claude Code and Cursor to “look at the reference” to get the styling nailed. I wanted the exact same design and only needed to change the backend. The trickiest part of the whole migration has been extracting the posts from MongoDB and transforming them into Markdown files, more specifically, MDX files, which allow for JavaScript within the content in case I ever needed that flexibility.

Astro also doesn’t have built in search, so I chose to integrate Algolia.

The results are fantastic. The site is even faster. Search is lightning fast. Here are two comparisons I’ve done: the /posts page and a single post (specifically, “Why We Still Need a HyperCard for the AI Era”). The difference is pretty stark:

Bar chart comparing web performance metrics for a posts page between Astro and Next.js/Payload. Astro shows 33 requests, 2.8 MB transferred, 3.2 MB resources, 909ms finish time, 178ms DOMContentLoaded, and 263ms Load time. Next.js/Payload shows 87 requests, 4.5 MB transferred, 6.9 MB resources, 8.45 second finish time, 390ms DOMContentLoaded, and 479ms Load time. Astro delivers substantially faster performance across all measurements.

Performance comparison loading the posts index page: Astro (purple) vs Next.js/Payload (blue). Astro completes in 909ms with 33 requests, while Next.js takes 8.45 seconds with 87 requests.

Bar chart comparing web performance metrics for a single post page between Astro and Next.js/Payload. Astro shows 27 requests, 1.6 MB transferred, 1.7 MB resources, 746ms finish time, 84ms DOMContentLoaded, and 127ms Load time. Next.js/Payload shows 72 requests, 2.1 MB transferred, 3.6 MB resources, 21.85 second finish time, 175ms DOMContentLoaded, and 272ms Load time. Astro significantly outperforms Next.js across all metrics.

Performance comparison loading a single blog post: Astro (purple) vs Next.js/Payload (blue). Astro finishes in 746ms with 27 requests, while Next.js takes 21.85 seconds with 72 requests.

The Numbers Don’t Lie

The performance difference is staggering. On the posts page, Astro loads in under a second (909 ms) while Next.js takes over 8 seconds. For a single post page, it’s even more dramatic—Astro finishes downloading and rendering all resources in 746 ms while Next.js takes a brutal 21.85 seconds. That’s nearly thirty-times slower for the exact same content. The numbers tell the story: Astro makes two- to-three times fewer server requests and transfers significantly less data. But the real difference is in how it feels—with Astro, the content appears almost instantly (84 ms DOMContentLoaded on the single post), while it took twice that for Next.js.

The kicker? Search performance. On the old Next.js/MongoDB setup, searching for “paul rand” took 3.63 seconds. With Algolia on Astro, that same search completes in 29.55 milliseconds. That’s over a hundred times faster. Not “a bit snappier.” Not “noticeably improved.” It’s the difference between a search that makes you wait and one that feels instantaneous—the kind of speed that fundamentally changes how you interact with content.

Building a Simple Admin

The advantage that Payload CMS has, of course, is its fully-featured admin experience. That doesn’t come with Astro and this setup. I started working on a simple admin UI for myself that will help me fill in the “frontmatter”—the metadata at the top of the MDX file, like tags, related posts, publish date, etc.

Screenshot of a custom blog post editor interface showing two panels: the left panel contains post metadata fields including Featured Image, SEO Meta Title, Category, Tags, and Related Posts; the right panel displays the post content in Markdown format with sections on performance comparisons and building a simple admin, plus an "Upload Image" section at the bottom with fields for Bunny URL and Image Alt Text.

The simple admin UI I’m building for myself.

The basics are working so far, but there is more I’d like to do with it, including adding an AI feature to help autofill tags and write alt text for images.

What I Learned

Sometimes the right tool isn’t the most feature-rich one—it’s the one that gets out of the way. I spent months building on Next.js and Payload because it felt like the “proper” way to build a modern CMS-driven site. Database, API routes, server-side rendering—all the things you’re supposed to want. (I learned a lot along the way, so I don’t see any of it as time wasted.)

But here’s what I actually needed: fast page loads and a simple way to write. That’s it.

Astro gives me both. The static site generation approach I initially dismissed turned out to be exactly right for a content site like this. No database queries slowing things down. No server costs scaling with traffic. Just clean, fast HTML with the minimum JavaScript needed to make things work.

The trade-off? I lost the polished admin interface. But I gained something more valuable: a site that loads instantly and costs almost nothing to run. Between ditching the $10/month MongoDB plan (which wanted to become $60/month) and Astro’s efficient static generation, hosting costs dropped to basically just the $20/month pro plan on Vercel. For a personal blog, that’s the right exchange.

It turns out the old ways—static files, Markdown, simple deployments—weren’t outdated. They were just waiting for better tools. Astro is that better tool. And honestly? Writing in MDX files feels pretty good. Clean. Direct. Just me and the content.

The site looks exactly the same as it did before. But now it actually works the way it should have from the start.

Subscribe for updates

Get design insights in your inbox. Sent weekly (or so).