Code
library(buffer)
library(bigrquery)
library(dplyr)
library(ggplot2)
library(scales)
library(knitr)
# set bigquery project
bq_auth()Julian Winternheimer
January 12, 2026
We’re considering deprecating Start Page as a Buffer channel. This analysis estimates the potential MRR impact by calculating how much revenue we could lose from organizations that currently have Start Page channels connected.
The core assumption is that organizations need at least 4 channels to maintain their subscription. If removing Start Page drops them to 3 or fewer channels, we assume that some percentage will churn completely and use the Free plan.
Deprecating Start Page would put between $17K and $26K in MRR at risk from around 1991 Stripe customers with at least one Start Page connected.
The key insights:
The scenario analysis shows that the churn rate assumption for at-risk organizations makes an $8.5K difference in the estimate. Customer research with the 811 at-risk organizations would significantly improve the accuracy of this analysis.
This analysis only includes Stripe customers. Mobile app customers are excluded, so the actual impact would be somewhat higher.
For each paid organization with Start Page channels connected, I calculate:
We’re only looking at organizations on paid plans (Essentials, Essentials + Team Pack, Team, Agency) that currently have at least one Start Page channel connected.
The SQL query below returns around 1991 paying organizations on New Buffer plans with at least one Start Page connected, along with their MRR and channel counts.
It’s worth noting that this only includes Stripe customers. Those paying through one of the mobile apps are not included, so the actual impact could be slightly higher.
# query to join billing, mrr, and channel data
sql <- "
select
b.organization_id
, b.state
, b.plan
, c.mrr / 100 as mrr
, ch.active_channels
, ch.startpage_channels_connected
from dbt_buffer.core_organization_billing_records as b
inner join dbt_buffer.chartmogul_customers as c
on b.organization_id = c.organization_id
inner join dbt_buffer.core_organization_channel_counts as ch
on b.organization_id = ch.organization_id
where b.state = 'paid'
and b.plan in ('Essentials', 'Essentials + Team Pack', 'Team', 'Agency')
and ch.startpage_channels_connected > 0
"
# execute query
startpage_data <- bq_query(sql = sql)
# save raw data
saveRDS(startpage_data, "startpage_raw_data.rds")Below we’ll calculate the MRR impact for each organization. If removing Start Page drops them to 3 or fewer channels, we assume that they will churn and use the Free plan. Otherwise, the MRR impact is proportional to the number of Start Page channels connected.
# calculate mrr impact for each organization
impact_data <- startpage_data %>%
mutate(
# mrr per channel
mrr_per_channel = mrr / active_channels,
# channels remaining after start page removal
remaining_channels = active_channels - startpage_channels_connected,
# calculate impact based on remaining channels
mrr_impact = case_when(
# if 3 or fewer channels remain, assume complete churn
remaining_channels <= 3 ~ mrr,
# if 4+ channels remain, impact is proportional
remaining_channels >= 4 ~ mrr_per_channel * startpage_channels_connected,
# default case
TRUE ~ 0
),
# flag impact type
impact_type = case_when(
remaining_channels <= 3 ~ "Complete Churn",
remaining_channels >= 4 ~ "Partial Impact",
TRUE ~ "No Impact"
)
)The total MRR value of these 1991 organizations is around $80K. Of that, around $26K is at risk. Approximately 1180 organizations would have their MRR reduced by an amount proportional to the number of Start Page channels connected.
There are 811 organizations that would drop to 3 or fewer channels and could churn completely. This represents around $17K in MRR at risk, or 64.7% of the total impact.


The baseline assumption is that all 811 organizations with 3 or fewer channels after deprecation would churn completely. Let’s test what happens if only 25%, 50%, or 75% of those organizations actually churn.
# identify organizations at risk of complete churn
at_risk_orgs <- impact_data %>%
filter(impact_type == "Complete Churn")
# baseline partial impact (organizations with 4+ channels remaining)
baseline_partial_impact <- impact_data %>%
filter(impact_type == "Partial Impact") %>%
summarise(total_impact = sum(mrr_impact, na.rm = TRUE)) %>%
pull(total_impact)
# calculate scenarios
scenarios <- data.frame(
churn_rate = c(0.25, 0.50, 0.75, 1.00),
scenario = c("25% Churn", "50% Churn", "75% Churn", "100% Churn (Baseline)")
) %>%
mutate(
# organizations that actually churn
orgs_churned = ceiling(churn_rate * nrow(at_risk_orgs)),
# mrr from complete churn
complete_churn_mrr = churn_rate * sum(at_risk_orgs$mrr, na.rm = TRUE),
# mrr from partial impact for orgs that don't churn
# (use proportional impact calculation)
partial_impact_non_churned = (1 - churn_rate) * sum(at_risk_orgs$mrr_per_channel *
at_risk_orgs$startpage_channels_connected,
na.rm = TRUE),
# total impact
total_impact = baseline_partial_impact + complete_churn_mrr + partial_impact_non_churned
)
kable(scenarios,
digits = 0,
col.names = c("Churn Rate", "Scenario", "Orgs Churned",
"Complete Churn MRR", "Partial Impact (Non-Churned)", "Total Impact"),
caption = "MRR Impact Under Different Churn Rate Assumptions")| Churn Rate | Scenario | Orgs Churned | Complete Churn MRR | Partial Impact (Non-Churned) | Total Impact |
|---|---|---|---|---|---|
| 0 | 25% Churn | 203 | 4185 | 4026 | 17338 |
| 0 | 50% Churn | 406 | 8370 | 2684 | 20181 |
| 1 | 75% Churn | 609 | 12555 | 1342 | 23024 |
| 1 | 100% Churn (Baseline) | 811 | 16740 | 0 | 25866 |
Let’s visualize how the total impact changes with different churn assumptions.

The scenario analysis shows that the churn rate assumption is critical: