Building Relay

Part 0 · Chapter 0.2

Four people who will judge us

You will produce: A persona set including the invisible end user · about 75 minutes including the exercise

Source: Personas

In chapter 0.1 we compressed our product into one sentence, and that sentence names a customer: product engineering teams at B2B and marketplace software companies. It is a fine phrase for a pitch deck. It is useless for a design decision. A "team" does not read our documentation at 11pm, does not veto our contract, does not pull up a conversation to settle a dispute, and does not close an app in a basement car park because a message arrived twice. People do those things. Before we can write a single requirement, we need to know who they are.

So this chapter turns the positioning statement into people — four of them — and, more importantly, shows the derivation, because the deriving is what you will repeat for your own product at the end.

An ordering that should bother you

Our personas are ordered by how much influence they have over the product, and for a developer platform that ordering is unusual and deliberate: the person who uses the product, the person who pays for it, and the person who benefits from it are three different human beings — and the one who benefits never knows it exists.

Read that again, because it is the strangest fact about infrastructure products and the source of most of their design mistakes. A consumer app has one person to please. We have a chain: a developer chooses us, a director approves us, a support lead operates what the developer builds on us, and a delivery driver — who will never hear the name Relay — feels every latency spike we ship. Each of them can kill the product in a different way. Let's meet them in influence order.

Mai — the person the product is for

Mai is a senior full-stack engineer, twenty-nine, at a logistics coordination platform of about thirty engineers in Ho Chi Minh City. She works across React and Node, owns features end to end, and has shipped integrations with Stripe, Twilio, and two mapping providers. She is not an infrastructure specialist and — this matters — does not want to become one.

Her situation is chapter 0.1's two-week feature, personified. Her PM has committed to in-app messaging between dispatchers and drivers for next quarter. Mai spent a weekend prototyping with ws and Postgres; it worked beautifully with one server. Then she thought about two servers, and about what happens when a driver's phone drops off 4G mid-conversation — and she started reading vendor documentation instead.

Watch how she evaluates, because every step is a requirement wearing casual clothes. She reads the docs before signing up. She looks for a quickstart she can paste into a scratch file. She checks whether the WebSocket protocol documentation specifies reconnection and message ordering — to her, that detail is a proxy for whether the team behind the product is serious. She searches for the error-handling section before the feature list. Then she builds a throwaway prototype and shows a colleague.

What wins her: a working chat between two browser tabs in under ten minutes; an SDK that is transport and state, not components (her design system is not negotiable); an OpenAPI spec she can generate types from; error responses that name the offending field. What loses her, instantly: "Contact us for API access", a quickstart that does not run as written, or any mandatory UI kit. Her one-liner is the cleanest requirements document we will ever receive: "I don't need it to do everything. I need to know exactly what it does and what happens when it breaks."

David — the buyer who can veto what he never uses

David is a director of engineering, forty-one, reporting to the CTO and managing four teams — Mai's among them. He has built messaging before, at a previous company, and remembers exactly how long it took, which makes him sympathetic to buying. He is also the person who gets paged and the person who answers the customer security questionnaire. He will never read our SDK. He can still veto it.

His goals are a different genre from Mai's: keep the team on the product's actual differentiator; cost that scales predictably with revenue, not with surprises; pass a customer's security review without a fire drill; avoid a dependency that becomes impossible to leave. So his evaluation looks different too — he models our pricing at ten times current volume, reads our uptime history and how we communicated during incidents, asks where messages live and how they are deleted, and checks whether his team could extract their data if they left. And one question no dashboard answers: will this vendor still exist in three years?

What wins him is unglamorous: a pricing calculator with real numbers, a usage dashboard his team can watch daily, a documented export path, clear retention and deletion semantics. What loses him: opaque metering, SSO and audit logs locked behind an enterprise tier, any hint that support ends at a community forum. His one-liner deserves a place on our wall: "The build-versus-buy maths is easy. It's the buy-versus-regret maths I'm doing."

Priya — the person who uses it every day without integrating it

Priya leads customer support. Thirty-four, non-technical, entirely comfortable with dashboards. Her team handles disputes on the platform: when a driver claims a dispatcher never sent an address, she needs to see the conversation; when someone is abusive, she needs to act within minutes — without filing a ticket to engineering for a database query.

What she needs reads like a checklist of things naive chat systems delete: an accurate, ordered, timestamped record including edits and deletions; the ability to remove content and restrict a user herself; an audit trail of her own team's moderation actions; confidence in front of a data deletion request. Her one-liner: "I don't need it to be pretty. I need it to be complete and in the right order."

