Tiers VS spikes: share your cookie the Agile way

There are days when each discussion after some time leans toward Agile methods, and it doesn't matter whether it has started with music gig, lunch place idea or recently published book :) - the end is inevitable. Today, I feel like past two weeks consisted only of those days - that freaks me out a bit & now I'm a bit reluctant to ask my 2yo daughter how was her day: she may show me her Kanban board and that would be too much. Nevertheless, there's one strictly Agile topic I feel an urgent desire to write about, because recently I've spoken with several people who have treated it very lightly (too lightly IMHO):

Splitting large apps between many Agile teams

Hey, in theory it's helluva simple - you just distinguish the products, identify the owners, assign teams & here you go. But the problem is that sometimes it's not that easy to identify "products" - overall system architecture may be extremely tangled & historical responsibility split may be against all the logic. That's why you have to start with imperfect split, just to have things started (even if you know that it has its flaws and adjustments will have to be made) - that's the moment when you may face the dillemma:

each team takes tier (or part of a tier)

each team takes a spike that goes through all the tiers

Tier?

Before I dive into the details - what's tier and how does it differ from layer? Tier is a horizontal / same level "layer" in physical (deployment) architecture - stuff that may be deployed (and usually is) separately from the other tiers.

On the other hand, layer is pretty much the same, but in logical (component) architecture - it's visible & distinguishable when you consider the hierarchy of method calls, etc. but all the layers within tiers are deployed together as one application / service / etc.

Whipped cream for Mary, puff pastry for John, cherry for Bob, ...

Tier-based split may make most sense at the first glance: in many cases (especially the legacy ones) each tier may use different set of technologies, so it requires different, specialized skills & knowledge. Keeping people capable of these altogether may help them develop those skills further & simplifies the deployment (team cares only about their tier(s)).

But it's wrong ...

Just ask yourselves these questions:

Can you envelop any user-facing / value-adding user story within one tier?

Can you have two independent backlogs for two teams responsible for different tiers? Would it make sense?

Can you independently test your code within one tier?

If no users use your tier directly & all it expose is low-level, highly specialized programming API, will you be able to find a product owner able to drive its development towards high value for organization?

Spikes, on the other hand, represent complete end-to-end scenarios & each of them goes through all the necessary layers. The idea of spikes' independence is quite delusional, but the level of coupling is much lower, especially if you set some reasonable ground rules. What's really important about spikes:

they represent typical user stories

thinking with spikes help you to keep functional domain model cleaner, because your forced to build the horizontal split into separate "modules" -> even if you start with a mess, quite likely it will get more & more tidy with time