Spring Boot + Thymeleaf + htmx technical journal for the async-bulkhead-* package family.
The site is intentionally server-rendered. Every article has a stable URL under /journal/{slug} so posts can be shared, indexed, and linked from package READMEs.
- Java 21
- Spring Boot 3.5.x
- Thymeleaf
- htmx via WebJar
- CommonMark Java for Markdown rendering
- YAML front matter for article metadata
mvn spring-boot:runThen open:
http://localhost:8080By default, the app reads sample Markdown files from:
sample-content/articlesKeep this application repository public and keep drafts/articles in a private repository.
Private repo shape:
systems-under-load-content/
articles/
p-limit-vs-bulkhead.md
protect-outbound-fetch-calls.md
protect-llm-providers.mdRun with the private content path:
export JOURNAL_CONTENT_DIR=/srv/systems-under-load-content/articles
export JOURNAL_BASE_URL=https://systemsunderload.dev
mvn spring-boot:runDuring deploy, clone the private repo, mount it, or copy it into the container/host and point JOURNAL_CONTENT_DIR at the articles directory.
Each article is a .md file with YAML front matter:
---
title: "Protect outbound fetch calls from request storms"
slug: "protect-outbound-fetch-calls"
description: "How to place fail-fast admission control around fetch calls."
publishedAt: 2026-05-06
updatedAt: 2026-05-07
tags: [fetch, nodejs, reliability]
draft: false
canonicalPath: "/journal/protect-outbound-fetch-calls"
---
# Protect outbound fetch calls from request storms
Article body...Required fields:
titleslugpublishedAt
Recommended fields:
description, used for SEO cards and article previewstags, used by the journal listingdraft, hides the article unlessJOURNAL_SHOW_DRAFTS=true
If canonicalPath is omitted, the app uses /journal/{slug}.
| Route | Purpose |
|---|---|
/ |
Homepage with latest posts |
/journal |
Searchable journal index |
/journal/{slug} |
Shareable article page |
/fragments/articles |
htmx article-list fragment |
/feed.xml |
RSS feed |
/sitemap.xml |
Search engine sitemap |
/robots.txt |
Robots policy |
/actuator/health |
Health check |
The journal page uses htmx for search-as-you-type. The server returns the same Thymeleaf article-list fragment used by the full page render, so there is no separate JSON API to maintain.
| Env var | Default | Description |
|---|---|---|
PORT |
8080 |
HTTP port |
JOURNAL_SITE_NAME |
Systems Under Load |
Site title |
JOURNAL_SITE_DESCRIPTION |
technical journal default | SEO description |
JOURNAL_BASE_URL |
http://localhost:8080 |
Absolute base URL for canonical links, RSS, sitemap |
JOURNAL_CONTENT_DIR |
sample-content/articles |
Filesystem path to Markdown articles |
JOURNAL_SHOW_DRAFTS |
false |
Show draft articles locally |
THYMELEAF_CACHE |
true |
Template cache toggle |
docker build -t systems-under-load .
docker run --rm -p 8080:8080 \
-e JOURNAL_BASE_URL=http://localhost:8080 \
-v "$PWD/sample-content/articles:/content/articles:ro" \
systems-under-loadFor private content:
docker run --rm -p 8080:8080 \
-e JOURNAL_CONTENT_DIR=/content/articles \
-e JOURNAL_BASE_URL=https://journal.example.com \
-v /srv/systems-under-load-content/articles:/content/articles:ro \
systems-under-loadStart with these SEO-oriented posts:
- p-limit vs bulkhead
- Stop queuing doomed requests
- Protect OpenAI and Anthropic calls from request storms
- Return 503 before an Express route melts down
- Protect outbound fetch calls from slow downstream services
- Why bounded queues beat unbounded async pileups
Link each article to the relevant package README and npm page.