Un blog no debería ser un SaaS | Parte 1/x
10 min read

Written by Rodrigo de Miguel

A blog shouldn't be a SaaS | Part 1/x

Why Astro SSG + AWS instead of Vercel

I moved from a React SPA (poor SEO and improvable CWV) to Astro with SSG served on AWS (S3 + CloudFront + Route 53) to have fast HTML, simple infrastructure, and minimal costs, without unnecessary vendor lock-in for a portfolio/blog.

Astro
SSG Static Site Generation
AWS
SEO
Core Web Vitals
WPO Web Performance Optimization
CDN
Infrastructure
Vendor Lock-in

Context: I didn’t want to build a product, I wanted a serious portfolio

This article comes from a very specific, very un-epic decision:

I wanted a portfolio (and later I added a personal blog), not a SaaS, not a monetizable side-project, not a startup.

It wasn’t going to make money.
It wasn’t going to have business logic with concurrent users.
It wasn’t going to need advanced analytics or A/B testing.

But I did want three very clear things:

  • SEO done right
  • Perfect Core Web Vitals
  • Simple, cheap infrastructure that I control

Nothing more.

And that’s exactly where a lot of today’s solutions start to be overkill.


The real problem: when the tool is bigger than the problem

For a while my portfolio was built as a React SPA.
It worked. It looked good. But it had two clear problems:

  1. Weak SEO unless you started adding hacks
  2. Core Web Vitals could be improved, especially LCP and CLS

I could’ve “fixed” it with:

  • SSR
  • prerendering
  • plugins
  • more infrastructure

But I asked myself a very simple question:

Why am I complicating something that only needs to serve HTML fast?

I wanted to try Astro without changing too much of the infrastructure I already had. And that’s where everything started.


The technical fork: modern platforms vs a simple stack

At this point there were two pretty reasonable paths.

Option A: a Vercel-like platform

Vercel is popular for a reason:

  • easy deploys
  • great DX
  • a tempting free tier

For many projects it’s a perfect fit.
I have nothing against it.

But in this specific context, a few “buts” showed up:

  • Full vendor dependency
  • Costs that can spike once you leave the happy path
  • Opaque infra: it works, but you don’t really know what’s under the hood
  • Built for apps, not for pure static HTML

For a portfolio with no revenue, that was too much.


Option B: Astro SSG + AWS (S3 + CloudFront)

The alternative was going back to basics, but with some technical love:

  • Generate static HTML
  • Serve it from a CDN I already had set up
  • Pay only what’s strictly necessary
  • Know exactly what each piece does
  • Reuse the existing React code

This is where Astro starts to make sense.


Why Astro and not Next or Nuxt

I didn’t need:

  • SSR
  • API routes
  • middleware
  • edge functions

What I wanted was:

  • fast HTML
  • a simple build
  • good Markdown support
  • zero friction for SEO

Astro fits that scenario really well because it:

  • prioritizes Static Site Generation
  • doesn’t lock you into a specific framework
  • drops JavaScript when it isn’t needed
  • outputs clean, predictable HTML

For a blog and a portfolio, it’s right in the sweet spot.


SSG isn’t a trend, it’s common sense (here)

A blog with SSG has some pretty clear advantages in this context:

AspectSSG
SEOExcellent
CWVVery easy to tune
CostZero
ComplexityLow
MaintenanceMinimal

No database.
No backend.
No runtime.

Just files.

That’s not a limitation.
That’s freedom.


SSG isn’t new: WordPress has been doing it for years

It’s worth remembering something simple:
Static Site Generation isn’t some recent trend.

WordPress has been serving HTML from the server (SSR) for years and it’s more than good enough for blogs and portfolios. It’s a totally valid option.

In my case I didn’t choose it for a very simple reason:
my portfolio was already in React because it was comfortable and let me tweak everything… and, honestly, I know just enough PHP, and I didn’t feel like rebuilding it in WordPress.

The lesson isn’t “WordPress vs Astro”.
It’s understanding that generating HTML on the server has always been the logical solution for this kind of site.
And with Astro, you do it with a couple of lines.

You can also do it in React with a “handmade” SSG setup using a NodeJS script, but that’s a post for another day.


Infrastructure: boring, cheap, and predictable (as it sometimes should be)

