2001 - The Beginning
I wrote my first commercial code in 2001, joining Action Information Management fresh out of
Southampton with a Computer Science degree and a dissertation on IPv6 — research that contributed
to the broader IPv6 work at the university. I started in C++, building core components of journey
planning technology, and quickly introduced the business to Java, XML, and modern web
development.
Those early years taught me something that's stayed with me: transport software doesn't forgive
sloppy thinking. The data is messy. The standards are fragmented - NaPTAN, ATCO, TransXChange,
GTFS, SIRI - each with their own assumptions and edge cases. If your system doesn't handle
them gracefully, people miss buses. It sounds mundane until you realise the scale: millions of
journey plans served every month, across multiple regions and operators, with the expectation that
the answer arrives in milliseconds. That complexity is what first drew me towards domain-driven
thinking - modelling the transport domain carefully, establishing clear boundaries between
contexts, and building a ubiquitous language that the code, the data, and the team all shared.
2006 - Senior Engineer
I progressed through the ranks - junior to mid, mid to senior - and the company evolved
too, eventually becoming part of Trapeze Group. By 2006 I was operating as a Senior Software
Engineer, and the work had shifted to Java and Spring. I was driving the adoption of practices that
felt cutting-edge at the time: test-driven development, continuous integration, pair programming. I
took on a lead role in defining stories, working with QA and stakeholders on acceptance criteria,
and mentoring developers ranging from graduate hires to outsource teams.
2017 - Architecture
The bigger transition came when I moved into architecture. It wasn't a sudden shift - it rarely
is. I'd been the person making the technical calls for years before the title caught up. When it
did, the scope expanded. I became responsible for the full stack: Java and Spring Boot on the
backend, .NET Core for specific platform components, Angular and Ionic on the front end, Azure for
cloud infrastructure. But the scope also expanded beyond code into the cross-cutting concerns that
define real architecture - security, data protection, disaster recovery, accessibility,
capacity planning, and the governance of how decisions get made and documented. The products I
architect serve operators across multiple UK regions and beyond.
The architecture style varies deliberately by product and context. Some products are well-served by a
layered monolithic design — clean separation of concerns, dependency injection throughout,
repository patterns for data access, but deployed as a coherent unit. Others have evolved towards
more distributed designs: event-driven messaging via queues, CQRS where read and write models have
materially different requirements, and API gateway patterns to manage external integration. I've
applied the Strangler Fig pattern more than once to progressively modernise legacy components
without the risk and disruption of a rewrite. The thread that connects all of this is pragmatism:
choosing the right architectural style for the actual problem, not the one that looks best on a
whiteboard.
One project that captures how I work is the gazetteer search engine. The gazetteer is at the heart of
any journey planning system - it's what turns a user's typed query into a usable location, and
it's also used internally whenever the system needs to resolve related data. The legacy
implementation was a bottleneck. I evaluated the options - Elasticsearch (powerful but
operationally heavy for this use case), database-native full-text search (insufficient ranking
control), off-the-shelf geocoding services (too generic for UK transport data). The conclusion was
that a bespoke Apache Lucene implementation would give us the control we needed. I engineered it
down to around 4 millisecond lookup times with significantly improved result ranking. That's
the kind of work I find most satisfying: understanding a problem deeply enough to know when the
standard answer isn't the right one.
Along the way, I've also been the person who built the engineering culture around the code. I
introduced CI/CD pipelines — first with Bamboo and BitBucket, later migrating to Azure DevOps —
implemented static analysis with SonarQube, stood up private Docker registries and NuGet/NPM
repositories, and introduced feature flags for progressive rollout of changes. I've delivered
internal training courses on Angular, Ionic, SOLID principles, dependency injection, and secure
development practices. I've led teams of varying sizes, managed outsource partnerships, run code
reviews, and been a key part of the hiring process.
Present - Chief Architect
Today, my role spans product architecture, technology roadmapping, vendor evaluation, and the
cross-cutting concerns that hold everything together. I contribute to long-term technical strategy,
conduct architecture reviews across product lines, help identify and prioritise technical debt,
influence cloud spend, and present technical direction to senior leadership. I work across multiple
markets and products as part of a wider team, helping to shape the standards and governance that
give teams the framework to make good decisions autonomously. What defines this journey isn't any
single technology or pattern. It's the combination of depth and breadth, built over twenty five
years of staying close enough to the code to make honest architectural decisions, and close enough
to the business to make relevant ones.