Here is the subtlety that makes Priya architecturally interesting: Relay does not serve Priya directly. She will use an internal tool that Mai builds. Our job is to make the moderation and history APIs complete and honest enough that Mai can build that tool in an afternoon. And yet Priya is the reason several of our most expensive decisions exist — soft-delete with tombstones instead of hard delete, an immutable edit history, moderation events in the webhook stream. She is proof that a persona can shape a schema without ever holding an API key.

Tuan — the user who will never hear our name

Tuan is a delivery driver, twenty-six, on a mid-range Android phone with intermittent 4G. He messages dispatchers between stops, often one-handed, often in a tunnel or a basement car park. He never signs up for Relay, never logs in to Relay, never hears the name Relay. Every latency spike is his.

What he needs sounds trivial and is anything but: messages that arrive. Messages that stay arrived after the app reconnects. Correct order. No duplicates when the network flaps. No battery drain from a connection retrying in a tight loop. He will never articulate any of this — the personas document is blunt about what he does instead: he just closes the app if it feels unreliable. And when he closes it, Mai's company loses a driver, David reads a churn report, and nobody files a bug against us.

Because Tuan cannot speak, we translate for him. Each need becomes a hard constraint on our protocol: reconnection with backfill from a cursor, not a full history reload. Server-assigned ordering that survives out-of-order delivery. Client-supplied idempotency keys so a retried send is not a duplicate. Exponential backoff with jitter on reconnect. Explicit sending / sent / failed states surfaced by the SDK so Mai's UI can be honest with him.

When they collide

Four people, four sets of needs — they will conflict, and a persona set that cannot resolve conflicts is decoration. So the personas document ends with an explicit resolution order: Tuan's reliability beats everything. Mai's integration speed beats feature breadth. David's cost predictability beats Mai's convenience. Priya's completeness beats storage efficiency.

Stop. Something should bother you here — we ordered the personas by influence, and Tuan came last: a constraint, not even a customer. Now the resolution order puts him first. Both orderings are correct, and the apparent contradiction is this chapter's real lesson. Influence measures who shapes product decisions — Tuan shapes none; he will never attend our roadmap review. The resolution order decides whose need wins when needs collide — and there Tuan wins outright, precisely because he has no voice. Mai can file a support ticket, David can escalate, Priya can complain to her account manager. Tuan can only leave. So we promote his needs from requests to non-negotiable constraints — the system's floor, not its feature list — to guarantee that his silence never means his loss. The quietest person at the table gets the strongest contract.

The document even shows the order earning its keep on a live conflict: end-to-end encryption would serve Tuan's privacy and please David's security reviewers — and it would make Priya's dispute resolution impossible and complicate Mai's integration considerably. Given the resolution order and the wedge market, it stays a non-goal. If that move feels familiar, it should: it is chapter 0.1's lesson wearing persona clothes — the reasoning is recorded, not assumed, so the decision can be honestly re-litigated when the inputs change.

Your turn

Now derive your own people — from the positioning statement you wrote in chapter 0.1, not from imagination. If you borrowed our practice idea (the veterinary clinic scheduler adding reminders and a client portal), keep using it.

Exercise 1 — derive the cast. Read your positioning statement and extract the candidates: who integrates your product, who pays for it, who operates whatever gets built on it day to day, and who merely experiences the result. Then write at least three personas using the field set our document uses — for each one:

Then order your personas by influence, and write one stated reason per rank — "she is the only person who can adopt us" is a reason; seniority is not.

Exercise 2 — the invisibility test. Find the persona who never chooses your product: never signs up, never sees your name, feels every defect. (The vet clinic's version is the pet owner who just wants the reminder to arrive before the appointment, not after.) Write down the constraints they impose on your system the way Tuan's needs became protocol requirements — each one a property the system must have, not a feature they would request.

Self-checks. Each answers yes or no:

  1. Does your influence ordering state a reason per rank, or is it org-chart seniority in disguise?
  2. Is every persona derivable from your positioning statement — could a stranger trace each one back to a phrase in it?
  3. Does at least one persona never sign up for your product?
  4. Is each "what loses them" an action your team could actually take by accident?

If check 2 fails, you have invented a persona your product does not serve. If check 3 fails, look harder — infrastructure and B2B products almost always have an invisible beneficiary, and missing them now means discovering their constraints in production.

Keep the persona set with your 0.1 artifacts, in the repository. Chapter 0.3 turns these people into journeys — the maps of where each of them can be lost.

Takeaways

If you read nothing else in this chapter, keep these: