Skip to content

Orchestrate

The whole portfolio, in one graph

Most companies do not ship one product. Stripe runs Payments, Billing, Connect, Radar, and Terminal: separate products on shared infrastructure, serving overlapping customers. Kept as separate files, the relationships between them go missing: the dependency, the shared customer, the metric that should add up and does not. The portfolio layer types those relationships, so a question about how two products connect resolves to a traversal of one graph.

01Two Axes

One organisation, two ways to slice it

A portfolio answers a strategic question: where does the company invest? An org chart answers a different one: who owns what? UPG keeps them as two independent axes over the same products. Collapsing the two into one tree forces a product to live where its funding sits or where its team sits, and the other fact is lost.

At Stripe, Radar is funded under the Core Payments portfolioportfolioA grouping of products by strategic axis and owned by the Acceptance & Risk product areaproduct_areaA grouping of products by organisational axis. Those are two separate facts about one productproductThe product being created, the root of the graph. A product can sit on one axis, both, or neither, and each axis nests to any depth.

Stripe
organizationorganizationThe top-level organisational entity
Organisational axis: who owns what
organised intoorganization_organised_into_product_area
Payments Platform
product_areaproduct_areaA grouping of products by organisational axis
containsproduct_area_contains_product_area
Acceptance and Risk
product_areaproduct_areaA grouping of products by organisational axis
containsproduct_area_contains_product
Radar
productproductThe product being created, the root of the graph
Strategic axis: where we invest
invests viaorganization_invests_via_portfolio
Core Payments
portfolioportfolioA grouping of products by strategic axis
containsportfolio_contains_portfolio
Growth bets
portfolioportfolioA grouping of products by strategic axis
containsportfolio_contains_product
Radar
productproductThe product being created, the root of the graph

Radar sits in the Acceptance & Risk team’s remit and draws from the Core Payments investment line. One product, placed on two independent axes: a nested product area on the organisational side, a nested portfolio on the strategic side. A product may belong to an area, a portfolio, both, or neither.

02The Registry

The shared vocabulary the products agree on

The moment two products both have “customers”, they begin to disagree about what a customer is. Billing tracks a subscription; Connect tracks a connected account; Radar tracks a risk profile. Each is reasonable on its own. Together they make “active customers” a number nobody can total.

The registry is the shared-vocabulary tier. The canonical Customer is defined once, and each productproductThe product being created, the root of the graph registers its local copy as an instance_of it. The definitions stay linked, so portfolio_validate flags the moment an instance drifts from canon, while the divergence is still small.

Beforedrift
Billing
Customer { email, subscription_status }
defines its own
Connect
Account { email, country, payouts }
defines its own
Radar
RiskProfile { email, risk_score }
defines its own

Three products, three definitions of the same person. “Active customers” means something different in each, so the company can never add them up.

Afterportfolio_validate ✓
Customer
registry/customer
canonical, registry
instance ofinstance_of
Billing
Customer → registry/customer
instance
Connect
Customer → registry/customer
instance
Radar
Customer → registry/customer
instance

Define it once in the portfolio registry; each product registers an instance. portfolio_validate flags an instance the moment its definition drifts from canon.

03Cross-Product Edges

The relationships that usually go missing

Between products, the relationships that matter become typed edges, stored at the portfolio level rather than buried inside any one product. Billing, Connect, Radar, and Terminal all depend on the Payments productproductThe product being created, the root of the graph, so a change to the core names every product that feels it, before it ships.

Billing shares a persona with Connect, so a research insight about that developer is relevant to both at once; and a no-code Payment Link cannibalises the sales-led integration, turning a surprise into a tradeoff somebody decided on purpose. That is three of a dozen cross-product edge types, shares_competitor, succeeds, rolls_up_to, and the rest, each with a direction and a meaning.

Four products depend on the core:
Billing
productproductThe product being created, the root of the graph
Connect
productproductThe product being created, the root of the graph
Radar
productproductThe product being created, the root of the graph
Terminal
productproductThe product being created, the root of the graph
depends onproduct_depends_on_product
Paymentsanchor
change the core, see who feels it
productproductThe product being created, the root of the graph
And the relationships that usually go missing become edges:
Billing
productproductThe product being created, the root of the graph
shares persona withproduct_shares_persona_with_product
Connect
productproductThe product being created, the root of the graph
Payment Links
productproductThe product being created, the root of the graph
cannibalisesproduct_cannibalises_product
Sales-led integration
productproductThe product being created, the root of the graph

Between products, the relationships that matter become typed edges, stored at the portfolio level rather than buried inside any one product. Four products depend on Payments, Billing shares a persona with Connect, and Payment Links cannibalises the sales-led integration. That is three of a dozen cross-product edge types, each with a direction, a meaning, and a use case, so a surprise becomes a tradeoff somebody decided on purpose.

04The Cascade

Numbers and goals that roll up across products

Typing the relationships lets numbers and goals connect across levels. Billing’s monthly recurring revenue metricmetricA unified metric that measures progress, health, or behaviour across the product rolls_up_to Stripe’s total revenue run-rate; Billing’s objectiveobjectiveA strategic goal (OKR) to make recurring revenue easier contributes_to the company objective to grow payment volume.

When the leaf metric moves, the company north-star moves with it, because the edge between them was recorded once and stays in place. The cascade runs the other way too: ask what a company goal rests on, and the graph names the products carrying it.

Stripe
Total revenue run-rate
company, north-star
rolls up torolls_up_to
Billing
Monthly recurring revenue
product, metric
Stripe
Grow total payment volume
company, objective
contributes tocontributes_to
Billing
Make recurring revenue effortless
product, objective

A number moves on one product and the portfolio sees it at the top. The metric cascade (rolls_up_to) and the OKR cascade (contributes_to) keep leaf work legible at company scale, without a quarterly spreadsheet to reconcile it.

05Beyond What It Owns

The watched field, in the same portfolio

The portfolio so far models what the organisation owns. The same tier extends to what it does not: a competitorcompetitorA competing product or company is a watched graph (member_kind: watched) inside the same portfolio, scored differently so it never drags the company health score down.

From there the competitive picture becomes structure. Every rival move is one dated competitor signalcompetitor_signalA competitor signal entity typed back onto a feature the company ships; parity becomes a traversal with the assessment on the edge; and every rival is placed against one shared classification. The Competitive Intelligence use case walks the whole motion.

Stripe
organisation
Under management
member_kind: product
Payments
health scored ✓
productproductThe product being created, the root of the graph
Billing
health scored ✓
productproductThe product being created, the root of the graph
Radar
health scored ✓
productproductThe product being created, the root of the graph
Watched
member_kind: watched
Adyen
not scored · no drag
competitor graph
Checkout.com
not scored · no drag
competitor graph
Braintree
not scored · no drag
competitor graph

A competitor is a graph the company does not own. Marked member_kind: watched, it sits in the same portfolio as the products it competes with, but portfolio_validateand the coverage scorers skip it: an empty discovery region in Adyen’s graph is not a gap in the owned product.

06Where To Go Next

The portfolio layer is optional and additive. A single-product file never has to know it exists; when the second product arrives, the same graph grows an organisational root, two axes, and a registry without rewriting what was already there. Follow a thread: