
For engineering teams drowning in dependencies and legacy systems, microservices offer a lifeline—but only if you understand when and how to use them.
Sander Hoogendoorn, CTO of iBOOD.com, learned this through rebuilding complex systems at an insurance company and an e-commerce platform. His experiences reveal practical insights about microservices beyond theoretical frameworks and conference presentations.
You’ve probably heard the microservices debate. The hype cycle has peaked. Amazon Prime threw them under the bus. Critics declare them dead. But dismissing microservices entirely misses the point. The real question isn’t whether microservices work—when they work and when they don’t.
As engineering leaders, you face this decision daily: stick with the monolith or break it apart. The answer isn’t in the architecture—it’s in your specific problems.
The Real Problems Microservices Solve
At the insurance company, Hoogendoorn inherited a nightmare: 18 million lines of COBOL code and 12 million lines of Java running on a mainframe housed on the fourth floor. Why the fourth floor? In the Netherlands, most of the country sits below sea level. If flooding happens, they don’t want the mainframe in the basement where it usually lives.
The technical debt was crushing them. Aging programmers were retiring, forcing the company to hire them back for massive salaries to work three days per week. “Run COBOL please,” Hoogendoorn jokes about the lucrative opportunity.
The company had failed six times over 12 years trying to replace their monolithic systems. The problem wasn’t the technology—it was the approach.
“A complex system designed from scratch never works,” explains Hoogendoorn, referencing John Gall’s principle. “You always have to start with a small working system, not try to build the big system.”
The microservices approach worked. After 4.5 years, they replaced the legacy system with 350,000 lines of code distributed across 150 small services.
The second company faced a different monster. They had grown from a startup with a single web page into a larger company with multiple systems: CMS, ERP, CRM, and various third-party integrations. Data lived everywhere, and keeping everything synchronized became impossible.
“This is where they got killed by dependencies,” Hoogendoorn notes. “They reached technical debt—spending all engineering power just maintaining everything to keep it running.”
This is technical death. When your entire engineering capacity goes toward keeping existing systems alive, you can’t build new features or respond to market changes. You’re trapped in maintenance mode while competitors race ahead.
When NOT to Choose Microservices
Most companies don’t need microservices. “Most companies do not have scalability issues, not yet,” Hoogendoorn emphasizes. “If you don’t have scalability problems yet, don’t solve them.”
The scalability excuse drives many failed microservices implementations. Companies see Netflix or Amazon using microservices and assume they need the same architecture. But Netflix serves 200 million subscribers globally. Your startup with 10,000 users faces different challenges.
Here’s the engineering reality: if your current system handles your load and your team ships features without major coordination overhead, microservices will probably make things worse. You’ll trade working software for distributed systems complexity.
But if you recognize these patterns, microservices might solve real problems:
Microservices work best for specific scenarios:
- Breaking down domains that became too complex
- Eliminating dependencies that prevent teams from moving quickly
- Enabling rapid deployment cycles
- Supporting autonomous team operations
“Apply new architectural styles for the right reasons,” Hoogendoorn warns. “I see many people say we’re going to do microservices because of scalability issues. If you don’t have scalability problems yet, don’t solve them yet, but solve problems for the right reasons.”
Do you face these problems? If your team deploys once per quarter and struggles with testing cycles, microservices might help. If you ship features regularly without coordination headaches, a monolith probably serves you better.
Remember: dependencies kill you. This phrase appears throughout Hoogendoorn’s experience. Whether in code, data, or team structure, dependencies create bottlenecks that slow everything down. Microservices help break these dependencies, but only if you implement them correctly.
Your engineering organization probably shows these warning signs if dependencies are killing you: features require coordination across multiple teams, database changes need approval from everyone, and deployments become all-hands events that everyone fears.
Software Architecture and Infrastructure That Adapts
Charles Darwin never studied software architecture, but his principle applies: “It’s not the strongest of the architectures that survive, nor the most complex ones. It’s the most adaptable ones,” Hoogendoorn quotes. “That’s the nice thing about microservices—they are adaptable.”
Hoogendoorn’s team uses a consistent architectural pattern across all microservices: Domain, Process, and Service Interface. This creates predictability across 150 repositories.
Each service contains:
- Domain layer: Entities that define core business logic
- Repository layer: Data access patterns
- Process layer: Use cases that coordinate multiple repositories
- Resource layer: API endpoints
- External integration layer: Connections to databases and other services

