Design Thinking
Team & Org-Level Design Thinking
Design systems for team ownership. Conway's Law in practice, API contracts between teams, reducing cognitive load, and Amazon's two-pizza team. Staff+ signal.
Staff engineers think beyond the system—they think about the org that builds and operates it. Conway's Law says architecture mirrors communication structure. Designing for team ownership, clear API contracts, and manageable cognitive load leads to systems that scale with the org, not against it.
Designing Systems for Team Ownership
Why Ownership Matters
- Clarity: One team owns one piece. No confusion.
- Speed: Teams can deploy independently
- Accountability: On-call, incidents, improvements—clear owner
- Scaling: Add teams = add services. Org scales with product.
Ownership Model
Single service, single owner: One team owns the whole service. Clear.
Domain ownership: Team owns a domain (e.g., "payments")—may include multiple services. Still clear.
Shared ownership: Multiple teams touch one service. Avoid if possible. If needed, define primary owner and consumers.
Design Implications
- Service boundaries should match team boundaries
- APIs are the contract between teams
- Data ownership: One team owns the source of truth
- Dependencies: Prefer one-way. Avoid circular team dependencies
Senior Insight
"If two teams need to change the same code for every feature, the boundary is wrong. Split so each team owns their slice end-to-end." — Ownership should be exclusive for the main code paths.
Conway's Law in Practice
The Law
"Organizations design systems that mirror their communication structure." — Melvin Conway
Implications
- Siloed teams → Siloed systems (hard to integrate)
- Cross-functional teams → Integrated products
- Many small teams → Many small services (microservices)
- Single monolith team → Monolith
Using It Intentionally
Option A: Structure the org to match desired architecture.
- Want microservices? Create small, focused teams.
- Want clear boundaries? Align teams to domains.
Option B: Structure the architecture to match the org.
- Have 3 teams? Design 3 main services.
- Teams don't talk much? Minimize cross-service calls.
Option C: Change both. Reorg and re-architect together. Hard, slow.
Real Example: Amazon Two-Pizza Teams
Amazon's "two-pizza team" (small enough to feed with two pizzas) led to small, autonomous teams. Each team owned services. Communication overhead within team: low. Between teams: via APIs. Result: Many services, clear ownership, API-first culture.
Interview Tip
"If we're designing for multiple teams, I'd align service boundaries with team boundaries. That way each team can own their service, deploy independently, and we minimize cross-team coordination. That's Conway's Law working for us."
API Contracts Between Teams
Why Contracts Matter
- Decoupling: Teams can evolve independently
- Clarity: Contract = agreed interface. No ambiguity.
- Versioning: Contracts change. Version them.
- Conflict resolution: When things break, contract is the source of truth.
Good Contract Design
- Stable: Don't change often. Additive changes preferred.
- Documented: Schema, examples, semantics
- Versioned: v1, v2. Old versions deprecated with notice
- Backward compatible: New fields optional. Don't remove.
- Owned: One team owns the contract. Consumers depend on it.
Contract Anti-Patterns
- Tight coupling: Internal implementation details in contract
- Breaking changes without versioning or notice
- Implicit contracts: "We both know how it works" — no
- Circular dependencies: Team A depends on B, B depends on A
Example: Order Service API
Team: Orders owns the Order service. Team: Payments consumes it.
Contract:
GET /orders/{id}— Returns order. Order includes status, items, total.POST /orders— Create order. Returns order ID.- Not in contract: Internal DB schema, caching, queue structure. Payments doesn't care.
Versioning: /v1/orders. When we add fields, v1 still works. v2 adds new fields. Deprecate v1 with 6-month notice.
Reducing Cognitive Load for Engineers
The Problem
As systems grow, no one understands the whole thing. Onboarding takes months. Debugging is hard. Changes have unexpected effects. Cognitive load = how much you need to hold in your head to work effectively.
Design for Lower Cognitive Load
- Clear boundaries: Each service has a clear purpose. Name it well.
- Documentation: Architecture docs, runbooks, decision records (ADRs)
- Consistent patterns: Same auth, same logging, same deployment across services
- Observability: Good traces and metrics so you don't need to read code to understand flow
- Limit fan-out: Too many dependencies = hard to reason about
- Standard interfaces: Same API style (REST or gRPC), same error handling
Senior Insight
"Cognitive load is a constraint. If a new engineer can't understand our system in 2 weeks, we've designed it wrong. Split it, document it, or simplify it." — Design for readability and operability.
Amazon's Two-Pizza Team and Service Boundaries
The Model
- Small teams: 6–10 people. Fed by two pizzas.
- Ownership: Team owns a service (or a few related services)
- Autonomy: Team can build, deploy, operate without waiting on others
- APIs: Teams interact via APIs. No shared DB across teams.
- Single-threaded: Team focuses on one product/area
Service Boundaries at Amazon
- Catalog team: Product catalog service
- Inventory team: Inventory levels, reservations
- Ordering team: Order creation, fulfillment
- Recommendations team: "Customers who bought..."
- Search team: Product search
Each team owns their domain. They expose APIs. Other teams consume. No team touches another's DB.
Lesson
"Start with the org. What teams do we have? What do they own? Design services to match. If we don't have teams yet, design as if we'll have one team per major domain. That gives us room to grow." — Design for future org structure.
Thinking Aloud Like a Senior Engineer
Problem: "Design a platform with catalog, inventory, orders, and recommendations."
My first instinct: "Four services. Catalog, Inventory, Orders, Recommendations. Done."
But team lens: Who owns what? If one team owns all, maybe a modular monolith is simpler. If four teams, four services with clear APIs.
I'll assume four teams (common for e-commerce):
- Catalog team: Product data, categories, attributes
- Inventory team: Stock levels, reservations, restocking
- Orders team: Order lifecycle, checkout, fulfillment
- Recommendations team: Algorithm, model serving
APIs:
- Catalog exposes: products, search, categories. Consumed by: Orders (to show product), Recommendations (to recommend).
- Inventory exposes: check availability, reserve, release. Consumed by: Orders (at checkout).
- Orders exposes: create order, get order status. Consumed by: (maybe external, maybe nothing internal).
- Recommendations exposes: get recommendations for user. Consumed by: frontend, maybe Catalog.
Ownership: Each team owns their data. No shared DB. Orders doesn't write to Inventory's DB; it calls Inventory API to reserve.
Cognitive load: Each service is understandable on its own. New engineer on Orders team learns Orders + a few API calls. Doesn't need to understand Recommendations internals.
Best Practices
- Align service boundaries with team boundaries
- Design APIs for cross-team consumption—stable, versioned, documented
- One team, one owner—avoid shared ownership when possible
- Reduce cognitive load—clear names, docs, consistent patterns
- Think org structure—Conway's Law. Design for the org you have or want.
Summary
Team and org-level design thinking:
- Ownership: One team per service/domain. Clear accountability
- Conway's Law: Architecture mirrors org. Use it intentionally
- API contracts: Stable, versioned, documented. The interface between teams
- Cognitive load: Design for understandability. Docs, boundaries, consistency
FAQs
Q: How do I bring up Conway's Law in an interview?
A: "If we're designing for multiple teams, I'd align service boundaries with team boundaries—Conway's Law. That gives each team autonomy and clear ownership."
Q: What if we have one team? Do we still design for multiple?
A: Design with boundaries in mind. Even one team benefits from clear domains. If the team grows, you can split. If not, you still have a modular system.
Q: How do we prevent API contract conflicts between teams?
A: One owner per API. Consumer-driven contract testing (Pact, etc.). Versioning and deprecation policy. Regular sync between dependent teams. Document everything.
Apply This Thinking
Practice what you've learned with these related system design questions:
Keep exploring
Design thinking works best when combined with practice. Explore more topics or apply what you've learned in our system design practice platform.