architecture
Decomposition, boundaries and deciding what should not be built.
-
The Whole Estate in One Article: How Every Layer Fits Together
Each layer of a self-hosted platform is well documented in isolation, but nothing describes the order they have to arrive in or why getting that order wrong fails weeks later rather than immediately. This article walks the full dependency chain from bare metal to self-hosted model serving, and demonstrates the ordering discipline with a runnable Compose file.
-
Documentation as a Repository: Publishing a Wiki.js Site from Reviewed Markdown
Documentation kept in a hosted wiki drifts silently, because nothing forces a reviewer to look at it when the code it describes changes. Treating docs as a repository, reviewed through the same pull requests as code, turns that silence into a diff someone has to look at. This covers what changes when documentation moves into git — as it does in the open-source OpenTaberna project — with a runnable Wiki.js setup and a CI check that fails a pull request when source changes without its docs.
-
When Microservice Decomposition Is the Wrong Default
Splitting a system into microservices before there is an actual scaling, ownership or isolation reason costs real coordination: versioned contracts, retries, and version-skew windows that a single process never has. This article builds the same three responsibilities as a modular monolith with an enforced internal boundary, so a later real split is mechanical rather than a rewrite.
-
Self-Hosted Identity with Keycloak: Central Offboarding and Forward Auth
Every internal service wants its own user database, and each one becomes a password nobody audits and an account that outlives the employment. Running a central identity provider turns offboarding into one action instead of a checklist, and this walks through why, with a runnable Keycloak setup that proves a single disable call locks a user out at the token endpoint, plus a forward-auth proxy protecting an application with no login of its own.
-
An Entity Graph as the Data Model for a Heterogeneous Estate
Hosts, volumes, links and alerts have genuinely different shapes, but an observability console still needs one model that can answer "what does this depend on" and "what is this node's health" without a type-specific code path for every kind of thing. This walks through an entity-graph model in Go that gets there, with a complete runnable implementation.
-
The Transactional Outbox: Never Losing a Job You Already Committed
Committing a database change and then enqueueing a job as two separate steps leaves a gap in which the change is permanent but nothing ever runs the job and nothing notices. This works through the transactional outbox pattern and gives a complete, runnable Postgres, Redis Streams and Python implementation that survives a crash at any point in that gap.
-
Layering an Angular Application: core, shared, features and the Rule That Holds
Splitting an Angular application into core, shared and feature folders is common advice, but without something enforcing the dependency direction between them an API call ends up inside a presentational component the first time someone is in a hurry. This article states the one rule that actually needs to hold, and enforces it with a lint check a reader can run and watch fail.
-
Embedding a Built Frontend Into a Go Binary with go:embed
Serving a single-page application from a separate static file server next to its API is two processes that have to be deployed and versioned together but usually are not. This article embeds a built frontend directly into the Go binary that also serves the API, with a complete example including the single-page-application routing fallback that this approach needs to get right.
-
Serving Several Local Models on One GPU with On-Demand Loading
One GPU can hold one large model at a time, but different tasks want different models and restarting a server by hand does not scale past a handful of requests. This describes a proxy that loads a model on first request, keeps it warm, and swaps it out for the next one automatically.
-
One Dashboard on Five Unrelated Backends: Normalising at the Boundary
A dashboard that calls a ticketing system and a CI system directly inherits their different pagination styles, error shapes and auth schemes. This article builds a FastAPI backend-for-frontend that normalises both into one schema, degrades gracefully when an upstream is down, and shows how to test each adapter without touching a real upstream.
-
Modelling an Order Lifecycle as an Explicit State Machine
When any code path can set order.status to any value, an invalid transition is caught only by whoever remembers to check for it, and eventually nobody does. This walks through modelling the lifecycle as an explicit state machine that rejects illegal transitions by construction, with a complete, tested implementation.
-
UUID Case Normalization as a Recurring Cross-Service Bug
An uppercase UUID from one service and a lowercase one from another look identical to a person and different to a dict, a cache, or a database index, which turns one entity into two without raising an error. Here is a minimal reproduction of the bug and a boundary-normalisation fix with a test that keeps it fixed.
-
Docker Compose or Kubernetes: What the Control Loop Actually Buys You
Kubernetes is usually sold as the next step up from Docker Compose, which makes it sound like a bigger version of what you already have. It is a trade: you hand over control of where things run in exchange for a system that keeps working when a machine dies. This works through what that trade actually costs, with a runnable example showing the control loop doing its job and a Compose stack that cannot do the same thing.
-
A Single-Writer Rule for Configuration Held in Redis
When several services can write the same Redis key, a read after a write can return someone else's value and nobody owns the truth. This walks through a lease-and-version pattern that makes one process the only writer, with a complete Python example a reader can run on a laptop.
-
Chaining Single-Purpose Redis Consumers into a Processing Pipeline
A single service that detects, tracks, calibrates and computes statistics over the same data becomes impossible to test or scale in isolation. This splits that service into four single-purpose consumers chained through Redis Streams, using consumer groups for at-least-once delivery and XAUTOCLAIM for crash recovery, in a complete example a reader can run against a local Redis container.
-
Tracking Moving Objects with Redis Sorted Sets and an Atomic Lua Tick
Tracking several objects moving along a line at once needs two guarantees at every step: a consistent view of where everything currently is, and a clean way to detect what has left the tracked range. This builds that on a Redis sorted set with a single atomic Lua script, and shows both guarantees holding under a real docker-based Redis instance.
-
A Python CLI That Scaffolds a Project Structure You Actually Want
Starting a new service usually means recreating the same src layout, Dockerfile and ignore rules by hand, or copying them from whichever previous project is open in another tab, drifting a little further from a consistent shape each time. This builds a small, dependency-free scaffolding CLI that generates a project from a fixed template, and a test that checks the result is actually valid.
-
A Feature-Module Layout for a FastAPI Application That Keeps Growing
A FastAPI project that starts as one main.py and one routers.py works fine for the first few endpoints, then becomes a file everyone edits and nobody owns. This lays out a feature-module structure where each feature carries its own router, schemas and service code, with a complete runnable example and a test proving a new feature needs no change to existing files.