The day after Maya gets off the video call with Nina from Harvest Circle, Sam opens a conversation with a question that sounds small and isn’t. “When we launch in New Zealand, where are the servers?” The answer turns out to be a diagram the team has been operating without for the entire life of the company.
It’s Wednesday morning. Maya is still slightly giddy from Friday’s call with Nina and Monday’s strategic conversation with Charlotte and Tom. The path is set: Greenbox is going to acquire Harvest Circle, slowly, carefully, preserving Nina’s continuity. The deal is not signed yet. Due diligence is going to take weeks. But the decision is made and the team is starting to think about what the launch actually looks like.
Sam walks into the Perth office at eight with a coffee in each hand, one for herself, one for Priya, who has been in since seven reviewing delivery predictions for next week. Sam hands Priya the second coffee and doesn’t sit down.
“I’ve got a question,” Sam says, “and I need to not forget it before someone tells me the answer. When we launch in New Zealand, where are the servers?”
Priya looks up from her screen.
“What do you mean where are they? They’re in AWS.”
“Yes, but where in AWS?”
“Sydney region. ap-southeast-2. Same as they’ve been since we started.”
“Right. So when a subscriber in Auckland logs in, their request goes from Auckland, to Sydney, and back?”
“Yes.”
“And that’s fine?”
Priya pauses. She has not thought about this. In the four years she’s been at Greenbox, the latency of an API request has been about 200 milliseconds for the slow ones and nobody has ever asked where the slow ones came from. She’s a backend developer. Auckland is geographically on the east side of New Zealand. Sydney is on the east side of Australia. She does the mental calculation. They’re about 2,150 kilometres apart. Light in fibre optic cable covers that in roughly 15 milliseconds round-trip, plus switching overheads, plus the normal database round-trips that Greenbox already takes.
“It’s probably fine for most things. It might be slow for the checkout flow. I don’t actually know.”
Sam nods. “Okay. Second question. Is it allowed?”
Priya stares at her.
“Allowed by who?”
“By whoever decides whether a New Zealand subscriber’s data is allowed to live on a server in Sydney. I don’t know who decides. But I know that when we were talking to Nina on Friday she mentioned data residency and nobody in the room including me knew exactly what to do with that phrase.”
Priya puts her coffee down.
“That’s a great question.”
“It’s not mine. Nina asked it first. I’m just repeating it.”
“It’s still a great question.”
The things the existing diagrams don’t show
Priya opens the architecture diagrams page that Tom set up back in May. The one with the living Structurizr DSL, the C1 and C2 views, and the single C3 component diagram for Supply Matching.
She shows it to Sam.
“Okay,” Priya says. “So this is what Greenbox is. This is the C1, subscribers, farm partners, Stripe, Mailgun. And this is the C2, the four containers inside Greenbox. Subscription, Billing, Supply Matching, Fulfilment. Each one is a Go service with its own database. That’s the whole architecture, at two levels of detail.”
Sam looks at it.
“Where does any of this say that it lives in Sydney?”
Priya looks at the diagram. She looks at the DSL source. She looks at the diagram again.
“It doesn’t.”
“How would I know, from this diagram, where a subscriber’s data is stored?”
“You wouldn’t.”
“Can you draw me a diagram that shows it?”
Priya is already getting up to find Charlotte.
Charlotte’s first reaction
Charlotte is in Perth this week, she’s been alternating between Perth, Sydney, and Melbourne for most of the year, and she happens to be at the Perth office this morning. Priya finds her at the communal table, drinking an espresso from the cafe downstairs.
“Remember when you taught us C4?” Priya says.
“I remember.”
“How many levels are there really?”
Charlotte puts down her espresso.
“Four main levels, plus a few supplementary views. Why?”
“Because Sam just asked me where the servers are, and then she asked me whether it’s allowed for a New Zealand subscriber’s data to live in Sydney, and I realised the existing diagrams have no way to answer either question.”
Charlotte’s expression shifts. It’s the expression she gets when someone in the team asks exactly the question she was waiting for. The question that tells her the team is ready for the next layer.
“You need a Deployment view.”
Priya gets her notebook.
Deployment views
Charlotte pours herself a second espresso because this is going to take at least fifteen minutes and she wants to explain it properly.
“The C4 model Simon Brown originally described has four main levels. Context, Container, Component, Code, and then a set of what he calls supplementary views. One of those is the Deployment view. It’s the diagram you draw when the question stops being what is the system and starts being where does the system live.”
She draws on the whiteboard.
“The Container diagram tells you that Greenbox has four containers: Subscription, Billing, Supply Matching, Fulfilment. It’s a logical diagram. It describes what is. The Deployment diagram takes the same containers and maps each one to where it runs. The containers don’t change. What changes is that each container is now shown inside a region, or an environment, or a data centre, whatever deployment nodes make sense for your system.”
“Like a physical architecture diagram.”
“Yes. Except instead of drawing servers on the diagram, you draw deployment nodes, which could be AWS regions, Kubernetes clusters, VMs, physical machines, or any combination. The point is that a single container from the C2 diagram can appear in multiple places on the deployment diagram. Your Subscription service currently appears once in Sydney. After New Zealand, it might appear once in Sydney and once in Auckland. Same container, two deployments.”
Priya writes this down.
“And the database?”
“The database is a deployment node just like the service. You show where it lives. You show which services connect to which database. You show the network links between regions. And you label each link with whatever matters, latency, protocol, whether it crosses a boundary that someone cares about.”
“Like data residency.”
“Yes. The Deployment diagram is often where data residency becomes visible for the first time. Most teams never draw one until they go multi-region. And then the first thing the diagram shows them is that they have no idea where half their data is.”
Sam, who has been standing behind Priya’s shoulder, makes a small approving noise.
What Priya knew she didn’t know
Priya has been putting off a thought for most of the morning and now she has to face it. She does not know, with confidence, where every piece of Greenbox data lives.
She knows the main PostgreSQL databases are in ap-southeast-2. She set them up. She manages the backups. Those are solid.
She does not know, off the top of her head:
- Where the Mailgun logs of outbound emails are stored. Mailgun has regional infrastructure but Greenbox signed up in the early days without picking one.
- Where Stripe’s record of Greenbox’s subscribers lives. Stripe has multiple regions too.
- Where the Redis cache in front of the subscription service is actually running. It’s a managed service in ap-southeast-2 but she’s not sure whether the provider has multi-region replication turned on by default.
- Where the backups of the PostgreSQL databases go. She set up S3 backups but she cannot remember if the S3 bucket is in Sydney or if she accidentally picked us-east-1 when she was setting it up at 11pm one night.
- Where Mailgun’s bounce logs live.
- Where Segment’s analytics events are collected from (and what region they sink to).
Six things. She knows they exist. She doesn’t know where they run. That’s the entire problem Sam is asking about, distilled into a checklist. And she is the senior backend developer at the company. If she doesn’t know, nobody does.
“I’m going to make a list,” she tells Charlotte. “Of every external thing we use and every internal thing, and next to each one I’m going to write ‘I know this runs in [region]’ or ‘I don’t know.’”
“Good. That’s Phase One of every deployment mapping exercise I’ve ever run. You can’t draw a diagram of things you don’t know the location of.”
“Phase Two?”
“Find out. Not guess. Look at the actual config. Get the actual answer. Write it down.”
“Phase Three?”
“Draw the current state. Before you draw the future state. You need to be able to see what is, honestly, before you can decide what should be.”
Maya sits in
Maya comes by at ten and Priya explains what’s happening. Maya’s face does the thing it does when she’s trying to look more relaxed than she actually feels. She nods a lot. She asks useful questions. But under the nods she’s nervous, because until this conversation she thought the New Zealand launch was mostly a question of farm relationships and subscriber onboarding, and now it turns out there’s an entire category of unknowns she hadn’t been tracking.
“How bad is this?” Maya asks.
Charlotte, who is good at exactly this kind of question, says the honest version.
“It’s not bad. It’s normal. Every company that goes from one country to two discovers this at roughly the same moment. The question isn’t whether you’re behind, you’re not, you’ve asked the question before the launch, which is earlier than most teams manage. The question is how much work it’s going to be, and the answer is: a couple of weeks of investigation and maybe a month of implementation depending on what you find. Not six months. Not a blocker.”
Maya nods. Her shoulders come down half an inch.
“Okay. Draw the diagram. Tell me what we find. I’ll hold the team back from promising Nina a launch date until we have the answers.”
That last line is the thing Maya has learned from the last four years. Don’t promise the launch date until the unknowns are known. She learned it the hard way. She won’t unlearn it for this.
The current-state Deployment view
Priya and Sam sit down together at a quiet table with a laptop, the existing C2 diagram, and a shared document. Priya writes, Sam asks questions.
They go through every container.
Subscription service. Runs on AWS Elastic Container Service in ap-southeast-2 (Sydney). Two tasks behind an Application Load Balancer. Backed by Amazon RDS for PostgreSQL, also in ap-southeast-2, with backups to S3 in ap-southeast-2 (Priya checks; she did pick Sydney back then, thankfully).
Billing service. Same deployment pattern. ap-southeast-2. RDS in ap-southeast-2. Talks to Stripe’s API, whose edge is global but whose primary data centres are in the US.
Supply Matching service. Same pattern. ap-southeast-2. One additional piece: it reads from a Redis cache, ElastiCache in ap-southeast-2, which Priya confirms via the console. She also confirms the Redis doesn’t have cross-region replication turned on. Good. One fewer unknown.
Fulfilment service. Same pattern. ap-southeast-2. Also talks to the courier’s API, the courier is an Australian company and their API endpoint resolves to servers in Sydney.
Mailgun. After ten minutes of clicking through the Mailgun dashboard, Priya discovers the account is configured to use Mailgun’s US region. Meaning every transactional email Greenbox has ever sent has had its metadata logged in the United States. She stares at this for a moment. It’s not necessarily a problem, email metadata isn’t typically considered subscriber personal data under most regimes, but it’s the kind of thing you want to know before someone asks.
Stripe. Stripe’s customer records live wherever Stripe decides to put them. Stripe handles the data residency question internally for most jurisdictions, and for New Zealand specifically, Stripe uses its global infrastructure. This is a contract Greenbox doesn’t control.
Segment. Priya logs in, checks the workspace settings, discovers they’re on the Segment US region. Another thing they didn’t know.
Sentry (error reporting). US.
Datadog (metrics and logs). They’re on the AU region. Priya remembers picking it explicitly because Datadog’s AU region launched the same month Greenbox signed up and she felt clever about it.
Sam writes the list on a sheet of paper because she wants a physical copy. When she’s done, the list looks like this:
| Thing | Region | Who decides |
|---|---|---|
| Subscription service + DB | Sydney (AU) | Us |
| Billing service + DB | Sydney (AU) | Us |
| Supply Matching + DB + Redis | Sydney (AU) | Us |
| Fulfilment service + DB | Sydney (AU) | Us |
| Mailgun email logs | United States | Mailgun account setting |
| Stripe customer data | Global (Stripe's choice) | Stripe |
| Segment events | United States | Segment workspace |
| Sentry errors | United States | Sentry project |
| Datadog metrics/logs | Sydney (AU) | Datadog workspace |
Nine rows. Four of them are things Greenbox runs directly. Five are third parties. Three of the nine are in the United States, which Priya had not previously thought of as relevant. Now it’s very relevant.
“Okay,” Sam says. “This is the thing I wanted. This list. Now we know what we’re looking at.”
The future-state Deployment view
Priya writes the future-state deployment diagram in Structurizr DSL. The DSL supports deployment views natively, she has never used the feature before, and it takes her twenty minutes of reading the documentation to get the syntax correct.
The future state, roughly:
deploymentEnvironment "Production" {
awsSydney = deploymentNode "AWS ap-southeast-2 (Sydney)" {
tags "AU region"
subscriptionAU = containerInstance subscription
billingAU = containerInstance billing
supplyMatchingAU = containerInstance supplyMatching
fulfilmentAU = containerInstance fulfilment
subscriptionDbAU = deploymentNode "RDS PostgreSQL" {
containerInstance subscription.database
}
// ...etc for each container's database
}
awsAuckland = deploymentNode "AWS ap-southeast-4 (Melbourne)" {
// Note: no Auckland AWS region exists; closest is Melbourne for NZ
tags "NZ region"
subscriptionNZ = containerInstance subscription
billingNZ = containerInstance billing
supplyMatchingNZ = containerInstance supplyMatching
fulfilmentNZ = containerInstance fulfilment
subscriptionDbNZ = deploymentNode "RDS PostgreSQL" {
containerInstance subscription.database
}
// ...etc
}
sharedIdentity = deploymentNode "Shared identity service (Sydney)" {
tags "cross-region"
}
// Cross-region relationships
subscriptionNZ -> sharedIdentity "authenticates via (TLS, Tasman crossing)"
subscriptionAU -> sharedIdentity "authenticates via"
supplyMatchingAU -> supplyMatchingNZ "replicates farm availability for AU-NZ corporate boxes"
}
The interesting bits are the cross-region edges. Priya has drawn three questions into the diagram that she does not yet know how to answer:
- Identity. If a subscriber logs in, does the identity lookup hit a shared service (requiring a Tasman crossing), or is identity duplicated per region? Duplicated is faster but introduces a sync problem. Shared is simpler but slower.
- Farm availability replication. The corporate catering program includes some Australian farms that supply both markets. Does their availability data need to exist in both regions?
- The event bus. Right now there’s no event bus at all, services talk to each other directly via HTTP within a region. But if there were a bus, would it be per-region or shared? The diagram surfaces the question by not showing one.
She draws the future state deliberately incomplete. It’s a deployment view with open questions on it, and that’s the point, the diagram is a place to park questions, not pretend to answer them.
Maya sees it
At four o’clock, Priya shows the rendered deployment view to Maya and Charlotte in the small meeting room. It has two large boxes. AU region, NZ region, with the same four containers in each, the databases underneath, and three dashed arrows crossing the middle between them. Each dashed arrow has a label ending in a question mark.
Maya looks at it for a long time.
“This is what I needed on Friday.”
“I know,” Priya says.
“If I’d had this diagram on Friday, I would have asked Nina the correct questions about data residency. I asked her whether she was okay with her data being on our servers and she said yes. I didn’t ask her whether her data was allowed to be on our servers by the New Zealand privacy authority. I don’t even know who that is.”
“It’s the Office of the Privacy Commissioner.”
“I didn’t know that.”
“Neither did I until this afternoon.”
Charlotte, who has been quiet through most of this, says the thing she’s been waiting to say.
“The Container diagram tells you what the system is. The Deployment diagram tells you where it lives. And until today, Greenbox was only asking the first question. That’s completely normal for a single-country company. It’s not sustainable for a multi-country company. Most companies don’t draw a Deployment view until they need one. You need one.”
Maya nods. “And the open questions?”
“The open questions are exactly the conversation you should be having this week. Not committing to answers. Finding out what the answers need to be. The diagram is the forcing function. It makes the unknowns sit on the page so they can’t be avoided.”
Sam makes a list
Sam, who started this whole thing by asking two questions in the morning, has been writing a different list. Her list is different from Priya’s. Sam’s list is a list of things that have to be decided before Greenbox can launch in New Zealand.
Her list:
- Where will New Zealand subscriber data physically live, and what does the NZ Privacy Act 2020 require? (She has already sent a text to Ren asking for a recommendation for an Australian lawyer who understands NZ data law.)
- Is Stripe’s handling of NZ subscribers compliant with the Act, and do we need to do anything on our side?
- Which third parties will we need to reconfigure, and which ones will we need to swap out? (Mailgun’s US region is top of the list.)
- Do we run two separate deployments, or one deployment with data partitioned by subscriber country?
- What’s the identity model, shared, replicated, or per-region?
- What gets replicated across the Tasman, and what stays local?
- If the Tasman link goes down, what still works?
She shows the list to Maya. Maya adds an eighth:
- Does Nina have to agree to all of this, and what happens if she disagrees?
Seven technical decisions and one human decision. That last one is Maya’s, she’s going to be the one to walk Nina through it, and she’s going to have to be honest about the fact that some things will change from how Harvest Circle runs today.
Priya commits the diagram
Before she leaves that evening, Priya commits the deployment view to the repository. She puts it in docs/architecture/deployment/ because she suspects there will be more than one deployment view over time. She writes a README.md alongside it that says:
This is the first deployment view for Greenbox. It was drawn on 4 November 2026, the day after the decision to acquire Harvest Circle in New Zealand, because Sam asked “where are the servers?” and the existing C1 and C2 views had no answer. The view is intentionally incomplete. The dashed arrows with question marks are open questions that the team is working through. When an open question is resolved, update the diagram, keep the old version in version control history, and write a brief note explaining what changed.
The Container diagram tells you what Greenbox is. This view tells you where it lives. The two views together tell you enough to have a conversation with a regulator, a subscriber, or a new engineer about what the system actually does and where it does it.
This view will get more detailed over time. It will probably spawn a per-region variant for NZ specifically. Keep them all in this directory. Keep them all current.
She pushes. The GitHub Action renders. The rendered diagram appears in the internal docs site.
Sam sees the Slack notification and opens the diagram on her phone on the bus home. She stares at the dashed arrows and the question marks. She thinks about Nina in Auckland, and about the farm partners in the Waikato, and about a subscriber in Wellington clicking “cancel subscription” and the request travelling across the Tasman and hitting a database in Sydney and coming back with an acknowledgement three hundred milliseconds later.
Three hundred milliseconds is nothing, in one sense. It’s less than a heartbeat. It’s less than the blink of an eye. It’s less than the gap between saying a word and hearing your own voice.
It is also, Sam thinks, a very long distance for a piece of data to go before it gets permission to move.
She gets off at her stop and walks home thinking about where the bytes live.
Maya writes in her notebook
Back at home that evening, Maya opens her notebook, the same one she writes in after every big day, and writes two sentences:
The diagrams we drew for Greenbox-in-one-country don’t work for Greenbox-in-two-countries. I didn’t know that until today. I’ll remember it for the third country.
Underneath she adds:
Ask Nina about data residency before the next call. Don’t wait for her to ask us.
She closes the notebook. Sam’s list is pinned to the fridge. Priya’s deployment view is in the repo. Charlotte’s going to be on a call with Maya and Nina next Tuesday with the diagram open. The week is going to be long.
The conversation about where the bytes actually live is not going to stop being hard. The next post in this thread is Priya and Tom working through exactly that: Data Residency: Where the Bytes Live.
Related
For the workshop pattern behind this kind of session, running a C4 modelling workshop, including when to draw deployment views, see The Workshop: C4 Modelling. For the earlier posts on how the first C1 and C2 came about, see Drawing the System: From Event Storm to C4 and When a Container Earns Its Own Zoom.