Write that blog… with Turso!

Piotr SarnaPiotr Sarna
Cover image for Write that blog… with Turso!

My new book on writing engineering blogs, co-authored with the magnificent Cynthia Dunlop, is hot off the press. We decided to take an alternative approach to promoting the book. Instead of endless tweets, we're launching a technical blog post aggregator. The aggregator's main purpose is to encourage more people to write, hence the name: https://writethat.blog.

As we stumble upon blog posts that we think are interesting to blog post readers/writers, we share them there, along with a short take on why each one stood out to us. Each post is also assigned one of the blog post "pattern" categories we described in the book:

  • bug hunt
  • we rewrote it in X
  • how we built it
  • lessons learned
  • thoughts on trends
  • non-markety product perspectives
  • benchmarks and test results

Building the first iteration of this web page took me around 4 minutes total, and the heart of the implementation is Turso!

#The implementation

Each time WriteThatBlog! loads in someone’s browser, it dynamically asks the database for the list of all blog post entries for the given month. Turso speaks HTTP, so it's the browser that asks for the information: no lambdas, no proxies, no whatever.

I've set up multiple replicas of the database, so the latency should be pleasantly low in various parts of the globe.

The web page has a Turso authentication token baked into the source. How can that possibly be secure? Well, it's a read-only token, and it's "leaked" to the browser on purpose. The web page is generally available to read by everyone, and so is its data!

Fetching fresh entries is really fast – it often takes less time than the browser needs to queue and schedule the actual request.

Google's PageSpeed analysis seems to agree!

I'm by no means a web developer, so I used the help of an Undisclosed Large Language Model 😇 to generate the frontend layer for me – hence the 4 minutes of development time.

I kindly asked the model to mimic the communication scheme from my other weekend project — the sorry@idont.date disposable email service that’s also based on Turso.

Yes, you guessed correctly — I'm addicted to grabbing lots of domain names. It's a great motivational tool. The money ($3 is technically “money”) is already invested, so now the cool domain name needs an implementation before it goes to waste!

The whole page is a single HTML file, hosted on GitHub Pages. Anything more than that is already beyond my frontend management skills anyway.

The "backend" is simply a Turso table, with the following self-descriptive schema:

CREATE TABLE blog(date, title, content, link, pattern);

Each field corresponds directly to how each entry is rendered.

#The (lack of) maintenance burden

The most pleasant aspect of this project is the ease of updates. Adding, removing, and updating entries takes seconds and happens 100% in the console.

With turso shell set up, I created my very elaborate shell script:

read DATE
read TITLE
read CONTENTS
read LINK
read PATTERN
turso db shell spin "INSERT INTO blog VALUES ('$DATE', '$TITLE', '$CONTENTS', '$LINK', '$PATTERN') RETURNING ROWID;"

Adding a new post is as easy as writing all the details down:

$ ./push.sh <<EOF
2024-09-10
Noisy Neighbor Detection with eBPF
This article is an introduction to eBPF-based profiling, with code samples and examples. It shows how to try and detect noisy neighbors that share a physical machine by tracking certain scheduler events in the Linux kernel. It is also a quite detailed guide on how to write more complex eBPF hooks -- using the available data structures (ring buffers, hash maps), calling available kernel functions (e.g. taking a read-copy-update lock).
https://netflixtechblog.com/noisy-neighbor-detection-with-ebpf-64b1f4b3bbdd
how we built it
EOF

ROWID
16

As you may have noticed, the script returns the entry's ROWID. ROWID is a unique identifier of a table's row. Tables implicitly have the ROWID column unless you opt out from it with WITHOUT ROWID keywords.

Why do I bother returning it? Because it makes fixing or removing the entry even more trivial than posting it.

Say I changed my mind and want to unpublish the post above. Here's how to do it:

turso db shell spin "DELETE FROM blog WHERE rowid = 16"

Or, if I feel like adding a punchline to the content or changing the category, it’s this simple:

turso db shell spin "UPDATE blog SET content = content || ' Highly recommended!!!11' WHERE rowid = 16;"
turso db shell spin "UPDATE blog SET category = 'lessons learned' WHERE rowid = 16"

Posting online has never been so simple for me!

This is a guest post by a customer, partner or community user of Turso.
scarf