Most people ask this question the same way: should we have one Jira space per application?
It's a reasonable instinct and it's usually close to right. But it's answering the wrong question, and the difference matters more the larger your estate gets.
Here's the rule I'd use instead, and what it looks like in practice.
The space boundary is the version boundary
A Fix version belongs to a space. That's the only scoping the object has. You can't share a version across spaces, and you can't scope one to a component.
So when you decide where the space boundary sits, you're also deciding where your version boundary sits. Everything downstream follows from that: what a release means, what your release queries return, what has to be coordinated by hand.
Which turns the question into something more useful:
Things that release together should live together. Things consumed by several release streams need their own space.
Application boundaries and release boundaries often line up, which is why "one space per application" usually works. But when they diverge, the release boundary is the one to follow.
Three structures, and when each one fits
- One space per application. The default, and the right answer when applications genuinely release independently. Each version means one deployable at one version on one date. Permissions, workflows and cadence can differ per app without negotiation. Release queries behave exactly as you'd expect.
- One space per team, components per application. Works when the team-to-application mapping is stable and a team ships everything it owns on one cadence. The Fix version represents the team's release, and components tell you which application was touched. It falls apart the moment two teams need to work on the same application.
- Shared services in their own space. Anything consumed by several release streams can't belong to any one of them. This is the case people most often miss, and it causes the most pain later. A shared library or service tied to a consuming application's space will fight you every release.
When several deployables share one space
Sometimes one space holds multiple independently deployable things. A team owning eight microservices doesn't want eight spaces, eight boards and eight backlogs, and they're not wrong about that.
The trade-off is worth understanding before you make it.
A Jira version has no idea what it's a version of. It knows its space, its name, and its dates. That's all. Components will tell you which microservice a ticket touches, but you cannot scope a version to a component.
So the Releases tab becomes a single flat list, interleaving unrelated release streams by date. Payment service 2.3.4 sits between two Pickup Point versions that have nothing to do with it.
The usual answer is to encode the deployable into the version name itself:
PAY 2.3.4
PUP 2.6.1
That's a convention doing a job the data model won't. And it turns out to be more than cosmetic.
Filtering a shared space
Two queries, doing different jobs:
1- By component, which scopes the tickets:
project = NESOA AND component = "Payment"
AND fixVersion in unreleasedVersions() AND statusCategory != Done
Documented, dependable, and independent of whether anyone named the versions consistently.
2- By version prefix, which scopes the versions:
project = NESOA AND fixVersion ~ "PAY*" AND statusCategory != Done
Shorter, and it does work on Jira Cloud. One caveat worth knowing: Atlassian's documentation lists the ~ operator as unsupported for fixVersion, and there's an open ticket noting it appears in the operator dropdown anyway. It works today. Treat it as undocumented behaviour rather than a guarantee.
I tested the matching behaviour, because it isn't obvious:
Query | Result |
|---|
fixVersion ~ "PAY"
| Nothing. A bare string needs an exact match |
fixVersion ~ "PAY*"
| Matches. Prefix plus wildcard works |
fixVersion ~ "AY*"
| Nothing. The match is anchored at the start |
So the asterisk isn't optional, and the prefix has to be the first characters of the version name.
Which makes the naming convention load-bearing
If you take one thing from this section: decide the convention before you create version one, and never deviate.
PAY 2.3.4 matches PAY*. Pay 2.3.4 doesn't. A leading space doesn't. NESOA-PAY 2.3.4 doesn't either, since that would need NESOA*, which defeats the point.
Nothing warns you when a filter silently stops matching a version someone named slightly differently. And two hundred versions in, with three variations of the same prefix in circulation, it's effectively unfixable.
One thing the prefix doesn't solve: the Releases tab itself. You can't filter versions there. The prefix makes the list readable, saved filters make it workable. If you co-locate deployables, plan on a dashboard rather than the Releases tab as your working view.
Once you have more than one space
The moment you split, a release can span several Fix versions across several spaces, and Jira has no native object above them.
What exists today:
- Jira Plans offers a cross-space view, but no workflow, no environment tracking, no sign-off.
- Release Management apps from the Marketplace add a genuine cross-space release object, which is closer to what most release managers actually need.
- Version sync automation keeps matching versions aligned across spaces. I've written up how to do this with Jira Automation: How to Sync Jira Versions Across Projects Using Jira Automation
That last one is worth a second look, though, and it leads somewhere more interesting than tooling.
The diagnostic: why do these spaces always release together?
If two spaces can never release independently, the structure is telling you something. There are three possible reasons, and they have three different answers.
1- A genuine technical dependency. At Nespresso we had these. Omni-channel features spanned the eCommerce platform and the ERP: the same capability for customers on the web, and for agents in service centers and boutiques. Ship one side without the other and the feature is broken by definition.
Some coupling is real and irreducible. Here, coordinate properly. Version sync is the right tool, and the goal is making the dependency visible rather than removing it.
2- A testing constraint. We had this too, and it's a completely different thing. We shipped three applications together every quarter, including a set of shared microservices that had no genuine dependency on the eCommerce release. They were in the bundle because testing everything together was easier than testing the pieces apart.
That's an honest reason and a common one. It's also not a fact about the systems. It's a consequence of not having the infrastructure to verify them independently: contract tests, service-level environments, a way to prove a service works against both the current and next version of its consumers.
Building that is expensive. Bundling the release is free, and it works, right until the quarterly release becomes the only release you're capable of doing. Then everything in the estate waits for the slowest thing in it. Scope gets bigger, freezes get harder, go/no-go covers three applications at once, and a rollback touches all three.
3- Habit. Nobody has questioned the bundle in years. The most common answer of the three, and the cheapest to fix.
Your space structure shows you where your applications are separate. Your release cadence shows you where your testing is not.
What I'd do differently
The microservices coupling was the avoidable one. The right move was to ship the shared services first, backwards-compatible with the current eCommerce version, and let that side release on its own cadence. The ERP coupling would have stayed, since omni-channel features genuinely need both halves. But it would have been one bundle instead of three things moving as one.
I want to be straight about what that costs, because it's easy to say and hard to do. Versioned APIs. Contract tests between services and consumers. A deprecation policy, so old behaviour is carried deliberately rather than forever. And someone senior enough to fund the work, given that the payoff is a cadence improvement rather than a feature.
We didn't do it. Given the same situation again, I'd argue for it, and I'd expect the argument to take a while.
A checklist for your own instance
- For each pair of spaces that always release together: is that a technical dependency, a testing constraint, or habit?
- Is any shared service living inside a consuming application's space?
- If a space holds multiple deployables, is there a version naming convention, and is it followed without exception?
- Does
fixVersion ~ "PREFIX*" return what you expect in that space? - Does one team own several spaces, each with its own board and backlog? Is that costing more than it saves?
- When a release spans several spaces, what holds it together: a tool, or a person?
- If that person were away next Tuesday, could the release still happen?
The last one is usually the most revealing.
I write about release management in Jira on LinkedIn, in a newsletter called Holy Ship.