Two users withdraw money from the same account at exactly the same moment. Your system processes both requests, your database balance goes negative, and you wake up to an incident report. Sound familiar?
What if you could combine Redis’s millisecond response times with PostgreSQL’s bulletproof consistency? This dual-layer locking pattern does exactly that, giving you both speed and safety.
In this post, we’ll explore a pattern that combines Redis’s speed with PostgreSQL’s reliability to prevent race conditions at scale.
In my career, I have realised that the best companies celebrate each success in a genuine, informal way. They avoid contrived rituals that can feel like an artificial façade.
In these organisations, individuals willingly help colleagues reach shared goals.
Take Janet from my local Parkrun, for example.
Although she does not compete, she choose to find the time to cheer on each participant to achieve their goals… even on cold Saturday mornings.
MCP standardises how AI applications communicate with external systems using JSON‑RPC 2.0 over stateful, bidirectional connections. Unlike standard JSON‑RPC, which treats every request independently, MCP augments the protocol by embedding session tokens and context IDs into each message.
This enhancement provides state, enabling advanced, multi‑step interactions and dynamic module loading at runtime. Such a stateful design is essential for modern, agile AI systems.
Imagine an AI‑powered payments system that dynamically integrates a new fraud detection module during operation. MCP allows the system to load this module on the fly without a full redeployment, provided the server supports dynamic module loading.
In this post, we’ll explore the MCP protocol, its core components, and how it compares to traditional REST and GraphQL APIs.
AI applications are shifting from monolithic large language models to modular, multi-agent systems—a transformation that enhances performance, flexibility, and maintainability.
In my talk about AI Agents last September, I said AI agents would become increasingly popular. Today, we see this shift happening across industries. By breaking down complex tasks into specialised components, engineers can design smarter, more scalable AI workflows.
Analogy: Think of multi-agent systems like a well-coordinated orchestra. Each musician (agent) has a specific role, and together, they create a harmonious performance. In software, this means dividing complex problems into manageable, specialised parts that work in concert.
In this guide, we’ll explore four key multi-agent patterns, using travel booking as an example. You’ll learn how to choose the right pattern for your application, implementation strategies, and error-handling techniques to build robust multi-agent AI systems.
Agentic systems, where multiple AI agents collaborate through decision-making and handoffs, shine in specific scenarios but add operational complexity.
In this post, we’ll explore the scenarios where agentic systems are most effective and the challenges you may face when using them.
Imagine: you run a busy online shop where every moment matters.
Your customers expect the fastest page loads, yet you still require dependable analytics to understand user behaviour and drive informed business decisions.
Relying solely on client-side tracking with tools like PostHog can be fraught with challenges. Many users have ad blockers or privacy extensions that prevent tracking scripts from running, and even when these scripts do execute, they can slow down page rendering and affect conversion rates.
In this post I’ll go over how you can use Next.js 15’s next/after API to handle analytics and events without slowing down your site.
Getting event names right in event-driven architecture and Domain-Driven Design (DDD) is essential for clarity, consistency, and scalability. A key decision is using singular or plural terms in event names.
Here’s how I approach it, with examples and reasoning to help you make the best choice.
Building a TypeScript library that is both maintainable and optimised for modern bundlers requires careful consideration of exporting functions, types, and other constructs from your modules.
With several strategies available, from wildcard re-exports to namespaced exports, explicitly named re-exports have emerged as the clear winner. This post explores the alternatives with examples based on an order management system.
We’ll discuss the benefits of exporting types, how to organise multiple entry routes (such as in /src/orders and /src/users), and review the necessary TypeScript configuration options (such as verbatimModuleSyntax) and package.json tweaks. Additionally, we’ll explain how this approach helps prevent circular dependency challenges by enforcing a clear dependency graph.
I love Next.js. It’s been my framework of choice since my first tiny contribution in 2017.
Yesterday, I joined a team discussion about which React framework to choose. In 2025, that decision is harder than ever, with so many excellent alternatives available.
While Next.js is recommended by React themselves, and is a very popular choice, the not-so-good parts are often left out on platforms like LinkedIn and YouTube.
I plan to write about the good things about Next.js 15 in the future, but here are some challenges I still face using it today.
31 Jan 2025Designing a payment system is like any other software solution I’ve worked on.
At first, it appears straightforward, but real-world factors like currency conversions, fees, payee validations and external APIs quickly add complexity.Read More →