flowchart TD
A["Choosing the primary endpoint"] --> B{"Mortality is the key outcome<br/>AND long follow-up is feasible?"}
B -->|Yes| OS["Overall Survival (OS)<br/>event = death, any cause"]
B -->|"No — need earlier readout"| C{"Measurable disease present,<br/>or disease-free after surgery?"}
C -->|"Disease present"| D{"Count death as an event?"}
D -->|"Yes (honest default)"| PFS["Progression-Free Survival (PFS)<br/>event = progression or death"]
D -->|"No (assess mortality separately)"| TTP["Time to Progression (TTP)<br/>event = progression only"]
C -->|"Disease-free post-surgery"| DFS["Disease-Free Survival (DFS)<br/>event = recurrence or death, from remission"]
A --> E{"Many distinct failure types matter<br/>(pediatric / rare disease)?"}
E -->|Yes| EFS["Event-Free Survival (EFS)<br/>event = any pre-specified failure"]
Choosing a Survival Endpoint: OS vs PFS, EFS, TTP & DFS
A practical decision aid for the time-to-event endpoint you measure — what each one counts as an event, what it censors, its regulatory standing, and the trade-off between objectivity and follow-up time
Overall survival (OS), progression-free survival (PFS), event-free survival (EFS), time-to-progression (TTP), disease-free survival (DFS) and time-to-treatment-failure (TTF) all measure time to an event — but a different event. This lesson compares their event definitions, censoring rules, and regulatory standing (OS the gold standard, PFS as a surrogate), then shows in R how the same cohort gives two different survival curves under two endpoint definitions — so you choose the endpoint that answers your question.
- A survival study doesn’t have one outcome — it has a choice of endpoint. The same patients give different answers depending on what you count as the event and what you censor.
- Overall survival (OS) — time to death from any cause — is the gold standard: objective, unambiguous, and accepted by every regulator. Its cost is long follow-up and large samples.
- Progression-free survival (PFS) — time to progression or death, whichever comes first — reads out sooner, which is why it supports accelerated approval. Its cost is assessment-time bias and reliance on how “progression” is defined.
- EFS, TTP, DFS, TTF are variations on the same theme: each widens or narrows the event set (EFS adds more failures; TTP drops death; DFS starts from remission). The right one depends on your disease setting and the question you’re answering.
- The decision rule: pick the endpoint that is clinically meaningful, objectively measurable, and feasible in your timeline — then define its event and censoring rules before you unblind.
Introduction
You’re designing a Phase III oncology trial. The science is settled, the drug is promising — and now you have to write the single line that shapes everything after it: the primary endpoint. Choose overall survival and you’ll wait four or five years for enough deaths, but the result is bulletproof. Choose progression-free survival and you could read out in two years, but a reviewer will ask how you defined “progression” and whether the scan schedule biased it.
That decision — which time-to-event endpoint do I measure? — is the most consequential one in a survival study. It sets the sample size, the follow-up, the regulatory pathway, and what you can ultimately claim. And it’s not just a clinical-trials question: any time-to-event analysis (time to churn, time to machine failure, time to readmission) faces the same fork — what counts as the event, and what do I censor?
This lesson is a decision aid. We line up the common endpoints — OS, PFS, EFS, TTP, DFS, TTF — compare what each one measures, then prove in R that the choice genuinely changes the curve. If you’re new to censoring and the survival function, read What is survival analysis? first; here we assume you know what a Kaplan-Meier curve is and focus entirely on which event to put in it.
What an “endpoint” actually is
Every survival endpoint is the same object — a Surv(time, status) pair — defined by three decisions:
- Time zero (the index date): when does the clock start? Usually randomization (the regulatory default) or first dose.
- The event: which clinical occurrence stops the clock and counts as a “1”? Death? Progression? Either?
- Censoring: for a patient who never has the event, when do you stop watching — and crucially, how do you treat occurrences you chose not to count as the event (do they censor, or are they ignored)?
Two endpoints can run on the same patients and disagree, purely because they answer questions 2 and 3 differently. That’s the whole point of this lesson — and we’ll see it on real data below.
The endpoints, side by side
Here is the working comparison. Read each row as: what stops the clock (event) · what gets censored · the trade-off.
| Endpoint | Event (clock stops at…) | Censoring | Regulatory standing | Use it when… |
|---|---|---|---|---|
| OS — Overall Survival | Death from any cause | Alive at last contact | Gold standard — objective, universally accepted | You can afford the follow-up and want the definitive benefit |
| PFS — Progression-Free Survival | Progression or death, whichever first | No event by last assessment | Accepted surrogate; supports accelerated approval | You need an earlier readout and progression is well-defined |
| TTP — Time to Progression | Progression only (deaths are censored) | Death, or no progression by last scan | Less favoured — ignores mortality | Pure anti-tumour signal; mortality assessed separately |
| EFS — Event-Free Survival | Any of several failures (progression, relapse, death, new therapy, second cancer…) | None of the listed events occurred | Accepted where the full failure burden matters | Pediatric/rare disease; many meaningful events |
| DFS — Disease-Free Survival | Recurrence or death, measured from remission | Disease-free at last contact | Standard in the adjuvant/curative setting | Patients start already in remission (post-surgery) |
| TTF — Time to Treatment Failure | Progression, death, or stopping treatment (toxicity, switch) | Still on treatment, event-free | Rarely primary — mixes efficacy + tolerability | A composite “did this treatment strategy hold up?” view |
A few distinctions worth fixing in your mind, because they’re the ones people get wrong:
- PFS vs TTP — the only difference is how death is handled. PFS counts death as an event; TTP censors it. PFS is preferred because a treatment that delays progression but kills patients shouldn’t look good — counting death keeps the endpoint honest.
- PFS vs DFS — same event logic (progression/recurrence or death), but a different time zero and population. PFS is used when measurable disease is present; DFS is used in the adjuvant setting, where patients are already disease-free after surgery and the clock measures time to recurrence.
- EFS vs PFS — EFS is the widest net: it adds failures beyond progression and death (starting non-protocol therapy, a second malignancy, induction failure). It captures the total disease burden, at the cost of a composite that’s harder to interpret.
A death is a death — no committee, no scan-reading protocol, no assessment schedule. OS has no measurement ambiguity and no assessment-time bias, which is exactly why regulators trust it as the definitive measure of benefit. Every other endpoint trades some of that objectivity for a faster or broader readout. When you move off OS, you take on the burden of defining the event precisely and defending that definition.
A decision tree for the primary endpoint
When the trade-offs blur, walk the tree: settings and timelines usually point to one endpoint.
The tree gives a starting point, not a verdict — competitive landscape, regulatory precedent in your indication, and resources all weigh in. But it captures the dominant logic: OS when you can afford it; a progression-based endpoint when you can’t; widen to EFS when several failures matter; switch to DFS in the adjuvant setting.
The same cohort, two endpoints, two answers
This is the part worth internalising: the endpoint definition isn’t a label — it changes the survival curve. We’ll show it on the colon dataset that ships with the survival package: a real adjuvant chemotherapy trial in colon cancer. Conveniently, colon records two event types per patient, so we can derive two endpoints from the same people and overlay them.
The data is stored “long” — two rows per patient: etype = 1 is the recurrence record and etype = 2 is the death record. Let’s look:
library(survival)
# Two rows per patient: etype 1 = recurrence, etype 2 = death
head(colon[, c("id", "rx", "time", "status", "etype")], 6) id rx time status etype
1 1 Lev+5FU 1521 1 2
2 1 Lev+5FU 968 1 1
3 2 Lev+5FU 3087 0 2
4 2 Lev+5FU 3087 0 1
5 3 Obs 963 1 2
6 3 Obs 542 1 1
Endpoint 1 — Overall Survival. Take only the death records (etype == 2): the event is death, censored patients are alive at last contact. This is OS, straight from the Surv() pair.
library(survival)
os <- colon[colon$etype == 2, ] # death records only
fit_os <- survfit(Surv(time, status) ~ 1, data = os)
# Median overall survival, in days
summary(fit_os)$table["median"]median
2552
Endpoint 2 — Recurrence-Free Survival (a PFS-style composite). Now build a composite: the event is recurrence or death, whichever comes first. We merge the recurrence record and the death record for each patient, take the earlier time, and mark it an event if either occurred at that earlier time — the same “progression-or-death” logic PFS uses, in base R:
library(survival)
rec <- colon[colon$etype == 1, c("id", "time", "status")] # recurrence record
death <- colon[colon$etype == 2, c("id", "time", "status")] # death record
# One row per patient, with both times side by side
m <- merge(rec, death, by = "id", suffixes = c("_rec", "_death"))
# Recurrence-free survival = earliest of the two times;
# event if recurrence happened first, OR death happened first
m$rfs_time <- pmin(m$time_rec, m$time_death)
m$rfs_status <- as.integer(
(m$time_rec <= m$time_death & m$status_rec == 1) |
(m$time_death <= m$time_rec & m$status_death == 1)
)
fit_rfs <- survfit(Surv(rfs_time, rfs_status) ~ 1, data = m)
summary(fit_rfs)$table["median"]median
1589
Two endpoints, the same 929 patients — and the medians already disagree: OS ≈ 2552 days, but recurrence-free survival ≈ 1589 days. Adding recurrence to the event set moves the median by nearly three years, because patients recur long before they die. Now overlay the two curves to see it directly:
library(survival)
library(survminer)
# Stack the two endpoints into one long data.frame for a single plot (base R, no dplyr)
combined <- data.frame(
time = c(os$time, m$rfs_time),
status = c(os$status, m$rfs_status),
endpoint = factor(rep(c("Overall survival (death)",
"Recurrence-free survival (recurrence or death)"),
c(nrow(os), nrow(m))))
)
fit_both <- survfit(Surv(time, status) ~ endpoint, data = combined)
ggsurvplot(
fit_both, data = combined,
conf.int = TRUE,
legend.labs = c("Overall survival", "Recurrence-free survival"),
legend.title = "Endpoint",
palette = "jco",
ggtheme = theme_minimal(),
xlab = "Time (days)",
ylab = "Survival probability"
)
Read the gap. The two curves come from identical patients; the only difference is the event definition. The recurrence-free curve falls earlier and lower because it counts an event the OS curve ignores — every recurrence that precedes death. A trial powered on recurrence-free survival sees its events sooner (shorter study), while OS waits for the deaths (longer, but the harder outcome). Neither is “more correct” — they answer different questions. Choosing the endpoint is choosing the question.
Because its event set is a superset. Every patient who dies contributes an event to both curves, but recurrence-free survival also counts patients who recur and are still alive — events that OS doesn’t see yet. A larger event set at every time point means a faster-falling curve. This is the general rule for composite endpoints: the more events you fold in, the earlier the curve drops — which is exactly why PFS reads out faster than OS, and why EFS (more events still) reads out faster than PFS.
Censoring and competing events change the picture too
Endpoint choice and censoring rules are inseparable. The trap to know about: in TTP, deaths are censored rather than counted. But death isn’t an ordinary “lost to follow-up” — a patient who dies can never progress. Treating death as plain censoring assumes the patient could still have had the event, which is false. That’s a competing risk, and naive Kaplan-Meier estimation of a non-fatal endpoint in the presence of substantial mortality overestimates the event of interest. When deaths are common and you’re measuring a non-fatal endpoint (TTP, time to a specific complication), reach for competing-risks methods (the cumulative incidence function), not a plain KM curve — see Competing risks.
A second, subtler issue is immortal time. If your endpoint’s clock starts at an event that can only happen to survivors (e.g. “time from response to progression”), patients had to survive long enough to respond — building a guaranteed event-free stretch into the design that can bias the comparison. Landmark analysis is the standard fix; keep the index date clean (randomization) whenever you can.
How regulators see the endpoints
The regulatory hierarchy is worth knowing because it often decides the question for you:
- OS is the benchmark. It needs no validation — death is death — and an OS benefit is the strongest efficacy claim available. The price is time and sample size.
- PFS is an accepted surrogate that can support accelerated approval when the effect is large and progression is rigorously assessed (often by a blinded independent review committee using a pre-specified criterion such as RECIST). Confirmatory OS evidence is typically expected later.
- TTP is less favoured precisely because it excludes mortality — regulators want the full benefit-risk picture, and an endpoint that can be “improved” while patients die is a red flag.
- EFS and DFS are well-established in their settings (EFS in pediatric/rare disease where many failures matter; DFS in adjuvant trials), where they map onto the clinical question better than OS or PFS.
For the formal framework behind these positions — ICH E9, FDA, and EMA expectations, and how endpoints feed the analysis dataset — see Designing a survival study and CDISC ADTTE & regulatory analysis.
Try it live
Re-run the comparison, then try a third endpoint: time to recurrence (TTP-style), where deaths are censored instead of counted. Notice how its curve sits between OS and recurrence-free survival — and ask yourself whether censoring those deaths is honest here. The sandbox boots on first Run.
Ask Prova “I have a trial dataset with both a progression date and a death date per patient — show me how to build OS, PFS and TTP endpoints in R with survival, and explain how the censoring differs between them” — it answers with survival code you can run on your own data. The runtime is the judge. Ask Prova →
Common issues
You read a PFS curve as if progression times were exact — but they’re interval-censored. Progression is detected only at scheduled assessments (every 8 or 12 weeks), so a “progression at week 16” really means “somewhere between week 8 and week 16”. This assessment-time bias inflates apparent PFS and, worse, distorts comparisons if the two arms are scanned on different schedules. Fix it by using the same imaging schedule in both arms and pre-specifying the progression criterion; for high precision, acknowledge the interval-censoring explicitly.
You censored deaths in a non-fatal endpoint and used plain Kaplan-Meier. For TTP (or time to any specific non-fatal event), a death is a competing event, not ordinary censoring — the patient can no longer have the event. Plain KM then overstates the non-fatal event rate. When mortality is non-negligible, estimate the cumulative incidence function with competing-risks methods instead of a KM curve. See Competing risks.
You interpreted a composite endpoint as if one component drove it. A PFS or EFS benefit is a benefit on the whole composite — progression and death (and more, for EFS). Before claiming “the drug delays progression,” check the components: a composite can look positive while the mortality component is flat or even unfavourable. Always report the component breakdown alongside the composite.
Frequently asked questions
Neither is universally “better”; they answer different questions. Overall survival (OS) measures time to death and is the gold standard — objective, unambiguous, and the strongest efficacy claim — but it needs long follow-up and large samples. Progression-free survival (PFS) measures time to progression or death and reads out sooner, which is why it supports accelerated approval. The trade-off is that PFS depends on how progression is defined and assessed, so it carries measurement and assessment-time bias that OS does not. Choose OS when mortality is the key outcome and follow-up is feasible; choose PFS when you need an earlier readout and progression is rigorously defined.
Both count progression and death as events, but event-free survival (EFS) casts a wider net: it also counts other pre-specified failures — starting non-protocol therapy, a second malignancy, induction failure, relapse — whereas progression-free survival (PFS) counts only progression or death. EFS captures the full burden of treatment failure (common in pediatric and rare-disease trials where several events matter), at the cost of being a more complex composite that’s harder to interpret. PFS is the narrower, more standardized oncology endpoint.
The only difference is how death is handled. Progression-free survival (PFS) counts death as an event (progression or death, whichever comes first). Time to progression (TTP) counts only progression and censors deaths. PFS is generally preferred because counting death keeps the endpoint honest — a treatment that delays progression but increases mortality shouldn’t look good. TTP is used mainly for a pure anti-tumour signal, with mortality assessed separately, and because its censored deaths are a competing risk, it usually calls for competing-risks methods rather than plain Kaplan-Meier.
Use DFS in the adjuvant or curative setting, where patients are already disease-free after surgery (or another curative treatment) and the clock measures time to recurrence or death from that point. DFS differs from PFS mainly in time zero and population: PFS is used when measurable disease is present, DFS when it has been removed. DFS is the standard endpoint in adjuvant cancer trials — the colon dataset in this lesson is exactly that setting.
Because it has no measurement ambiguity. A death is a death — there’s no committee, no scan-reading protocol, and no assessment schedule that could bias it, so OS is free of the assessment-time bias that affects progression-based endpoints. That objectivity is why every major regulator accepts OS without additional validation and treats an OS benefit as the definitive demonstration of clinical benefit. Its only real drawback is practical: it requires long follow-up and large sample sizes to accumulate enough deaths.
Test your understanding
- Run it. Using the
colondata, build overall survival (deaths,etype == 2) and time to recurrence (recurrences,etype == 1) and report each median. Which is shorter, and why? - Interpret. A trial reports a significant PFS benefit (HR 0.62) but a non-significant OS benefit (HR 0.88). In plain words, what might explain the gap — and what would you check before claiming the drug “extends life”?
The recurrence endpoint counts an event (recurrence) that happens before death for most patients, so its clock stops sooner — expect a shorter median. For question 2, a PFS-but-not-OS pattern is common: the drug may delay progression without (yet) translating into longer life, OS may be immature (too few deaths), or post-progression therapies may dilute the OS difference. Check OS maturity (event count and follow-up), the component breakdown, and crossover.
library(survival)
os <- colon[colon$etype == 2, ]
rec <- colon[colon$etype == 1, ]
summary(survfit(Surv(time, status) ~ 1, data = os))$table["median"] # ~2552 days
summary(survfit(Surv(time, status) ~ 1, data = rec))$table["median"] # shorter — recurrences precede deathTime to recurrence is shorter because recurrence is an earlier event than death for most patients — the event clock stops sooner. For question 2: a significant PFS with a non-significant OS typically means the treatment delays progression but hasn’t (yet) shown a survival gain. Before claiming it “extends life,” check whether OS is mature (enough deaths and follow-up), whether post-progression treatments or crossover diluted the OS comparison, and the component breakdown of the composite. A PFS benefit is real and meaningful, but it is not an OS benefit.
A trial measures time to progression (TTP) and censors patients who die before progressing. In this cohort, 30% of patients die without ever progressing. Why is a plain Kaplan-Meier estimate of TTP misleading here, and what should you use instead?
Death is a competing risk, not ordinary censoring: a patient who dies can never progress, yet plain Kaplan-Meier treats the censored deaths as if they could still have the event. With 30% dying without progression, this overestimates the true progression rate. Use a competing-risks analysis — the cumulative incidence function — which correctly accounts for death as a competing event. See Competing risks.
Conclusion
A survival study has no single outcome — it has an endpoint you choose, and that choice sets the event, the censoring, the sample size, the follow-up, and what you can claim. Overall survival is the gold standard because death is unambiguous, at the cost of time; progression-free survival trades a little of that objectivity for a faster readout; TTP, EFS, DFS, and TTF widen or narrow the event set for specific settings. We proved the stakes on real data: the same 929 colon-cancer patients gave a median of 2552 days under overall survival but 1589 days once recurrences were counted — the endpoint definition, not the patients, moved the answer by years. Pick the endpoint that is clinically meaningful, objectively measurable, and feasible, define its event and censoring rules before you unblind, and mind the competing-events and immortal-time traps along the way.
Reuse
Citation
@online{2026,
author = {},
title = {Choosing a {Survival} {Endpoint:} {OS} Vs {PFS,} {EFS,} {TTP}
\& {DFS}},
date = {2026-06-26},
url = {https://www.datanovia.com/learn/biostatistics/survival-analysis/choosing-a-survival-endpoint},
langid = {en}
}