Backend Engineer
Services, data access, and the systems that keep them running.
- SQL fundamentalsWhat a SELECT actually does in execution order rather than in the order you type it, and why GROUP BY, HAVING, and WHERE are not interchangeable filters on the same data.
- Window functions, CTEs, and recursive queriesRANK vs DENSE_RANK vs ROW_NUMBER measured on real ties, LAG for period-over-period deltas without a self-join, and the recursive CTE mechanics that make a bill-of-materials query possible.
- Query optimisationSARGable predicates measured against the non-sargable rewrite that "does the same thing," why HAVING after GROUP BY costs more than WHERE before it, and reading a plan for where the actual cost is hiding.
- Data ingestion and change data captureBatch versus streaming as a latency-and-cost trade, why polling for changes misses deletes and intermediate states, and what a CDC connector reading the transaction log actually captures that a timestamp column can't.
- PostgreSQL in productionWhat EXPLAIN actually says once you know where the loops divide, why VACUUM is not optional, and how a table can be 500,000 rows and still choose to scan every one of them — correctly.
- Indexes, joins, and reading a query planWhy a LEFT JOIN can return more rows than either table has, how the four join types relate as sets, and where the selectivity crossover actually sits — measured, not assumed.
- MongoDBEmbed or reference, why a document's growth pattern decides the schema more than the query pattern does, and the write-amplification bug that only appears once an array stops being small.
- CosmosDB and partition keysWhy the best-distributing partition key is often the wrong one, how RU/s gets divided among partitions you don't control, and the migration you can't avoid once a key choice turns out wrong.
- NoSQL data modellingModel by access pattern, not by entity — why a NoSQL schema starts from the queries you'll run rather than the things you're storing, and what breaks when a new query arrives that the model didn't anticipate.
- pgvectorVector search inside Postgres — what you gain by not standing up a second datastore, what HNSW costs in index build time and memory, and when the "one less service" argument stops being the right trade.
- Vector databases comparedPinecone, Qdrant, and Weaviate implement the same ANN algorithms pgvector does — what actually differs is operations, filtering, and how each one degrades at the corpus size pgvector stops being comfortable.
- File formats and object storageRow-oriented versus column-oriented storage, why Parquet reads 10x less data for an analytical query than CSV, and what Delta and Iceberg add on top that a folder of Parquet files can't do alone.
- Cloud fundamentals — regions, IAM, and the shared responsibility modelThe vocabulary every cloud provider assumes you already have: regions and availability zones as a blast-radius decision, IAM as default-deny, and the shared responsibility line that determines who gets paged for a breach.
- AWS — the services that show up in most stacksEC2, S3, RDS, Lambda and IAM roles as the five services almost every AWS architecture is built from, and the mental model — instance vs managed service vs event-driven function — that generalizes to any provider.
- Azure — resource groups, Entra ID, and Cloud Run's closest cousinWhat's genuinely different about Azure once you already know AWS — resource groups as a real management unit rather than a tagging convention, and Entra ID's tenant-first identity model.
- GCP — projects, IAM inheritance, and Cloud RunWhat's genuinely different about GCP once you already know AWS and Azure — the project hierarchy IAM inherits down through, and Cloud Run's per-request billing as a distinct point between Lambda and a always-on container.
- Containers — layers, caching, and what isolation actually meansA container is a process, not a VM — namespaces and cgroups instead of a hypervisor, and image layers as a cache Docker computes from, which is why Dockerfile instruction order is a real performance decision.
- CI/CD — the pipeline as the only path to productionWhy caching only helps when it's actually restored, what a deployment strategy trades off (blue-green vs rolling vs canary), and the discipline that makes a pipeline trustworthy — nothing reaches production except through it.
- Observability — logs, metrics, traces, and what each can't tell youThree signal types that answer different questions, why none of them substitutes for the others, and SLOs as the mechanism that turns "is it slow" into a number someone can page on.
- Cloud security — where incidents actually come fromAlmost no real cloud security incident is the provider's infrastructure failing — it's a misconfiguration on the customer's side of the shared responsibility line: a public bucket, an over-broad role, a leaked long-lived credential.
- How LLMs workThe mental model an engineer actually needs — next-token prediction, attention, context as the only state, and which observed behaviours follow from the architecture rather than from a bug.
- Tokens and samplingWhat temperature, top-p and top-k actually do to a probability distribution, why they interact, and why "set temperature to 0 for reproducibility" is only half true.
- PromptingWhat actually moves the needle — structure, examples, and output contracts — and how to tell a prompt problem from a retrieval problem before spending a week on the wrong one.
- Context engineeringThe context window is a budget, not a container. How to decide what goes in it, in what order, and what to do when the conversation outgrows it.
- HallucinationsWhy fabrication is a property of the training objective rather than a bug, what actually reduces it, and how to build a system that fails loudly instead of confidently.
- EvaluationHow to know whether a change made things better — building a golden set, choosing metrics that survive contact with production, and using an LLM judge without fooling yourself.
- EmbeddingsHow text becomes a vector, why similarity is an angle rather than a distance, and the failure modes that make a retrieval system quietly return the wrong documents.
- Vector searchApproximate nearest neighbour search — what HNSW actually trades away, why recall is a dial rather than a property, and the memory cliff that turns a fast index into a slow one.
- RAGRetrieval-augmented generation as a pipeline of separately-measurable stages — and why debugging it end-to-end is the most expensive mistake in the field.
- Chunking and retrievalWhy chunk size is not a knob you can reason about monotonically, what overlap actually buys, and how an answer that is provably in your corpus becomes unretrievable.
- Reranking and hybrid searchWhy embeddings are bad at identifiers, how to fuse two rankings whose scores are not comparable, and where a cross-encoder earns its latency.
- Tool useFunction calling as an interface design problem — why the schema is the prompt, what a tool should return, and the authorisation mistake that turns a helpful agent into a confused deputy.
- AgentsThe think-act-observe loop, the four ways it fails in production, and why the controls around the loop matter more than the model inside it.
- Agent orchestrationMulti-agent systems — when splitting genuinely helps, why context does not cross agent boundaries for free, and the coordination costs nobody budgets for.
- LLMOpsRunning LLM features in production — what to log when output is non-deterministic, where the cost actually goes, and how to ship a model upgrade without breaking things silently.
- GuardrailsPrompt injection has no clean fix, and understanding why tells you where the real controls go — output validation, capability limits, and authorisation that never trusts the model.
- Knowledge graphsWhen entities and relationships beat embeddings — multi-hop questions, aggregation, and the extraction cost that decides whether a graph is worth building.
- LLM gateway — routing, fallback, and cost attribution across providersA gateway is the one place that knows every provider's health, every tenant's spend, and which request should fail over to what — pulling routing logic out of application code before the second provider makes it unavoidable.
- Prompt versioning — treating a prompt as a deployable artefactA prompt edit that quietly regresses quality is a deploy with no diff, no review, and no rollback unless prompts are versioned, tested, and released like code — not typed into a string constant and shipped.
- Node Backend FrameworksExpress and Fastify don't change the concurrency model underneath them — they change what runs on top of it. What saturates first is still the event loop, and the framework just decides how easy that is to hit by accident.
- Dependency-Injected Backend FrameworksNestJS and its relatives add a request lifecycle and a provider scope model on top of the same event loop — which means the same blocking-handler failure now hides behind a decorator, and a new failure (shared request-scoped state) becomes possible that plain Express never had.
- Python Backend Runtimes — WSGI and ASGIWSGI gets its concurrency from OS processes; ASGI gets it from an event loop borrowed straight from the same model Node uses. They fail in opposite ways, and a synchronous call in the wrong one collapses throughput exactly like a blocking Express handler does.
- REST APIsThe parts of REST that only bite you past the first CRUD endpoint — caching headers, content negotiation, versioning, and the hypermedia question everyone skips.
- Graph Query APIsGraphQL solves over-fetching by letting the client shape the query — which means the client now also shapes the cost, and an unbounded query is an unbounded bill.
- Validation and SerializationThe server is the trust boundary, not the browser — schema validation and serialization are where an attacker-controlled string either becomes a typed value or reaches your database as-is.
- Realtime APIsWebSockets and Server-Sent Events remove polling and hand you reconnection, backpressure, and fan-out instead — and the question that actually matters is what happens to a message sent while the client was gone.
- Authentication & AuthorizationTwo different questions bolted together in most codebases — who you are and what you can do — and what revoking access actually costs under a session, a JWT, and OAuth.
- API SecurityDefensive coverage of the vulnerabilities that actually show up in backend APIs — every recommendation stated as a threat, a mitigation, and a way to verify it holds.
- Background JobsWhat moves work out of the request path — scheduling, idempotent execution, and catching the job that fails silently instead of loudly.
- Service DecompositionWhat splitting a monolith into services actually buys, argued honestly in both directions — including the concrete conditions under which not splitting is the better call.
- Gateway & Load BalancingHow each load-balancing algorithm actually behaves once backends stop being identical, and the health-check condition that decides when a sick instance gets taken out of rotation.
- Domain-Driven DesignWhy a boundary drawn around a business capability outlives one drawn around a technical layer, and how to find it by watching where the language changes.
- Event-Driven ArchitectureWhat a service gives up when a synchronous call becomes an event it fires and forgets — and the specific things you have to build back to recover the traceability that call had for free.
- Resilience PatternsWhy a retry without a budget makes an overloaded dependency worse, and the bound — timeout, retry budget, circuit breaker — that turns a retry back into a fix instead of an amplifier.
- Multi-TenancyThe isolation guarantee at each layer of a shared system, why the data layer is a correctness and trust problem before it's a cost one, and what one noisy tenant does to everyone sharing the system with them.
- Repository Layout — Monorepo vs PolyrepoThe trade-off repository layout actually encodes — coupling cost against coordination cost — derived without recommending a specific build tool.
- The incident method — why fixing is step sevenDetect, isolate, mitigate, investigate, fix, prevent — the order production incidents actually get resolved in, and why jumping straight to a fix is the single most common mistake under pressure.
- Reading the symptoms — CPU, latency, and what each combination rules outLow CPU and high latency means waiting, not working — measured from a real service genuinely faulted six different ways, not asserted. The single fact this whole section is built around.
- Linux production debugging — top, free, ss, dmesg, and what they actually meanReal captured Linux command output from a genuinely loaded container — what every column in top means, why free's "used" number lies by omission, and the kernel's own record of an OOM kill in dmesg.
- Kubernetes production debugging — pod states, real and brokenImagePullBackOff, CrashLoopBackOff, Pending, OOMKilled — captured from four genuinely broken pods on a real kind cluster, with the exact kubectl describe events that explain each one.
- Distributed tracing — spans, context propagation, and where the time actually wentA trace is a tree of spans reconstructing one request across every service it touched. Drag one span's duration and watch why optimising the wrong one is arithmetically irrelevant.
- Cascading failures — how one slow dependency becomes a total outageA downstream 429 turned into a 5x amplification, captured for real — bulkheads, backpressure, and load shedding as the three mechanisms that stop one failure from becoming every failure.
- Capacity estimation — the back-of-the-envelope math that catches a bad plan earlyQPS, storage, bandwidth, and Little's Law worked as real arithmetic, not asserted — the estimate that tells you a plan won't work before you've built anything.
- AI incident catalogue — the failure modes unique to LLM systemsPrompt growth silently turning into a latency and cost regression, a retry loop between two agents that never terminates, a retrieval pipeline that went quiet — the incident shapes that don't show up in a normal backend's playbook.