Today I redesigned this blog’s deploy process. It was taking ~8m to publish updates because it was recomputing global state for every new post. Now it takes ~45s while maintaining the properties I need:
- Notes edited in Obsidian
- Can change git and web hosting providers within 1h
- Automatic deploys with manual option
The blog has 390 posts and 2k images, but the whole vault is much larger.
BEFORE
- 3 github repos: obsidian vault, hugo blog (except
public/dir), hugo blog’spublic/dir - A post-merge GH workflow checks out the whole vault, calls Hugo to update
content/andpublic/, commits changes to both repos. - Cloudflare redeploys on merges to the blog’s
public/.
| Step | Time |
|---|---|
| Checkout vault | 40s |
| Install Hugo + obsidian-export | 40s |
| Clone Hugo repo | 30s |
| npm install | 15s |
| obsidian-export | 10s |
| Hugo build (cold) | ~5min |
| git push public repo | 30s |
| Cloudflare’s deploy | 53s |
AFTER
- 2 github repos: obsidian vault, hugo blog
- A post-merge GH action on the vault repo checks out the hugo repo, updates
content/andpublic/and deploys to Cloudflare withwrangler - Self-hosted runner instead of Github managed runner
| Step | Time |
|---|---|
| Checkout vault (sparse) | 1s |
| Checkout Hugo repo (fetch) | 3s |
| npm ci (for hugo + tailwind) | 3s |
| obsidian-export | 2s |
| Hugo build (warm) | 7s |
| wrangler deploy | 18s |
| Overhead (setup, SSH, etc.) | 11s |
| Wrangler’s Phase | Time |
|---|---|
| wrangler startup | ~2s |
| Hash 4351 files | ~7s |
| Upload changed files | ~1s |
| API call + propagation | ~8s |
7:53 ████████████████████████████████████████████ BEFORE
0:46 ████ AFTER
The new system is faster because it caches at almost every step and layer (I/O, compute, network). 71% of the speed up comes from caching image thumbnails.
Swapping GitHub’s free managed runner for a self managed one didn’t move the needle but mine has more than GitHub’s one 9 of reliability.
Security wise the new setup decreases attack surface by removing repo write access from the deploy workflow but increases it slightly via the self hosted gh action runner (container escape risk).
There’s space for more optimizations but it’s in diminishing returns territory.
Observations
- Push vs pull: pull deploys reduce infra to maintain but you tradeoff control. When you have multiple tenants and environments, the latency costs rapidly multiply.
- Caching: it was how I made gamersmafia.com fast enough on an Athlon 700Mhz in 2000 to play UT99 with thousands of visits a day, and it’s still the same today.
- The ROI for optimizing systems is growing fast: thanks to AI coding assistants, it took about 2h to do this and I spent most of that time learning about v8 isolates, Cloudflare infra choices, and tweaking some Claude Code skills.