The final stack ended up like this:

  • Astro → generates HTML
  • S3 → stores the files
  • CloudFront → global CDN
  • Route 53 → DNS and domain

Si presentas esto en un trabajo de clase te suspenden de lo sencillo que es 🤣
Si presentas esto en un trabajo de clase te suspenden de lo sencillo que es 🤣

That’s it.

No middlemen.
No magic.
No “platforms”.


Real cost: let’s be clear

This part matters.

In my specific case:

  • I have quite a few hosted zones in Route 53
  • the cost is around ~$0.10 USD / month

For a normal person:

  • Route 53 costs $0.50 USD / month per hosted zone
  • S3 + CloudFront, with low traffic, is basically free

CloudFront’s free tier includes 10 million HTTP/HTTPS requests per month or 1 TB monthly transfer, which roughly translates to more than 2 million visits (each page transfers ~580 KB).

If you have that kind of traffic on a personal blog: congrats, you’re famous, you probably don’t need to read this 🤣

ItemMonthly cost
Route 53$0.50 USD
S3~$0 USD
CloudFront~$0 USD
Total~$0.50 USD

This isn’t an optimistic estimate.
This is what happens when you serve static HTML.


SEO and CWV as a requirement, not a last-minute patch

This is a meaningful mindset shift.

I didn’t optimize SEO “because Google demands it”.
I did it because I enjoy doing it properly.

  • Predictable HTML
  • Clean URLs
  • No unnecessary JavaScript
  • Full control over rendering

With SSG + CDN:

  • LCP is almost trivial
  • CLS disappears
  • INP stops being a problem

No weird tricks.
Just good decisions from the start.


What about analytics?

This isn’t a SaaS.

I don’t need funnels, cohorts, or complex events.

I use:

  • Google Search Console for SEO

And that’s it.

If someone wants:

  • GA4
  • Plausible
  • whatever fits

You can add it without drama.
But it’s not mandatory.


Vendor lock-in: the detail almost nobody mentions

With this approach:

  • the output is HTML
  • hosting is standard
  • the domain is mine

If tomorrow I want to:

  • move to another provider
  • serve it from another CDN
  • change DNS

No painful migrations.
No weird dependencies.

For a personal project, that brings a lot of peace of mind.


“If it grows, I’ll migrate later” (and why it makes sense here)

This argument is often misused, but here it fits.

If one day:

  • the blog grows
  • I need SSR
  • dynamic parts show up

Then:

  • the decision gets revisited
  • the stack gets adjusted

But not today.

Today the problem is different, and this solution fits what I need right now.

As Elon Musk said:

The most common mistake of a smart engineer is optimizing something that shouldn’t exist.

If I ever get 2 million monthly visits on a personal blog, I promise I’ll worry about other things before infrastructure.


What I changed compared to my previous setup

Before (not bad, but could be better)

  • React SPA
  • Forced SEO
  • More JavaScript than necessary
  • Mediocre CWV

CWV antes con SPA React
CWV antes con SPA React

Now (ouuuh yeahh! 🎉)

  • Astro SSG
  • Pure HTML
  • Simple infra
  • Excellent CWV

CWV de Astro SSG
CWV de Astro SSG

The change didn’t come from extreme urgency.
It came from technical judgment.

And from the pure joy of seeing (almost) everything green in PageSpeed Insights.


What’s left to do (honestly)

This setup isn’t “perfect”, it’s good enough.

To do:

  • Automate deploy with GitHub Actions (real TODO)
  • Add comments to posts
    • Giscus (GitHub Discussions)
    • Disqus
    • etc.

For now, comments via LinkedIn or email work well.

Nothing blocking.
Nothing that keeps me up at night.


A blog doesn’t need to be a modern SaaS

For a personal portfolio + blog:

  • less is more
  • simple scales better
  • cheap hurts less
  • control matters more than convenience
  • I only worry about writing (which is already enough)

Astro + SSG + AWS isn’t a “modern” decision.
It’s a sensible decision for my current situation.

And for this context, it was exactly what I was looking for.


👉 Post 2: Getting an Astro project ready for production (SSG, sitemap, and structure) — and that’s where we’ll actually get into code.

Let's talk?

Looking for someone who understands product as much as code?

Start a conversation

© 2026 Rodrigo de Miguel. All rights reserved.