---
title: "A Hakka Engineer's Survival Rules: Is Serverless Worth It? Try It and You'll Know"
description: "The cloud is seductive, but the moment the bill shows up is genuinely nerve-racking"
author: "kidneyweakx"
published: 2025-08-28T00:00:00.000Z
updated: 2026-10-29T10:17:47.589Z
lang: en
tags: ["serverless", "cloudflare", "隨筆"]
canonical: https://kidneyweakx.com/blog/live-for-serverless?lang=en
alternate_zh_tw: https://kidneyweakx.com/blog/live-for-serverless.md
alternate_ja: https://kidneyweakx.com/blog/live-for-serverless.md?lang=ja
---

# A Hakka Engineer's Survival Rules: Is Serverless Worth It? Try It and You'll Know

> The cloud is seductive, but the moment the bill shows up is genuinely nerve-racking

Lately I've been thinking about how, as a **Hakka engineer** (we're famously thrifty), I can squeeze every last drop out of the resources I have. Back when I had a job, I used the cloud to my heart's content, but as someone obsessed with resource utilization, I always believed: save where you should, spend where you must, and wring every cent of value out of every cloud service.

After leaving the company, the "unlimited cloud access" I'd had through work was suddenly gone. Once you're used to luxury, it's hard to go back, so I kept firing up cloud tools like Gilgamesh unloading the Gate of Babylon, everything on and maxed out, until the bill arrived and I got annoyed. Back when I was a blockchain engineer, I'd spin up five EC2 instances at a time and run K8S at full blast. Doing the math now, that was a serious chunk of money every single month.

<br />

My lesson came on my last project. All I needed was a simple RDB, so I spun up a managed service on GCP, and the cloud vendor proceeded to show me what peak overhelpfulness looks like: automatic backups, monitoring, idle charges, the works. That one service alone burned through 2000 NTD a month. The project hadn't made a cent or gotten any traffic yet, and this evil cloud behemoth had already taken a bite out of me. Staring at that bill and its endless line items, **all I could do was curse under my breath, credit card in hand**.

**Lesson learned the hard way: cloud vendors' fat margins tend to hide in all those line items blooming like a hundred flowers.**

<br />

Paying for traffic, paying for compute, fine, I accept that. But when you realize that keeping alive a service that maybe a handful of people use per day means paying a fixed monthly infrastructure fee, Serverless suddenly becomes a crucial choice.

> **Why have I moved my whole stack to Serverless, and why Cloudflare Workers in particular?**

## Nobody uses it, nobody pays

The answer is very Hakka: **when it's idle, the bill is zero.**

With a traditional managed DB or VM, whether or not anyone uses it, the machine sits there running and the meter keeps ticking. Workers only charges when a request comes in, and the free plan gives you 100,000 requests a day, which a personal project will never use up. Storing things on R2 has no egress fees either, which is super friendly for a blog full of images.

Take this blog you're reading right now. The whole site is really just three pieces:

- A `blog` Worker for the frontend (SvelteKit)
- A `blog-cms` Worker for the admin and API (Elysia), with Cloudflare Access in front of it
- An R2 bucket holding `index.json`, each post's Markdown, and the images

**No database.** Yep, you read that right. Even the DB got cut.

<br />

## Watch the connection pool: a small trap when serverless talks to a database

The reason I cut the DB is that I've genuinely been burned by hooking serverless up to a database before. Here's the gist; for why it blows up and code you can copy straight away, I wrote it up separately in "[Watch the Connection Pool: A Small Trap When Connecting Serverless to a Database](https://kidneyweakx.com/blog/serverless-db-connection-pitfalls)".

A traditional backend connection pool rests on one big assumption: **your program is a long-lived process**. It opens ten connections at startup, then ten thousand requests take turns using those ten, and everyone gets along just fine.

Serverless breaks exactly that assumption:

- Every isolate / function instance is independent. When traffic arrives, a whole bunch of instances spin up at once, and **each instance opens its own connections**
- Instances can be reclaimed at any moment and connections don't always get closed cleanly, so the DB ends up holding a pile of half-dead connections
- Postgres and MySQL both have a `max_connections` limit. When a traffic spike hits, it's not your program that falls over first; the DB starts refusing connections

The result: **everything's fine normally, and it blows up the moment traffic shows up**, right when you most need it to stay alive.

<br />

There are roughly three ways out:

1. **Switch to a database driver that goes over HTTP**: like Turso (libSQL) or Neon's serverless driver. Every query is just an HTTP request, with no long-lived connections to manage
2. **Put a connection pool proxy in the middle**: that's exactly what Cloudflare's Hyperdrive does. The Worker connects to Hyperdrive, and Hyperdrive maintains the connection pool to Postgres for you
3. **Just skip the database**: if your data is small and writes are infrequent, a JSON index plus a bunch of files is plenty

This blog used to run on PayloadCMS plus Turso, which counts as option one. Later I realized that for a blog updated once or twice a month, keeping a CMS and a DB alive was way too extravagant, so I went straight for option three: the post list is `index.json` on R2, the post bodies are `content/<slug>.md`, and the frontend Worker only gets read-only access to R2. **The best connection pool is no connection pool**.

## But serverless isn't a free lunch either

After all that praise, I should be honest about the costs:

- **Environment variables aren't global**: Workers bindings arrive with each request, so a framework like Elysia, which likes to read config at the module level, has to pass env all the way down via `AsyncLocalStorage`
- **No dynamic code generation**: Workers forbid things like `new Function`, so Elysia only runs once you turn off AOT (`aot: false`)
- **Local dev takes some getting used to**: I now run `wrangler dev` directly against the production R2. Convenient, sure, but one slip and you're editing live data

None of these holes are deep, but you only find them by stepping in them.

<br />

## Try it and you'll know

So, for the "try it and you'll know" in the title, my verdict is: **for personal projects and low-traffic services, serverless really is a Hakka's best friend**. Nobody uses it, you pay nothing; people use it, you pay for what you use. The worst case is getting flooded with traffic, but by then you should have the money to pay the bill.

As for that 2000 NTD, I'll call it tuition. At least now, when the Cloudflare bill arrives each month, I'm at peace.
