Price. Price. Price. Insurance has become a commodity product, something to be packaged up and have a price tag slapped on it. At least that's the perception from the outside looking in.
From the inside, that process of packaging up is more challenging than it appears on first glance. Commercial fleet in particular is more nuanced, needing to meet the needs of a London Uber driver, whilst also working for a haulier driving thousands of miles up and down the UK for some of Britain's biggest retailers.
As Flock has grown, meeting these needs became more challenging as our technology, teams (and frankly our brains) started to strain trying to comprehend how to offer these neatly packaged products to customers in a seamless way.
The instinct is to treat that as a tradeoff. Move fast with a rigid one-size-fits-all product, or go deep and hand-build each one. This post is about why we stopped accepting that choice. The way out was a joint technical and product decision about who owns a change.
Making a mess (but intentionally)
Starting out, we had two bad options:
- Premature codification: try to bake every variation into the platform, end up with rigid logic that doesn't survive contact with the next piece of feedback.
- Snowflake sprawl: bespoke agreements, one-off rules, side processes, knowledge trapped in people's heads. Works until it doesn't.
Mixing and matching these options helped the business grow early doors, keeping the majority of our customers happy. On the surface everything appeared normal.
Back in 2002, Joel Spolsky wrote about the iceberg secret: customers judge software by its user interface, which is a small fraction of the work. Show a non-programmer a polished screen and they'll assume you're nearly finished, because everything holding it up is invisible to them.
Our iceberg is a little different. Customers don't see our configuration or our services. They see how easy it is to change their fleet, the great support they received over the phone, and the wizzy dashboards explaining this year's rebate. Underneath that sat the cost of delivering it: manual processes, single points of failure, and a cost of change that climbed with every bespoke agreement we signed.
Visible to customers
Below the surface
After years of operating this way, the cost of this was growing. That mess had started to constrain or even completely halt our speed to market, preventing us from bringing value to our customers.
The Spectrum of Solutions People Reach For
Managing this type of complexity at scale is not a new problem, with both enterprise solutions and startups providing a spectrum of options to choose from.
Whilst there was a temptation to find agility and speed in allowing non-technical users to build and manage product configurations, that path simply isn't right for our use-case. However, there are risks with the configuration as code path.
Mike Hadlow drew the same problem as a clock rather than a line. In the configuration complexity clock each step externalises a little more of the logic, and you can see how gradually the complexity of the framework grows into a product to maintain in its own right.
Where We Landed: Configuration as Code and Composable Behaviours
For our use-case we picked a mix of declarative product configuration combined with modularised code units. If you can't tell by now, we love a special snowflake solution.
We deliberately didn't build a language. There's no bespoke syntax and no parser to maintain - a product is typed configuration in the same language as everything else, so the compiler is what tells us when a product no longer makes sense. That's a better guardrail than anything we'd have written ourselves.
The configuration is the source of truth for what a product is and does. What documents it has, what questions we ask, and who is allowed to change which answer once the policy is live:
Those two blocks are the whole permissions model for this product in a dozen lines. A customer can add a vehicle to their own fleet mid-term; nobody outside Flock can quietly change the level of cover. You can read that off the page without opening a single service.
Beneath the configuration sit the modules that do the work. They aren't in the product's own files - they're separately versioned packages, built and tested in isolation, and each product picks up the version it wants. So a product's job is to name the behaviour it needs rather than implement it:
The backdating numbers above cap how far a customer can move a vehicle's cover dates. The accessLevel line says one of our team can go further, because they hit the same rule with elevated rights. Every live product calls the same two rules, but with different numbers.
For an engineer that means you write a rule once and test it once. A config change can only break the product it's in, and a rule change lands per product when that product takes the new version, so you upgrade one at a time instead of all at once or never. This makes changing products a deliberate process, not one of compatibility, migrations, and, in my general experience, sleepless nights.
What This Unlocks
The energy invested into this approach has already paid dividends, both for the top line of the business and for what PMs at Flock are capable of.
Haulage: Supporting the journey to PMF
Haulage is the first launch where we saw real benefits. Launched as a distinct product with its own rules, it started slowly, but evolving and iterating the product has led to it becoming Flock's biggest ever product release.
The product grew 5x in its first 6 months and has become our 2nd largest product in that time.
Taxi: The Comeback Story
Taxi is the other kind of story. During the acquisition process, we needed to overhaul our taxi product and re-launch it. Ideally... within two weeks.
Our framework enabled speed, and let us add the features taxi fleets had been crying out for that we simply could never deliver in our old platform. Since going live we've been binding 2.3x the policies per month we managed before the re-launch.
Product (Manager) Velocity
One of the unexpected shifts is what this has unlocked for PMs. Prior to these changes, our tech stack needed shielding and protecting from unruly requests and changes. This made even the most effective PM armed with Claude Code reticent to get stuck in.
Now that this framework is implemented across all our products, we're seeing PMs deploying 2-3 changes a week against the platform. This is a game-changer for how PMs can create impact for our customers.
Feedback is turned around in real time. Experiments start and run independently.
Closing Thoughts
What has changed is where the constraint sits. It used to be engineering capacity, how many people we could put on a product and for how long. Now it's how well we understand the customer, because once we can describe what they need, describing it is most of the work. From a PMs perspective, that's the best place to be.
If you're weighing up the same move, three things we'd tell you:
- If copy-paste still works, you're too early. The itch to spin up another variant isn't the same thing as genuine complexity.
- Once it is genuine, go before the breaking point rather than after it, and pick the direction by where the customer value is.
- Sell the journey, not the destination. We got this wrong first time. "It'll be better in the end" asks people to take a lot on faith without early validation.
About the author
