Intent before change
The architecture is written down before any code is committed, including the options we rejected.
Software consultancy
A small consultancy for web applications, AI systems, and data platforms. We take a few engagements at a time, and we hand back code your own engineers can own.
Services
We take engagements end to end: the architecture, the build, the tests, and the handover. Usually two at a time, so each one gets the attention the problem actually needs.
Product-grade web applications, from the first prototype to the system that carries real traffic.
We design the data model, build the API and the interface, and put the whole thing behind tests and CI. You get a codebase your own engineers can read, extend, and own.
Across every layer
Applied AI that survives contact with production: evaluated, observable, and costed.
Most AI projects stall between the demo and the deployment. We focus on the part that decides the outcome: retrieval quality, evaluation harnesses, guardrails, latency, and unit cost.
The evaluation loop
Pipelines and warehouses that stay correct as the volume and the schema move.
We build the ingestion, transformation, and storage layer that everything else depends on, then make it testable so a schema change fails loudly in CI instead of quietly in a dashboard.
What keeps it correct
The name
A write-ahead log records the change before it touches the data, so the system can always recover. We work the same way: the intent is written down first, the change comes second, and the record survives us.
The architecture is written down before any code is committed, including the options we rejected.
Every change arrives as a pull request with tests and CI, so nothing lands that cannot be backed out.
Documentation and a runbook ship with the code. If we vanish, the log is enough to keep going.
Work
Roughly 39 systems across tenancy, storage internals, platform engineering, and applied AI. Most started as a problem we hit and could not buy a good answer to.
Tenancy & identity
Systems that know whose data this is
A product that serves one customer per database is simple. One that serves ten thousand is a different system. Tenancy has two halves: a data plane that decides which shard holds a customer’s rows, and a control plane that knows who the customer is, what they may do, and what they owe. Most teams build neither, so tenant state ends up scattered across an auth provider, a billing dashboard, and a spreadsheet.
A wire-protocol proxy that clients connect to as if it were Postgres. It reads tenant identity out of the query, routes to the shard that owns those rows, fans out and merges when the key is absent, and coordinates commit across shards with best-effort rollback. Wire adapters stay separate from the routing core, so other databases can plug in later.
One service that owns the whole organisation lifecycle, covering orgs, their users, authorisation, and billing, so tenant state stops living in three vendor dashboards. Merchants configure policy centrally and enforce it inside their own backend.
Configure an external provider once, then fetch a valid token for it over a plain REST call from any application, indefinitely. It removes per-project OAuth flows, refresh logic, and secret storage from every downstream service.
Permissions extracted into a library so access rules stop being re-implemented, slightly differently, in every service that needs them.
Shared user management built because rewriting it per project stopped being defensible: session tokens, JWT, and OAuth first, with a path through directory protocols, MFA, and time-bounded access.
A production-grade Go starting point that stitches the full stack together without a heavyweight framework: JWT auth, role-based access control, Stripe billing across plan tiers with webhook handling, account-isolated projects, migrations, and a generated client SDK.
Define a Go struct, call save or find, and the adapter maps it onto Postgres, MySQL, SQLite, MongoDB, or ClickHouse. It trades SQL expressiveness for reaching persistence fast.
An open-source alternative to the dominant form SaaS: Postgres, OAuth sign-in, and a Docker Compose stack that comes up from a single env file.
Storage internals
The layer below the query
When a database becomes the bottleneck, the fix usually sits below the query layer, in the replication path, the snapshot mechanism, the lock granularity, or the cache in front of it. We have built these pieces from scratch rather than configured them, in Go and in Rust, because that is what it takes to reason about them under load.
Consensus and log replication implemented from first principles, built to close the gap between understanding Raft and actually shipping it. A coordinator drives independently runnable managers for WAL generation, log replication, and leader election, exercised against a three-node cluster in the test suite.
Snapshot semantics for an in-memory store with zero additional memory cost until data is mutated and minimal impact on read latency. A snapshot buffer layers over shard threads, with simultaneous snapshot instances and cross-shard restore, and no dependence on an OS-level fork.
Move a collection between clusters with negligible downtime: bulk-copy what exists, record the start timestamp, then tail the oplog from that point until lag closes. A self-contained path off a managed migration service and its lock-in.
An in-memory database in Go that extends Redis commands with query subscriptions. Clients subscribe to a SQL-like query and receive a push when the result changes, rather than polling. Drop-in compatible with existing Redis tooling.
Work inside a from-scratch Rust rewrite of SQLite: storage engine territory, in a systems language with a different set of guarantees to Go.
A Go implementation of the hash table design behind Dragonfly, written to understand its memory layout and probe behaviour rather than to read about them.
Sits between the edge and the application server with a per-request in-memory response cache, invalidation APIs, and per-route skip rules for endpoints that must always reach the backend. It cuts backend load with no application-level change.
Striped locks across 1024 slots with FNV-32a key hashing, benchmarked against a single global mutex under contention. Plus a memory pool, and a ring buffer that flushes batches on message count, rollover, or time since the last flush.
Benchmarks run and written up rather than assumed: protobuf against JSON across four compressors and eleven payload shapes, goroutine spawn cost against pre-allocated worker pools, interface dispatch against direct calls, and copy-by-value against pointer semantics.
Platform & runtimes
Getting workloads to run, on time, in order
Most teams do not need Kubernetes. They need a repeatable way to put a container on a machine, give it a database, and find out when it dies. Once the workloads run, something still has to schedule them, move events between them, and hold the pipeline together when a stage fails. That machinery is where delivery speed is actually won or lost.
Register SSH-reachable nodes, define an app, and deploy Docker containers to it, with no Kubernetes required. It provisions managed Postgres, Redis, Kafka, and Prometheus with Grafana, injects the connection details into linked services automatically, redeploys on a container-registry webhook, streams logs live, and runs a background health reconciliation loop.
Terraform modules for AWS and DigitalOcean: VPCs and networking, instances, object storage, managed Kubernetes, and a Kafka node, with deployable manifests kept separate from the reusable modules.
A custom resource and its controller on kubebuilder, covering both the standard reconciler pattern and external event sourcing, where events from outside the cluster enter the reconcile loop through a channel-based source.
A small function-as-a-service runtime, and a worker pool that sizes itself against the arriving work instead of spawning a goroutine per task.
Schedules hold triggers; triggers fire jobs built from templates with conditional logic and connector integrations. Absolute dates, relative offsets, and recurring intervals, expressed in a scheduling DSL that supports genuine pipelining. A structured replacement for a drawer full of crontabs.
Declare a source topic, a transformation, and a destination topic or external system, then chain the stages. Streaming pipeline logic in Go, for teams that want it without the JVM footprint of Kafka Streams or ksqlDB.
Composable stage definitions over Kafka with reliable delivery semantics, for pipelines where a dropped or duplicated event is a correctness problem rather than a metric.
A broker WebSocket client with binary protocol decoding behind a callback-handler interface, benchmarked for latency across 100k ticks. On top of it, an order management system covering placement, modification, and lifecycle tracking, and a tick-processing engine that runs rule-based strategies.
Every major index, sector, and currency-adjusted return in one view, with valuation and macro overlays and capital-flow tracking, so the question of where the next unit of capital should go is answerable at a glance instead of out of a filing.
A minimal SFU handling multiple simultaneous producers and consumers, with the full signalling lifecycle: RTP capability negotiation, transport creation, and the producer and consumer handshakes. Conferencing infrastructure without a managed service.
A Gin-based framework that exposes Go structs as CRUD endpoints with Rails-style lifecycle hooks around save and action, plus a config-driven parallel HTTP load driver that exercises an API without bespoke client code.
AI & agents
Agents that survive contact with production
Agents are easy to demo and hard to run. The engineering sits in the plumbing around the model: routing events in from the systems people already use, keeping sessions coherent across turns, deciding what runs locally so the bill stays near zero, and making the output reproducible enough to trust twice.
Bridges Telegram and Linear into a coding agent running locally. It fans incoming events from every configured provider into a single channel, invokes the agent per message, streams results back in chunks, and holds session IDs so multi-turn conversations stay coherent. Project bindings hot-reload from config every few seconds, with no restart.
A maintained library of agent skills and workflows: review, planning, release, and repository conventions encoded once, so an agent applies them consistently instead of being briefed from scratch each session.
Any technical video in, animated overlays out. ffmpeg extracts the audio, a local Whisper model transcribes it with timestamps, a model detects technical scenes and writes the slides, Remotion renders them with spring animations and line-by-line code reveals, and ffmpeg composes the result. Keeping speech-to-text local holds API cost near zero.
Analyses recorded play, tracks progress across sessions, and generates personalised drills and feedback rather than a single post-hoc score.
Running open models on local hardware to establish where a hosted API earns its latency and cost, and where it does not.
Also shipped
Tools and products that did not need a section of their own.
Merges the five best-known problem lists into roughly 326 unique problems, reorganised by 20 solution patterns instead of by data structure.
A lightweight product built around a clean, product-oriented architecture rather than a framework default.
People, projects, and responsibilities held in one shared workspace instead of three disconnected tools.
Give it a file and an object name; it traces every transitive dependency and copies the closure into a mirrored source tree with the import hierarchy intact.
Normalises an arbitrary struct into a name and an attribute map, with optional snake_case keys, for schema-less serialisation and structured logging.
Post a set of paths and key-value filters, get matching rows back. Makes flat data queryable without standing up a database.
Approach
Short feedback loops, working software early, and no black boxes. You see the repository from day one.
We start with the problem, not the technology. One or two calls to understand the constraints, the deadline, and what success means.
We write the architecture down before we write code: the data model, the interfaces, the trade-offs we chose and the ones we rejected.
Weekly increments you can run yourself. Every change arrives through a pull request, with tests and CI attached.
Load, failure modes, observability, and cost. This is the step most projects skip, and the one that decides whether the system holds.
Documentation, a runbook, and time with your engineers. The goal is that you do not need us afterwards.
Not a phase at the end. A change without a test is not finished.
Your repository, your accounts, your infrastructure. No lock-in to us.
If an approach is not working, you hear it early, not at the deadline.
About
The core team has spent its career on systems where correctness and scale were not optional, previously at:
Databases, payments infrastructure, virtualisation, and platform engineering. The kind of work where an outage has a postmortem and a schema change has a migration plan.
A write-ahead log records the change before it is applied, so the system can always recover its state. It is also the reason our engagements leave documentation behind. If the only record of a decision is in someone's head, the system is one resignation away from being unmaintainable.
Fit
Being honest about that early saves everyone a quarter.
None of the second column is a lesser kind of work. It is simply work where our particular experience adds cost rather than value, and we would rather say so than bill for it.
Contact
Email is the fastest route. A paragraph is enough to start. We read every enquiry ourselves, and we answer either way.
We answer every genuine enquiry, including the ones we turn down. If we are not the right team, we will say so and suggest who might be.