Adam Fortuna

@adamfortuna.com

Full-stack product developer (Rails/React) in Salt Lake City, UT. I love enlivening experiences, visualizing data, and making playful websites. 📚 Founder @hardcover.app 🎧 Developer @libro.fm ✍️ Blogger @ https://adamfortuna.com

Hardcover hit 7k weekly active users this week - a new high! Some API improvements we made last month sped up the site a bunch, along with a number of server tweaks and site optimizations. The site has been faster with less downtime as a result. Only 1 slow response time incident in 3 weeks!

Active users a week graph starting at 0 in 2022 and up to 7k now in 2026.Uptimerobot screenshot of a graph with a bunch of downtimes and spikes, but leveling out to fewer downtime and faster load speed in the past month.

After meeting with a bunch of arborist, I finally felt safe (for the trees) to cut some roots in our basement. Each one I talked said "I've never seen something like this before". That's ~9 times people we work with have said that. The joys of owning an old house. 😅 Bucky for scale.

50lb Black dog on the grass with roots about 4x the size for the dog.

It’s Pioneer Day today, Utah’s campy holiday that’s a combination of Independence Day and Columbus Day. For non-LDS folks like myself, it’s also called Pie and Beer Day. Picked up 4 mini pies to celebrate. 🥧

Hit a point yesterday where Hardcover's Sidekiq jobs were at 2.6m and growing. 📈 😱 They're now back at 0. What we did: 👉 Increase Kubernetes workers from 2 → 8 (they're CPU bound, so OK) 👉 Rewrite a jobs to use a Coalescing Queue design patter for counters, and cache columns 1/3

Hardcover's public API since day 1 has had no limits on the number of top-level queries to in GraphQL. That meant some people might send over 1000 mutations or 10,000 searches - towards a 60/s rate limit. Lowered this to 60 top-level requests/min over any number of requests and feels a lot safer 😅

Started listening to The Count of Monte Cristo, which has been on my list for a while. I loved the movie and the anime (Gankutsuou: The Count of Monte Cristo) from the same source. Watching France in the World Cup today too, and now I have an accidental theme. 🇫🇷 hardcover.app/books/the-co...

The Count of Monte Cristo - Hardcover

After fourteen years of wrongful imprisonment, merchant sailor Edmond Dantès escapes his grim island fortress. With the promises of youth erased and his betrothed now married to someone else, Dantès l...

hardcover.app

My talk for UtahJS was accepted! This is the first one I've given in the age of AI, and it's completely changing how I'm creating and teaching topics. What someone needs to "know" to create something using LLMs is so completely different than it was even a year ago.

Partial screenshot with title "Teaching Example: D3.js Axis". with an axis shown and a <svg viewbox example with draggable handles under some of the numbers.

First time ever grilling ribs today! Calcifer, our new Ninja FlexFlame grill, has a very useful app. Able to see the temperate of the grill and the meat, and have some custom timers. Doing one rack as maple bourbon, one as Carolina bbq. Let’s see how it goes. 🤞

Screenshot of ninja iPhone app set to 250 degrees f, with pork ribs set to 203, currently at 116.

I picked up work on Hardcover Groups today, which are a combination of Meetup Events, Facebook Groups and Reddit Subreddits. Fable 5 picked the perfect day to come back. Now to see how much use I can get before it's taken away again.

Working on something on Hardcover that I’ve wanted for a while: Filter Lists. Think BlueSky’s moderation lists and labels, but for books and authors. Add to your own block list, create a public, private or following only list, or subscribe to someone’s else’s. Choose to hide or label them. 👀

Screenshot of Hardcover with books highlighted red with a label to indicate a filter list. Ability to hide/show them anyways.

On March 26, 2026, during a debate on violence against women in Germany’s Bundestag, left-wing MP Kathrin Gebel was repeatedly interrupted by AfD MP Martin Reichardt. She responded: “Mr. Reichardt, the clitoris has 3,000 nerve endings, and you’re still more sensitive. That’s quite an achievement.”

One of my favorite AI hallucinations is how if you ask some models to generate a version of the Mona Lisa (ex: "Mona Lisa in Van Gogh's Starry Night style"), the person genreated might have two heads. ...because so much of the training data is people taking selfies with The Mona Lisa. 🖼️

Framed generated image of "Mona Lisa in Van Gogh style", with two mona lisa heads and stary night style sky.

I've been rebuilding the Hardcover Editor to use Plate.js ( platejs.org ) and it's been really neat! As part of this, we're also adding references to other entities in the system (books, authors, users, lists, etc). Lists can be Private or Follows only, which means they need to show up differently.

Review with links to other entities (book, list, etc) with one of them not shown.

Updated Hardcover's network diagram for the new Rust Search Proxy. About 20% of our API traffic passes through it. If I knew how Rust worked I'd be very excited about this. Claude Code built it and it seems to work super well, despite looking alien to me. 😅 Only 1 API req/s hits the main app. 📚

An architecture diagram of how Hardcover runs. Everything lives on Digital Ocean, with most of it inside a Kubernetes cluster.
A visitor hits a load balancer, which sends them either to the main Ruby on Rails app at hardcover.app or to the Rails API proxy at api.hardcover.app. The API proxy talks to two Hasura instances — one read-only, one read/write — that sit in front of our Postgres databases. There are four of those: a primary, a follower, a dedicated cache database, and a separate one for analytics. Redis is in there too, and a Sidekiq process chews through background jobs.
Search runs through Typesense, with a little Rust search proxy in front of it. Images get resized by Imaginary at img.hardcover.app, and there's a separate service that generates the OpenGraph screenshots you see when a link gets shared. Plausible handles our analytics, and a Digital Ocean Space hosts Rails assets.
Down in the Cloudflare layer: CDNs for images and static JS/CSS, plus an R2 bucket that mirrors our Google Cloud Storage (where book covers, avatars, and CSV imports/exports live). Off to the side, a headless WordPress site, and Loops handles transactional and newsletter email.Chart showing requests per second for API queries (42 req/s), mutations (1/s) and search (10/s).

We're getting close to a major milestone for @hardcover.app - 100k users! 👏 Launched: 2021 2022: 200 2023: 1,300 2024: 5,000 2025: 23,000 2026: 59,500 On pace to hit over 200,000 by 2027. 🫨 We're already starting to shift focus from acquisition to focusing on retention & engagement.

Text showing "99k users"