All posts

Where I'm heading next

My roadmap for the next year: the fundamentals underneath everything, Go and backend engineering, production engineering, AI agents and evals, and how language models work inside.

I’ve spent the last few years building across the stack: interfaces and design systems, APIs and databases, real-time features, authentication, payments, CI and AI products. This is where I’m taking that next. Not a list of new tools to collect, but a deliberate push on the things that make software hold up: the fundamentals underneath, a compiled backend language, and the engineering that keeps a system correct when things go wrong.

  1. 01

    Go & backend

    A compiled, statically typed language, learned by building a real service.

  2. 02

    Production engineering

    Taking my AI travel planner from prototype to production-grade.

  3. 03

    Agents, MCP & evals

    Real tool calling, tools other agents can use, and measured quality.

  4. 04

    LLM internals

    A small model trained from scratch, to understand the layer I build on.

Underneath all four, all year

Algorithms & data structures · Databases · HTTP & networking · Concurrency · Processes & memory · Caching & queues · Distributed failure modes · Security

The next twelve months, in order, on a continuous foundation

Underneath everything: the fundamentals

This isn’t a phase that comes first and then ends. It runs alongside every step, because the projects below keep raising the questions it answers.

  • Algorithms and data structures. Arrays and strings, hash maps, stacks and queues, linked lists, trees and graphs, heaps, recursion, breadth- and depth-first search, binary search, sorting and dynamic programming, with the time and space cost of each. A little every week, not a cram.
  • Databases. How indexes work and why a query is slow, transactions and isolation levels, migrations that don’t lock a live table, and modelling data so the schema protects it.
  • HTTP and networking. What actually happens between a request leaving the browser and a response arriving: DNS, TLS, connections, caching headers, and API design that ages well.
  • Concurrency, processes and memory. Threads, event loops and goroutines; processes and scheduling; stack and heap; allocation and garbage collection; resource ownership and cleanup (connections, pools, file descriptors); and what happens when a process dies. The knowledge behind “why is this service using 2 GB of memory?”
  • Caching, queues and distributed failure. Where to cache and how to invalidate, at-least-once delivery, and the partial failures that only show up when more than one machine is involved.
  • Security. Authentication and session design, input validation, secrets handling, and the common ways web systems get broken.

01 · Go and backend engineering

TypeScript gives me a lot of static checking, and I’ll keep using it. Go gives me a different set of constraints: static typing, native compilation, explicit error handling, and lightweight concurrency through goroutines and channels. It’s widely used for backend and infrastructure software, and it’s the language of the Cosmos SDK that Holy Mary Chain was built on.

What I’ll build: a health checker for this site, in Go. It will check the site on a schedule, record status and response times in a database, and publish the results here as the “health you can check” section the home page already promises. It’s small enough to finish and big enough to need the real things: goroutines for concurrent checks, a clean HTTP API, a schema with the right indexes, structured logging, graceful shutdown, and tests from the first commit.

02 · Production engineering

My AI travel planner works, and its hardest parts are good: a parser that renders cards while the model is still writing them, and a scoring engine that finds the dates a whole group can make. It was built as a prototype, though. This step is about making it something I’d trust with real users, and being able to explain every decision along the way.

  • Testing in layers. Unit tests for the parser and the scoring engine; integration tests against a real database and stubbed third-party APIs; end-to-end tests of the full flow in a browser.
  • Observability. Structured logs, metrics for latency and error rates, and tracing that follows one request through the API, the model call and every external search.
  • Failure handling. Timeouts and retries with backoff for every external call, so one slow provider can’t hang a whole request, and a clear answer to “what happens if this crashes halfway through?”
  • Idempotency. Committing a trip or making a reservation must be safe to retry: the same request twice should never mean two bookings.
  • Data. Real migrations instead of hand-run SQL, so every environment has the same schema; indexes chosen from actual query plans; and transactions where several writes must succeed or fail together, so a half-saved trip can’t exist.
  • Performance. Following a slow request from the latency graph to its trace, then to a profiler for CPU and memory allocation, then to the database’s query plan, until the actual bottleneck is found rather than guessed.
  • Abuse and cost. Rate limiting per user and per route, so one runaway client can’t exhaust a paid API budget or slow the service down for everyone else.
  • Authentication. Verifying a signed token on every request rather than trusting an id the client sends, so nobody can read or change someone else’s trips.
  • Shipping. CI on every change, and deploys that can be rolled back in one step, so a bad release costs minutes instead of an evening; plus a plan for what to watch right after one.
  • A design write-up. What changes when the group planner serves thousands of groups instead of a handful: caching calendar scans, moving them to background jobs, and where the bottlenecks move next.

03 · AI agents, MCP and evals

Today the planner is deliberately not an agent. Plain code calls the calendar and search APIs, and the model only writes the interface. That was the right call for speed and reliability, but it means the model can’t decide on its own that it needs one more search.

  • Real tool calling, with a cap on steps and validation on every tool result.
  • An MCP server exposing the planner’s tools (free-time search, group availability) through the Model Context Protocol, so any MCP-capable assistant can use them, not just my app.
  • Evals: a fixed set of trip requests with expected outcomes, run on every change, so a prompt or model change is measured instead of guessed.

04 · How language models work inside

Last, and deliberately the lightest. I build on top of language models every day, and I want to know what’s underneath: how text becomes tokens, what attention computes, and why the same prompt behaves differently across models. I’ll train a small GPT from scratch on one machine, change one thing at a time, and write up what each change does, so the model is never a black box in the systems I design.

Building while learning

None of this waits for the rest to finish. The fundamentals run under every project, and each step ends in something public: a service running, a test suite passing in CI, a write-up here. I’ll update this post as each one lands.