Three teams.
One database.
And almost every deployment required coordination between them.
The system was technically working.
Payments were processing.
Settlement jobs were running.
Ledger entries were being created.
But engineering was becoming slower every month.
A change that should have taken one team a day could take several teams a week.
A database migration required multiple approvals.
A deployment from one team could block another team’s release.
When something went wrong, the first question was often:
“Whose system is this?”
The uncomfortable answer was:
“Everyone’s.”
That was the problem.
The architecture had evolved around organizational boundaries rather than business boundaries.
We had built a system that mirrored the structure of our teams.
And eventually, the organization became the bottleneck in the architecture.
1. The System Looked Like the Organization
The original structure seemed reasonable.
We had three major teams:
Payments Team
│
▼
Payment Services
│
└──────────────┐
│
▼
Settlement Team ──► Shared Database
▲
│
┌──────────────┘
│
▼
Ledger Team
Each team had its own responsibilities.
The Payments team handled payment processing.
The Settlement team handled settlement workflows.
The Ledger team handled accounting and ledger operations.
On an organizational chart, the boundaries looked clean.
Inside the architecture, they weren’t.
All three teams depended heavily on the same database.
They shared tables.
They shared schemas.
They depended on each other’s data.
And some workflows crossed all three teams.
The system wasn’t really three independent capabilities.
It was one tightly coupled system being maintained by three organizational groups.
2. The Deployment Problem
The first symptoms appeared in deployments.
The Payments team wanted to change a database table.
The Settlement team depended on that table.
The Ledger team depended on another part of the same schema.
A seemingly simple change became:
Payments Team
│
▼
Database Change
│
├── Settlement Team Review
│
└── Ledger Team Review
│
▼
Coordinated Release
The problem wasn’t that teams were collaborating.
Collaboration is good.
The problem was that collaboration had become a prerequisite for ordinary change.
Teams couldn’t move independently because the architecture didn’t allow them to.
Every change created a coordination problem.
And coordination became increasingly expensive as the organization grew.
3. The Shared Database Became a Shared Ownership Problem
The database was originally introduced as a practical solution.
There was a lot of shared financial data.
Putting it in one place made many operations easier.
Over time, however, the database became more than a persistence layer.
It became the integration mechanism between teams.
Instead of:
Payments → API → Settlement
we increasingly had:
Payments
│
▼
Shared Database
▲
│
Settlement
And:
Payments
│
▼
Shared Database
▲
│
Ledger
Teams began depending on database tables as if they were APIs.
A schema change was effectively an API change.
A new column could affect another team’s queries.
A renamed field could break a background job.
A change in transaction behavior could affect downstream processing.
The database had become a shared contract.
But there was no single owner of that contract.
4. The Incident That Made the Problem Obvious
The architectural problem became impossible to ignore during a production incident.
The Payments team released a change intended to improve transaction processing.
The change itself was reasonable.
The deployment passed testing.
Payments appeared healthy.
Shortly afterward, a settlement workflow started processing fewer records than expected.
Nothing immediately looked broken.
The payment service was healthy.
The settlement service was healthy.
The database was healthy.
But the workflow between them was not.
The investigation eventually showed that the change had altered behavior in a shared database structure that the Settlement team depended on.
Nobody had intentionally broken the Settlement system.
Nobody had ignored a known ownership rule.
The problem was that the ownership boundary wasn’t clear enough to prevent the change.
Three teams were responsible for different business capabilities.
But the architecture gave them a shared implementation boundary.
5. We Initially Tried to Fix It With Process
Our first response was predictable.
We added process.
More reviews.
More documentation.
More deployment checklists.
More database approval steps.
More meetings between teams.
The new process looked something like:
Database Change
↓
Payments Review
↓
Settlement Review
↓
Ledger Review
↓
Architecture Review
↓
Deployment
It reduced some surprises.
But it didn’t solve the underlying problem.
We had treated an architectural coupling problem as a coordination problem.
And coordination doesn’t remove coupling.
It manages it.
For a while, that can work.
As the system and organization grow, it becomes increasingly expensive.
6. The Cost Wasn’t Just Deployment Time
The impact was broader than slower releases.
Teams started making architectural decisions based on what other teams might need.
Developers avoided changing parts of the database because they weren’t sure who depended on them.
Engineers delayed improvements because the coordination cost was too high.
Small changes became large projects.
Ownership became ambiguous.
And incidents became harder to resolve.
A typical question during an incident was:
“Who owns this?”
The answer might be:
“Payments owns the service, Settlement owns the workflow, and Ledger owns the data.”
That isn’t clear ownership.
That’s shared responsibility.
And shared responsibility can easily become distributed accountability.
7. The Conway’s Law Problem
Eventually we recognized a familiar pattern.
Conway’s Law is often summarized as the idea that organizations tend to produce systems whose structure reflects the communication structure of the organization.
Our system was doing exactly that.
We had teams organized around technical responsibilities.
The architecture had started reflecting those boundaries.
But the business didn’t operate that way.
The business cared about capabilities such as:
Payment
Settlement
Ledger
Those capabilities had relationships and dependencies.
The engineering organization had separate groups with overlapping technical ownership.
The architecture followed the organization.
The result was a system with boundaries that were convenient for teams but inconvenient for the business.
That was the moment the problem became much clearer.
We didn’t just have a database coupling problem.
We had an organizational architecture problem.
8. The Three Options We Considered
We considered three broad approaches.
Option 1: Keep the Teams and Improve Coordination
We could continue with the existing organization.
Add stronger database governance.
Define ownership rules.
Improve documentation.
Introduce compatibility requirements.
This would reduce some problems.
But the underlying dependency graph would remain.
Teams would still need each other for many changes.
Option 2: Keep the Architecture and Add More Platform Ownership
Another possibility was to create a central database or platform team.
That team could own the shared infrastructure and coordinate schema changes.
This could make governance clearer.
But it risked creating another central dependency.
Instead of:
Payments ↔ Settlement ↔ Ledger
we might create:
Payments ──► Platform Team ◄── Settlement
▲
│
Ledger
The coordination problem would move.
It wouldn’t necessarily disappear.
Option 3: Align Teams With Business Capabilities
The third option was more difficult.
We changed the organizational boundaries themselves.
Instead of organizing primarily around technical layers, we organized ownership around business capabilities.
The goal became:
The team responsible for a business capability should have enough ownership to evolve that capability independently.
That didn’t mean every team needed its own database immediately.
It meant ownership had to become clear first.
9. We Reorganized Around Business Capabilities
The new model looked more like:
Payment Team
│
▼
Payment Capability
│
▼
Settlement Team
│
▼
Settlement Capability
│
▼
Ledger Team
│
▼
Ledger Capability
The important change wasn’t the diagram.
It was the ownership model.
The Payments team became responsible for the payment capability.
The Settlement team became responsible for settlement behavior.
The Ledger team became responsible for ledger behavior.
Each team had clearer authority over:
- Business logic
- Service interfaces
- Data ownership
- Operational metrics
- Production incidents
- Changes within its boundary
That dramatically reduced ambiguity.
10. Ownership Became a Technical Property
This was one of the biggest lessons.
We had previously treated ownership as an organizational concept.
Who manages the service?
Who is on call?
Who reviews the pull request?
We started treating ownership as an architectural property.
For every important capability, we wanted to answer:
Who owns the business behavior?
Who owns the API?
Who owns the data?
Who owns the operational health?
Who decides when the contract changes?
Who responds when it fails?
If those questions had different answers, that wasn’t necessarily wrong.
But it needed to be intentional.
Ambiguity was the problem.
11. The Database Still Needed Boundaries
Reorganizing teams didn’t magically eliminate database coupling.
That required architectural work too.
We started identifying which data belonged to which business capability.
For example:
Payments
└── Payment state
Settlement
└── Settlement state
Ledger
└── Accounting entries
The goal wasn’t to duplicate everything.
It was to establish data ownership.
Other teams could consume data through explicit interfaces rather than assuming they could directly modify another team’s tables.
That distinction was critical.
A team’s database schema stopped being a shared implementation detail and started becoming part of an owned boundary.
12. Shared Data Doesn’t Always Mean Shared Ownership
Financial systems make this particularly difficult.
Payment processing, settlement, and ledger systems naturally depend on related information.
The answer isn’t necessarily:
“Give every team its own database and never share anything.”
That can create a different set of problems.
Instead, we asked:
Who is authoritative for each piece of information?
For example:
Payment Status
↓
Payments owns it
Settlement Status
↓
Settlement owns it
Accounting Entry
↓
Ledger owns it
Other systems can consume those states.
They shouldn’t casually become co-owners of the underlying data.
This made the boundaries much clearer.
13. We Introduced Explicit Contracts
Once ownership was clearer, we could start replacing implicit database dependencies with explicit contracts.
Instead of:
Settlement
↓
Reads Payments tables directly
we moved toward:
Settlement
↓
Payment API / Event
↓
Payments
Or, for asynchronous workflows:
Payments
│
▼
PaymentCompleted Event
│
▼
Settlement
The important architectural improvement was not necessarily whether the interface was synchronous or asynchronous.
It was that the dependency became explicit.
An API or event is a contract.
A shared database table is often an accidental contract.
14. The Deployment Model Changed
Once teams had clearer boundaries, deployment became easier.
Before:
Payment Change
↓
Database Change
↓
Settlement Review
↓
Ledger Review
↓
Coordinated Deployment
After:
Payment Change
↓
Payment Team
↓
Independent Deployment
If the change affected another capability, it required an explicit contract change.
That was actually healthier.
A dependency became visible instead of remaining hidden inside a shared database.
The system became easier to reason about.
15. Incidents Became Easier to Own
The organizational change also affected incident response.
Previously:
“The payment workflow is failing. Who owns it?”
could result in several teams joining the investigation.
Afterward, the initial question became:
“Which business capability is failing?”
That gave us a clearer starting point.
The owning team could investigate the capability while other teams joined when the evidence showed a dependency problem.
This didn’t eliminate cross-team incidents.
It made the starting point much clearer.
16. Financial Systems Make Ownership Especially Important
In a financial system, the boundaries between payment, settlement, and ledger aren’t merely organizational preferences.
They represent different responsibilities.
A payment might answer:
Was the customer’s payment authorized?
Settlement might answer:
Has the financial obligation been settled between the relevant parties?
The ledger might answer:
What accounting entry represents the financial event?
These operations are related.
They are not identical.
If ownership becomes ambiguous, several problems can follow:
- Unclear transaction state
- Difficult reconciliation
- Conflicting data interpretations
- Slower incident response
- Riskier schema changes
- Unclear operational accountability
Clear ownership therefore isn’t just about developer productivity.
It supports financial correctness and operational control.
17. What We Did Not Do
We didn’t immediately turn everything into microservices.
That would have been an easy conclusion to draw.
But the problem wasn’t:
“We have too few services.”
The problem was:
“Our organizational and architectural boundaries don’t align.”
A monolith with clear modular boundaries and clear ownership can be healthier than a collection of microservices with shared databases and unclear responsibility.
We focused on ownership first.
Then boundaries.
Then implementation.
That order mattered.
18. The Dangerous Pattern
There is a pattern I’ve learned to watch for:
Teams grow
↓
Responsibilities split
↓
Shared components remain
↓
Dependencies increase
↓
Coordination increases
↓
Deployments slow down
↓
Ownership becomes unclear
↓
Architecture becomes harder to change
At some point, the organization starts creating meetings to compensate for architectural coupling.
That is a warning sign.
Meetings can coordinate people.
They cannot make a tightly coupled system loosely coupled.
19. When to Suspect an Organizational Architecture Problem
There are several signals.
1. Multiple teams regularly need to approve ordinary changes
This may indicate that ownership boundaries are too broad or unclear.
2. One database schema is effectively owned by several teams
Shared data can be necessary, but shared ownership needs to be deliberate.
3. Teams cannot deploy independently
Frequent coordinated releases are often evidence of architectural coupling.
4. Incidents repeatedly involve multiple teams without clear ownership
This can indicate that business capabilities don’t have clear technical owners.
5. Engineers avoid changing parts of the system
Fear of breaking another team’s workflow is a form of architectural coupling.
6. Teams are organized around technical layers while the business operates around capabilities
This is one of the strongest signals.
7. Process keeps increasing while architectural coupling remains
If more approvals and meetings are being added every year, the organization may be compensating for boundaries that need redesign.
20. The Questions I Ask Now
When looking at an architecture, I don’t only ask:
“What are the services?”
I ask:
Who owns each business capability?
Then:
Who owns the data behind it?
Then:
Can that team change its implementation without coordinating with several other teams?
Then:
Are dependencies expressed through explicit contracts?
And finally:
Does the organizational structure make the desired architecture easier or harder to maintain?
Those questions often reveal problems that a system diagram won’t show.
21. The Bigger Architectural Lesson
Architecture isn’t produced only by architects.
It is produced by the structure of the organization that builds and operates the system.
If three teams share a database, the database becomes part of their organizational boundary.
If five teams must approve every change, the architecture has effectively created a five-team deployment boundary.
If nobody owns a capability end-to-end, the system will eventually reflect that ambiguity.
This is why Conway’s Law is so useful.
It reminds us that architecture and organization are not independent variables.
They influence each other continuously.
22. What Changed After the Reorganization
The most important improvement wasn’t simply that deployments became faster.
The system became easier to understand.
We had clearer answers to:
Who owns this capability?
Who owns this data?
Who can change it?
Who operates it?
Who responds when it fails?
Teams spent less time coordinating routine changes.
Dependencies became more explicit.
Database ownership became clearer.
And architectural decisions could be made closer to the people responsible for the business capability.
The organization and the architecture started reinforcing each other instead of fighting each other.
Final Thought
The architecture didn’t suddenly become complicated because the engineers forgot how to design systems.
It became complicated because the organization evolved while the architecture didn’t.
Teams were created.
Responsibilities changed.
Business capabilities grew.
But the system boundaries remained largely the same.
Eventually, the organization was forced to coordinate around architectural boundaries that no longer made sense.
The lesson wasn’t:
“Always create one team per service.”
And it wasn’t:
“Always split the database.”
The lesson was simpler:
Architecture and organization must evolve together.
If you want teams to own business capabilities independently, the architecture needs to give them meaningful boundaries.
If you want independent deployments, teams need control over the components they deploy.
If you want clear accountability, data and operational ownership need to be explicit.
And if three teams are constantly fighting over the same database, the database may not be the only thing that needs redesigning.
Sometimes the first architectural change you need to make isn’t in the code.
It’s in the organization that creates the code.