---
title: "Two-sided markets and platform competition"
description: "Model platform markets as two-sided network games with cross-side externalities, analyzing pricing structure, platform competition, tipping, and multihoming."
author: "Raban Heller"
date: 2026-05-08
date-modified: 2026-05-08
categories:
- network-games
- two-sided-markets
- platform-economics
- network-externalities
keywords: ["two-sided markets", "platform competition", "Rochet-Tirole", "network externalities", "game theory"]
labels: ["network-economics", "industrial-organization"]
tier: 1
bibliography: ../../../references.bib
vgwort: "TODO_VGWORT_network-games_two-sided-markets-platforms"
image: thumbnail.png
image-alt: "Line plot showing platform market shares under network externalities with tipping dynamics using the Okabe-Ito palette"
citation:
type: webpage
url: https://r-heller.github.io/equilibria/tutorials/network-games/two-sided-markets-platforms/
license: "CC BY-SA 4.0"
draft: false
has_static_fig: true
has_interactive_fig: true
has_shiny_app: false
---
```{r}
#| label: setup
#| include: false
library(ggplot2)
library(dplyr)
library(tidyr)
library(plotly)
okabe_ito <- c("#E69F00", "#56B4E9", "#009E73", "#F0E442",
"#0072B2", "#D55E00", "#CC79A7", "#999999")
theme_publication <- function(base_size = 12) {
theme_minimal(base_size = base_size) +
theme(plot.title = element_text(size = base_size * 1.2, face = "bold"),
plot.subtitle = element_text(size = base_size * 0.9, color = "grey40"),
axis.line = element_line(color = "grey30", linewidth = 0.3),
panel.grid.minor = element_blank(), legend.position = "bottom",
plot.margin = margin(10, 10, 10, 10))
}
```
## Introduction & motivation
Two-sided markets are economic platforms that serve two distinct groups of users, creating value by facilitating interactions between them. Ride-sharing services like Uber connect drivers and riders; app stores connect developers and consumers; credit card networks connect merchants and cardholders; real estate platforms connect landlords and tenants. The defining feature of these markets is the presence of cross-side network externalities: the value a user on one side derives from the platform depends on the number or quality of users on the other side. A rider values Uber more when more drivers are available, and drivers value Uber more when more riders use the platform. This interdependence creates strategic dynamics that differ fundamentally from traditional one-sided markets.
The seminal work of Rochet and Tirole formalized the economics of two-sided markets and established a key insight: the price structure matters, not just the price level. A platform that charges the total fee $P = p_B + p_S$ (buyer price plus seller price) will attract very different participation levels depending on how that total is split between the two sides. Credit card companies famously subsidize cardholders (often with rewards programs) while charging merchants interchange fees, because cardholders are the more price-sensitive side and their participation is necessary to attract merchants. This asymmetric pricing is not predatory or irrational -- it is the equilibrium outcome of optimal platform design in the presence of cross-side externalities.
Platform competition adds another strategic layer. When two or more platforms compete for users on both sides, the dynamics can produce market tipping, where a small initial advantage compounds through network effects until one platform dominates entirely. Alternatively, platforms may coexist if users multihome -- that is, participate on multiple platforms simultaneously. The conditions under which tipping versus coexistence occurs depend on the strength of network externalities, the degree of platform differentiation, and user switching costs. Understanding these dynamics is essential for antitrust analysis, platform regulation, and competitive strategy.
This tutorial builds a simulation model of two-sided market competition between two platforms. We model user adoption decisions as a participation game where each potential user joins the platform offering the highest expected utility, accounting for cross-side network effects. We implement iterative best-response dynamics to find equilibrium participation levels and examine how platform pricing, externality strength, and initial conditions determine whether the market tips to monopoly or sustains duopoly. The simulation reveals the critical role of expectations and coordination: small differences in user beliefs about future platform size can cascade into vastly different market outcomes.
## Mathematical formulation
Consider two platforms $k \in \{1, 2\}$, each serving buyers (B) and sellers (S). Let $n_B^k$ and $n_S^k$ denote the mass of buyers and sellers on platform $k$. A buyer's utility from joining platform $k$ is:
$$
u_B^k = \alpha_B \cdot n_S^k - p_B^k + \delta_B^k
$$
where $\alpha_B > 0$ is the cross-side externality parameter, $p_B^k$ is the buyer-side price, and $\delta_B^k$ captures platform-specific differentiation. Similarly for sellers:
$$
u_S^k = \alpha_S \cdot n_B^k - p_S^k + \delta_S^k
$$
With total potential mass normalized to 1 on each side and logit adoption, the equilibrium participation satisfies the fixed-point system:
$$
n_B^k = \frac{\exp(u_B^k)}{\sum_{j} \exp(u_B^j) + 1}, \quad n_S^k = \frac{\exp(u_S^k)}{\sum_{j} \exp(u_S^j) + 1}
$$
where the $+1$ in the denominator represents the outside option of not joining any platform. A tipping equilibrium occurs when $n_B^1 \to 1, n_S^1 \to 1$ and $n_B^2 \to 0, n_S^2 \to 0$ (or vice versa).
## R implementation
We simulate the participation game for two competing platforms under varying externality strengths, finding equilibrium market shares through iterated best response.
```{r}
#| label: two-sided-market-sim
set.seed(42)
simulate_platform <- function(alpha_B, alpha_S, p_B, p_S,
delta, n_iter = 100) {
n_B <- c(0.5, 0.5)
n_S <- c(0.5, 0.5)
history <- tibble()
for (t in seq_len(n_iter)) {
u_B <- alpha_B * n_S - p_B + delta
u_S <- alpha_S * n_B - p_S - delta * 0.5
exp_B <- exp(u_B)
exp_S <- exp(u_S)
n_B_new <- exp_B / (sum(exp_B) + 1)
n_S_new <- exp_S / (sum(exp_S) + 1)
n_B <- 0.7 * n_B_new + 0.3 * n_B
n_S <- 0.7 * n_S_new + 0.3 * n_S
history <- bind_rows(history,
tibble(t = t, side = rep(c("Buyers", "Sellers"), each = 2),
platform = rep(c("Platform 1", "Platform 2"), 2),
share = c(n_B, n_S)))
}
list(eq_B = n_B, eq_S = n_S, history = history)
}
alpha_values <- seq(0.5, 4.0, by = 0.25)
tipping_results <- tibble()
for (a in alpha_values) {
res <- simulate_platform(
alpha_B = a, alpha_S = a,
p_B = c(1.0, 1.0), p_S = c(1.0, 1.0),
delta = c(0.1, -0.1))
hhi <- sum((res$eq_B / sum(res$eq_B))^2)
tipping_results <- bind_rows(tipping_results,
tibble(alpha = a,
share_B1 = res$eq_B[1], share_B2 = res$eq_B[2],
share_S1 = res$eq_S[1], share_S2 = res$eq_S[2],
hhi_buyers = hhi))
}
detail_run <- simulate_platform(
alpha_B = 2.5, alpha_S = 2.5,
p_B = c(1.0, 1.0), p_S = c(1.0, 1.0),
delta = c(0.1, -0.1))
cat("=== Two-Sided Market Equilibrium Results ===\n\n")
cat("Externality strength -> Market concentration (buyer-side HHI):\n")
for (a in c(0.5, 1.0, 2.0, 3.0, 4.0)) {
row <- tipping_results %>% filter(abs(alpha - a) < 0.01)
cat(sprintf(" alpha = %.1f: P1 share = %.3f, P2 share = %.3f, HHI = %.3f\n",
a, row$share_B1, row$share_B2, row$hhi_buyers))
}
cat(sprintf("\nDetailed run (alpha=2.5): P1 buyers=%.3f, P1 sellers=%.3f\n",
detail_run$eq_B[1], detail_run$eq_S[1]))
```
## Static publication-ready figure
The figure shows how market concentration increases with the strength of cross-side network externalities, illustrating the tipping phenomenon.
```{r}
#| label: fig-platform-tipping-static
#| fig-cap: "Market tipping in two-sided platform competition. Top panel: equilibrium market shares of Platform 1 (advantaged) and Platform 2 on the buyer side as a function of cross-side externality strength. Bottom panel: buyer-side HHI concentration index. As externalities strengthen beyond alpha approximately 2.0, the market tips toward monopoly. Equal prices; Platform 1 has a small differentiation advantage (delta = 0.1). Okabe-Ito palette."
#| dev: [png, pdf]
#| fig-width: 9
#| fig-height: 6
#| dpi: 300
share_long <- tipping_results %>%
select(alpha, share_B1, share_B2) %>%
pivot_longer(cols = c(share_B1, share_B2),
names_to = "platform", values_to = "share") %>%
mutate(platform = ifelse(platform == "share_B1",
"Platform 1 (advantaged)",
"Platform 2"))
p1 <- ggplot(share_long, aes(x = alpha, y = share, color = platform)) +
geom_line(linewidth = 1.1) +
geom_point(size = 1.5) +
scale_color_manual(values = okabe_ito[c(1, 5)], name = NULL) +
labs(title = "Market tipping under cross-side network externalities",
subtitle = "Two-platform competition with symmetric pricing",
x = expression(alpha ~ "(externality strength)"),
y = "Buyer-side market share") +
geom_hline(yintercept = 0.5, linetype = "dashed", color = "grey60") +
annotate("text", x = 3.5, y = 0.52, label = "Equal split",
color = "grey50", size = 3) +
theme_publication()
p_static <- p1
p_static
```
## Interactive figure
The interactive version provides detailed information about both buyer and seller participation at each externality level when hovering.
```{r}
#| label: fig-platform-tipping-interactive
tip_interactive <- tipping_results %>%
mutate(text_label = paste0("Externality: ", round(alpha, 2),
"\nBuyers P1: ", round(share_B1, 3),
"\nBuyers P2: ", round(share_B2, 3),
"\nSellers P1: ", round(share_S1, 3),
"\nSellers P2: ", round(share_S2, 3),
"\nHHI: ", round(hhi_buyers, 3)))
p_int <- ggplot(tip_interactive,
aes(x = alpha, y = share_B1, text = text_label)) +
geom_line(color = okabe_ito[1], linewidth = 1) +
geom_line(aes(y = share_B2), color = okabe_ito[5], linewidth = 1) +
geom_point(color = okabe_ito[1], size = 2) +
geom_point(aes(y = share_B2), color = okabe_ito[5], size = 2) +
labs(title = "Platform market shares (hover for details)",
x = "Externality strength",
y = "Buyer-side share") +
theme_publication()
ggplotly(p_int, tooltip = "text") |>
config(displaylogo = FALSE,
modeBarButtonsToRemove = c("select2d", "lasso2d"))
```
## Interpretation
The simulation results vividly demonstrate the tipping phenomenon that is central to two-sided market theory. When cross-side externalities are weak ($\alpha < 1$), the two platforms coexist with nearly equal market shares despite Platform 1's small differentiation advantage. In this regime, the network effect is not strong enough to amplify the initial asymmetry, and both platforms maintain viable user bases on both sides. The market structure resembles standard differentiated product competition, where each firm serves its natural customer segment.
As externality strength increases past the critical threshold (around $\alpha \approx 2.0$ in our parameterization), the market undergoes a dramatic phase transition. Platform 1's small initial advantage in buyer-side differentiation attracts slightly more buyers, which makes it more attractive to sellers through the cross-side externality, which in turn attracts even more buyers, creating a self-reinforcing feedback loop. Platform 2's market share declines rapidly, approaching near-zero participation at high externality levels. This is the tipping equilibrium: one platform captures essentially the entire market while the other becomes unviable. The HHI concentration index rises from approximately 0.5 (equal duopoly) to nearly 1.0 (monopoly).
This tipping dynamic has profound implications for platform strategy and competition policy. For platform managers, the results underscore the importance of early-stage growth. The initial differentiation advantage ($\delta = 0.1$ in our model) is objectively small, yet it is sufficient to determine the long-run market winner when externalities are strong. This explains the aggressive subsidization and below-cost pricing that characterize platform launches: the goal is to establish a participation advantage before the tipping dynamic takes hold. Uber's early rider subsidies, Amazon Marketplace's seller incentive programs, and payment networks' cardholder rewards all follow this logic. The short-run losses are investments in triggering the tipping dynamic that produces long-run monopoly rents.
For competition policy, the results illustrate why two-sided markets require different analytical frameworks than traditional markets. A regulator who observes Platform 1 pricing below cost on the buyer side might suspect predatory pricing, but in a two-sided market this is the natural equilibrium pricing structure -- the platform subsidizes the side with higher price sensitivity and extracts surplus from the other side. The Rochet-Tirole framework formalized this insight by showing that the socially optimal price structure in two-sided markets generally involves one side paying below marginal cost. Antitrust analysis must therefore consider the total price across both sides and the role of cross-side externalities, rather than examining each side in isolation.
The logit participation model we employ has the advantage of producing smooth adoption curves and unique equilibria for given parameters, but it may understate the discreteness of real adoption decisions. In practice, users often make binary join-or-not decisions rather than continuous participation adjustments, and they may exhibit inertia or switching costs that the logit model does not capture. The damping factor (0.7/0.3 weighting) in our iterative dynamics approximates adjustment costs and prevents unrealistic instantaneous tipping. Real platforms experience tipping over months or years rather than in simulation iterations, and the process can be reversed by sufficiently aggressive competitive entry or regulatory intervention.
Multihoming -- users joining both platforms simultaneously -- is another important phenomenon our single-homing model does not capture. When buyers multihome but sellers single-home (common in credit card markets), the competitive dynamics change qualitatively: platforms compete on the seller side through exclusive deals while buyers divide their activity across platforms based on merchant acceptance. Extending the model to allow differential multihoming rates on each side is a natural next step.
## Extensions & related tutorials
Two-sided market analysis connects to several related topics in network games and mechanism design.
- [Network formation strategic](../../network-games/network-formation-strategic/)
- [Public goods on networks](../../network-games/public-goods-on-networks/)
- [Congestion games and potential](../../network-games/congestion-games-potential/)
- [Braess paradox routing](../../network-games/braess-paradox-routing/)
## References
::: {#refs}
:::