notes
Aug 14, 2026 · 1 min read

Static Sites, Revisited

Two years ago I moved this site to a server-rendered stack chasing features I used maybe twice. Last month I moved it back to something that just builds to files and sits on a CDN. It was, without exaggeration, the fastest performance win I’ve shipped all year.

Why static still wins

Most of what a blog needs — typography, a fast first paint, content that doesn’t change per request — is exactly what static output is best at. The server work I’d added wasn’t serving readers; it was serving my own curiosity about the stack.

The fastest request is the one your server never has to think about.

The one place I kept dynamic behavior was content collections — typed frontmatter, checked at build time:

const blog = defineCollection({
  loader: glob({ pattern: '**/*.md', base: './src/content/blog' }),
  schema: z.object({
    title: z.string(),
    pubDate: z.coerce.date(),
  }),
});

If a post’s frontmatter is wrong, the build fails before it ever reaches a reader. That’s the whole appeal — correctness as a byproduct of simplicity, not a framework bolted on top of it.

None of this means server rendering is wrong for every project. It means it was wrong for this one — a handful of pages that change a few times a month, read by people who just want the words to show up fast.