“Every service has the domain at its heart,” Hoogendoorn explains. “Around it, we have repositories—they get instances of entities and push them away. On top of that, we have the process layer with use cases that hold the process logic. If you have multiple repositories bringing together behavior, that’s what the use case does.”
“The only thing that keeps them together is the fact that they have the same architectural patterns,” Hoogendoorn explains. “That makes them readable and maintainable over time.”
His team maintains 150 repositories using a single technology stack: React, Node.js, Express, and MongoDB on the Google Cloud Platform. This decision prioritizes team productivity over technology diversity.
“We made a deliberate choice of trying to move away from all the different technology stacks and move back into one,” he explains. “Everybody on my team can understand the stack. I can open up any one of the 150 repos and understand what the code is like, even though I might not have written it.”
Can any team member understand any service? If you need different people for different parts of your system, you’ve created operational complexity that outweighs microservices benefits.
For engineering teams, this consistency matters more than technology diversity. You might want to use the latest JavaScript framework for one service and Go for another, but operational simplicity trumps technical variety. When someone gets paged at 3 AM, they need to debug any service quickly.
Breaking Down <<Domain-Driven Design>> Principles
Domain-driven design provides the foundation for service boundaries. Hoogendoorn uses bounded contexts to identify where to split services.
The bounded context concept comes from Eric Evans, who wrote that “when you model larger domains, it becomes progressively harder to create a single unified model.” Managing a data model with 1,100 tables—which one of Hoogendoorn’s customers has—becomes nearly impossible.
Take an e-commerce product example. In a traditional model, you might have one product entity used for both inventory management and customer orders. But these contexts treat products differently:
- Inventory management cares about supplier relationships, stock levels, and procurement
- Customer orders care about pricing, descriptions, and availability.
“The behavior of the product on the left side differs from the product on the right side,” Hoogendoorn notes. “In domain-driven design terms, it’s not a ubiquitous language. You want everything to have a single meaning in your domain. That makes a bounded context. You split the product into two and keep a very thin line between them.”
Split these into separate services with their product representations. This eliminates cross-context dependencies and allows each service to evolve independently. But don’t try to identify these boundaries upfront. “This is not something you can do up front,” Hoogendoorn warns. “If you’re trying this up front, you’ll probably fail. You define this over time. You take small steps and you get better at it.”
The aggregate pattern from domain-driven design maps well onto microservices. Each aggregate has a root that becomes your service endpoint. If you have a categories collection in MongoDB, you access it via categories/category/ID, entering through the aggregate root of that service.
For engineering teams, this means starting with your existing pain points. Which parts of your codebase cause the most cross-team coordination? Which database tables get touched by every feature? These friction points often reveal natural service boundaries.
Micro-Applications Break Frontend Dependencies
Traditional microservices architecture often creates a monolithic frontend that talks to multiple backend services. This shifts dependency problems to the user interface layer.
Hoogendoorn’s team builds micro applications—separate frontend applications for different business processes. Each application handles one part of the user journey and deploys independently.
At iBood.com, customers move between applications:
- Browsing products: offers app at ibood.com
- Managing profiles: profile app at ibood.com/profiles
- Checkout process: separate checkout application
“Each one of these small applications—they’re all on a subdomain,” Hoogendoorn explains. “You can see them if you go to the website. If you go to your profile, it says ibood.com/profiles. You’re in another app. It looks the same because we use the same UI framework, but it’s a different app deployed at different times. That’s exactly what matters.”
Users see a consistent interface because all applications share the same UI framework. However, each application deploys separately and owns its complete stack.
Continuous Product Delivery Changes Everything
Hoogendoorn’s team deploys 50-80 times per day. This frequency transforms how they work and respond to business needs.
During a quarterly sale, their marketing manager called at 12:10 AM requesting a feature change. The team implemented, tested, and deployed the change in 10 minutes while traffic peaked.
“If you break your code into small pieces and deliver each one continuously, you’re in a much better situation,” Hoogendoorn explains. “The deltas between versions are tiny, which makes them much easier to test.”
This requires complete automation. Manual testing disappears when you deploy multiple times daily. Static code analysis, automated testing, and infrastructure-as-code become essential.
Jeff Humble from the Continuous Delivery book offers this principle: “If it hurts, do it more frequently and bring the pain forward.” Most companies do the opposite. They have quarterly releases that become increasingly painful, so they slow down to annual releases. This makes the problem worse.
Jason Gorman provides a perfect analogy: “Missing a bus is not a big thing if the next bus comes in about 5 minutes. You’ll just wait. If the next one doesn’t come until the next day, you’re in trouble.”

Break your deployments into small, frequent releases. If something goes wrong, the impact is minimal and the fix is quick. But if you wait months between releases, every deployment becomes a high-stakes event that no one wants to handle.
Engineering teams often resist this frequency, citing stability concerns. Sander’s experience shows the opposite: frequent small deployments create more stability than infrequent large ones. The key is automation and testing, not deployment frequency.
Testing Strategy for Speed
Manual testing kills microservices’ velocity. Hoogendoorn’s team automates everything:
- Unit tests run continuously during the development
- Integration tests validate service interactions
- End-to-end tests verify complete user journeys
- Performance tests catch scalability issues
- Production monitoring tests system health every five minutes
“If you are still doing manual testing, you cannot go to the speed of delivering 50 to 80 times per day,” Hoogendoorn states. “All this stuff about people checking spreadsheets with data and going through it and clicking on the website—that slows you down. You want to automate everything.”
“The majority of your tests should be unit tests,” Hoogendoorn recommends. “Test everything in isolation.”
Their libraries maintain 95.4% code coverage. This enables trunk-based development—checking code directly into the main branch without pull requests or code reviews.
“A test is not a unit test if it talks to the database, talks across the network, or touches the environment,” Hoogendoorn explains, citing Michael Feathers. “You isolate the test from the rest. You run them separately from other tests, which means you can run multiple tests in parallel and shorten the feedback loop.”
How long does your testing cycle take? If manual testing requires hours or days, you can’t achieve microservices velocity benefits.
Hoogendoorn’s team moved to trunk-based development, eliminating pull requests and code reviews. This sounds dangerous to many engineering teams, but their 95.4% test coverage and static analysis provide safety nets that traditional code review can’t match.
“We moved away from pull requests because they’re too late,” he explains. “If you write code and make a pull request, that other person might not be in the room. It takes a day or two days. If they have feedback, you don’t remember what you were working on last week. Context switching is very expensive.”
How to Eliminate Database Dependencies
Each microservice owns its data completely. Services never access other services’ databases directly. This creates complexity—you can’t join across services—but eliminates the worst dependencies.
“We don’t want those dependencies because if one of those small domains changes, we don’t want to have dependencies on the other ones,” Hoogendoorn explains.
Different services use different storage technologies based on their needs. Some use relational databases, others use document stores, and some integrate with external APIs. Hoogendoorn’s team even hacks into their HR system to get manager relationships for their profile service. “HR doesn’t know that yet,” he admits. “Well, they might know if they’re looking, but they’re probably not.”
The single database approach kills microservices benefits. You end up with all services depending on the same schema, the same performance characteristics, and the same deployment schedule. You’ve recreated a distributed monolith that’s harder to manage than the original.
For engineering teams, this data ownership principle creates operational challenges. Your monitoring, backup, and disaster recovery strategies must handle multiple databases with different technologies. But this complexity enables team autonomy—each service team owns its complete stack.
Team Structure Follows the Architecture Pattern
Microservices change how teams work. Hoogendoorn’s 13-person team operates with minimal hierarchy and maximum autonomy.
The Hock Principle guides their approach: “Simple, clear purpose and principles give rise to complex and intelligent behavior. Complex rules and regulations give rise to simple and stupid behavior.”
They eliminated traditional processes:
- No Scrum ceremonies
- No product owners—developers talk directly to business stakeholders
- No user story estimation
- No pull requests or formal code reviews
“We took out most of the stuff that people are used to doing,” Hoogendoorn explains. “We don’t do Scrum, we have no product owner. People on my team are their own product owners. They want to pick up some work, they go into the business and talk to people. We don’t do user stories, we don’t estimate. We deliver 50 to 80 times per day—why would you estimate? They’re all small.”
“Simple, clear purpose and principles give rise to complex and intelligent behavior,” Hoogendoorn quotes from the Hock Principle. “Complex rules and regulations give rise to simple and stupid behavior.”
Teams form around problems, not projects. When someone identifies work, they assemble a micro-team with the right skills, solve the problem, deliver the solution, and disband.
“No two work items use the same amount of people or the same people,” Hoogendoorn explains. “They form what I call a micro team. They sit together and solve a single problem every day.”
Antoine de Saint-Exupéry captured this philosophy: “Perfection is achieved not when there’s nothing left to add, but when there’s nothing left to take out.” Hoogendoorn’s team lives on this principle, constantly removing unnecessary processes and ceremonies.
Engineering organizations often accumulate process debt like technical debt. Meetings, approvals, and ceremonies multiply over time. Microservices force you to question every process because coordination overhead becomes visible when you split systems apart.
Choosing the Right Infrastructure for the Company
Microservices succeed when they solve real problems, not theoretical ones. Sander’s experiences show that they work best for organizations facing complexity and dependency challenges.
Ask these questions before choosing microservices:
- Do dependencies between system parts prevent quick changes?
- Can you deploy parts of your system independently?
- Do you have the expertise to automate testing and deployment completely?
- Will your team structure support autonomous service ownership?
“There’s a place and time for everything, and that includes microservices,” Hoogendoorn reflects. “Use them for the right reasons. Sometimes monoliths are better, sometimes microservices. The things we have done with this stuff don’t mean everything we do works for you too.”
“Solve the right problems with the right patterns,” Hoogendoorn concludes. “Sometimes monoliths work better, sometimes microservices do.”
The decision depends on your specific context, not industry trends or technology preferences. Choose the architecture that serves your actual needs, not the one that sounds most impressive.
Microservices aren’t a silver bullet. They’re a tool for specific problems. If you don’t have those problems, the tool won’t help. But if dependencies are killing your velocity, if your monolith has become unmaintainable, if your teams can’t deploy independently—then microservices might be exactly what you need.
Just remember Hoogendoorn’s final piece of advice: “If everything else fails, all the patterns you’ve tried before, you can always remove your node modules and do an npm install.”
Ready to Transform Your Software Architecture?
Microservices aren’t about following trends—they’re about solving real engineering problems. If dependencies are strangling your team’s velocity, if your monolith has become unmaintainable, if coordination overhead exceeds development time, then it’s time to act.
Start your microservices transformation:
- Identify your biggest pain points – Which parts of your system cause the most coordination overhead?
- Map your natural boundaries – Where do different teams consistently step on each other?
- Build your automation foundation – You can’t succeed without automated testing and deployment
- Start small and learn – Extract one service, measure the impact, adjust your approach.
Don’t let analysis paralysis keep you stuck in dependency hell while your competitors ship features at lightning speed. Your engineering team’s velocity hinges on architectural decisions that match your actual problems, not the latest Medium articles.
Join us at How to Web Conference where real CTOs share battle-tested insights about microservices, distributed systems, and engineering challenges that actually matter—or keep attending those quarterly deployment meetings where everyone holds their breath and prays nothing breaks. After all, as Sander reminds us: “If everything else fails, you can always remove your node modules and do an npm install.” But for everything else, there’s How to Web.
You may also like
Europe's Goldmine: 13 Tech Conferences To Attend in 2025
For engineering teams drowning in dependencies and legacy systems, microservices offer a lifeline—but only if you understand when and how to use them. Sander Hoogendoorn, CTO of iBOOD.com, learned this through rebuilding complex systems at an insurance company and an e-commerce platform. His experiences reveal practical insights about microservices beyond theoretical frameworks and conference presentations…. Read more »
Mind Over Pixels: How AI Redefines the Future of UX
For engineering teams drowning in dependencies and legacy systems, microservices offer a lifeline—but only if you understand when and how to use them. Sander Hoogendoorn, CTO of iBOOD.com, learned this through rebuilding complex systems at an insurance company and an e-commerce platform. His experiences reveal practical insights about microservices beyond theoretical frameworks and conference presentations…. Read more »