← Methods repository
concept

Restart, Rechallenge, and New-Episode Rules

A protocol-specified set of exposure-episode rules that classify a later dispensing of the same drug as continuation of an ongoing episode, a restart after a permissible gap, a rechallenge after a safety-driven dechallenge, or a distinct new treatment episode, because each classification changes who is counted, when follow-up starts, and what the estimand means.

Exposure_Definitionexposure-definitionexposure-episode-constructiontreatment-episoderechallengedechallengerestartnew-episodepersistence
Methods reference only. Use primary source citations and local policy before applying this in a study protocol, regulatory submission, payer dossier, or clinical decision.

In plain language

When a patient stops a drug and then refills it later, analysts must decide whether that later fill continues the original treatment period or starts a brand-new one — and, critically, whether the restart happened after a safety scare on the drug. The rules in this concept draw a firm line around four situations: continuing without a real gap, restarting after an ordinary gap, restarting specifically because a doctor rechallenged after a bad reaction, and beginning a clinically fresh course after a very long break. Getting the classification right matters because every count of who is being treated, for how long, and from what starting point is built on top of these rules.

Restart, rechallenge, and new-episode rules

are the deterministic logic that turns a stream of pharmacy dispensings (or orders/administrations) into discrete treatment episodes and decides how to handle a re-appearance of the same drug after exposure has lapsed. The rules are not a single threshold; they are a small decision tree applied per `person_id` per drug, evaluated in date order over `fill_date` and `days_supply`, against (a) the gap since the prior episode's covered end, (b) whether an intervening adverse event / intolerance triggered the stop, and (c) whether the indication or clinical context has changed. Because every downstream quantity — incidence-rate denominators, persistence/discontinuation, time-zero for a new-user contrast, drug-utilization counts, and per-member cost denominators — is built on top of these episodes, the rules must be written into protocol/SAP language before programming and stress-tested with sensitivity analyses on the thresholds that drive them.

Core conceptual distinction

Four mutually exclusive states must be separable, and conflating any two is a reviewable error: - Continuation — the next fill arrives within the allowable gap (typically the prior `days_supply` end plus a pre-specified grace period). It extends the same episode; no new time-zero, no new "initiation." - Restart — exposure lapsed beyond the grace period but re-initiation reflects ordinary stop/start behavior (cost, forgetting, a drug holiday), with no intervening adverse event. Whether a restart opens a new analytic episode depends on the question: for persistence it is a new episode; for cumulative-dose effects it may be the same chronic exposure resumed. - Rechallenge — re-initiation after a dechallenge that was itself driven by an adverse event or intolerance. This is a safety-specific construct: the dechallenge-positive / rechallenge-positive sequence is one of the strongest individual-level signals of drug causality (it is an explicit item in the Naranjo and WHO-UMC causality algorithms). A rechallenge is never "just another restart" — the prior stop carries information about the outcome. - New episode — the re-appearance belongs to a clinically distinct course: a different indication, a gap so long the prior course is irrelevant (a "new-episode" threshold, e.g., > 365 days), or a re-qualifying diagnostic event. A new episode legitimately resets time-zero and washout for a new-user-style analysis.

The estimand must name which states open a new at-risk episode and which do not. A cause-specific hazard for first discontinuation treats restart as a new spell; an as-treated cumulative-exposure model stitches restarts into continuous person-time with on/off indicators; a rechallenge safety analysis conditions follow-up on the dechallenge-rechallenge sequence itself (and is the design behind prescription-sequence-symmetry and case-only rechallenge studies).

Pros, cons, and trade-offs

- vs a single fixed-gap "any refill = same episode" rule: Explicit four-state rules are transparent, reproducible, and defensible to FDA/EMA/HTA reviewers, and they prevent the silent merging of a safety rechallenge into a benign restart. Cost: more code, more diagnostics, and more thresholds to justify and vary in sensitivity analysis. Prefer the explicit rules for any consequential comparative-safety, effectiveness, utilization, or cost-denominator analysis. - vs prescription-sequence-symmetry (PSSA) / case-only rechallenge designs: PSSA exploits the temporal symmetry of an event around the (re)start to self-control for time-invariant confounding and is excellent for hypothesis screening. Cost: it answers a narrower signal-detection question and assumes the event does not itself affect the probability of the second dispensing. Prefer cohort episode rules when you need rate or cumulative-incidence contrasts; prefer PSSA for rapid, confounding-robust signal screening of a suspected rechallenge effect. - vs collapsing everything into prevalent-user person-time: Counting all dispensings as one undifferentiated exposure is simplest but destroys time-zero, re-introduces immortal time (the survivor who lives long enough to refill), and makes "restart vs rechallenge" invisible. Never prefer this for causal contrasts.

When to use

Any claims/EHR/registry analysis where the same drug can be stopped and restarted: chronic-disease persistence and discontinuation; comparative safety where rechallenge after an event is informative; drug-utilization and treatment-pattern (lines-of-therapy) work; and HTA budget-impact/cost denominators that depend on how many distinct treated episodes exist. Use whenever the protocol must defend why a later fill was or was not counted as a new initiation.

When NOT to use — and when it is actively misleading or dangerous

- When the data cannot observe the gap. If person-time inside a gap is unobservable (e.g., Medicare Advantage enrollees whose fee-for-service pharmacy claims are not in the source), a "gap" may be missingness, not a true stop — classifying it as a restart or new episode manufactures spurious initiations. Restrict to continuously observable (e.g., Part D / commercial pharmacy-benefit) person-time before applying the rules. - When you let a rechallenge masquerade as a restart in a safety study. If the dechallenge was AE-driven and you fold the re-initiation into ongoing person-time, you both dilute the rechallenge signal and bias the comparator — survivors who tolerated and resumed look healthier (depletion of susceptibles). This is the classic place the method becomes dangerous. - When new-episode resets create immortal time. Resetting time-zero at a "new episode" defined using future information (e.g., requiring the patient to survive to a later qualifying fill) re-creates immortal time bias (Suissa). The qualifying logic must use only information available at the candidate time-zero. - When stockpiling/oversupply fakes continuation. Mail-order 90-day fills, sample fills, and refill-ahead behavior inflate `days_supply` coverage and erase real gaps; without stockpiling/carry-over rules the algorithm will call a true discontinuation a continuation.

Data-source operational depth

- Administrative claims (FFS vs MA vs commercial): The episode is built from `fill_date` + `days_supply` + NDC. Failure modes: (1) MA-only person-time lacks FFS pharmacy claims — a clean-looking 200-day gap may simply be a period you cannot see; require continuous Part A/B/D (or commercial medical + pharmacy) enrollment across each gap you intend to classify, and exclude MA-only spans. (2) Claims reversals and same-day duplicates inflate fill counts — collapse to net paid dispensings before stitching. (3) Adjudication/run-out lag truncates the last observable fill — censor at end-of-data, not at the last fill. (4) Bundled/inpatient drugs are invisible in Part D — an apparent gap during a hospitalization is often bridged inpatient exposure (see inpatient-bridging-exposure-rwe). - EHR: Exposure is the order or administration, not the dispensing; restarts/rechallenges are frequently captured in unstructured notes ("rechallenged after rash resolved") that structured order tables miss, and external-care leakage means a restart prescribed elsewhere is invisible. Differential, encounter-driven capture makes gaps look longer for patients who simply left the system; treat loss to follow-up as potentially informative and prefer linked dispensing. - Registry: Often strongest for the reason a drug was stopped (adjudicated AE → enables true rechallenge classification) but weak for complete refill history; link to claims for fills and to a death index so a "permanent discontinuation" is not actually an unrecorded death. - Linked claims–EHR–registry: The ideal substrate — registry/EHR supply the AE that defines a dechallenge while claims supply the complete fill history — but order/fill/administration date discrepancies and linkage selection must be reconciled before assigning episode boundaries.

Worked claims example

Question: classify exposure to drug X (an oral immunomodulator) into episodes in a commercial + Medicare FFS database, distinguishing a safety rechallenge from a routine restart. Setup per `person_id`, drug X NDCs only, sorted by `fill_date`; require continuous medical + pharmacy enrollment (no MA-only spans) across every evaluated gap. Define `covered_through = fill_date + days_supply`, GRACE = 30 days, RESTART_MAX = 180 days, NEW_EPISODE = 365 days. Walking the fills: - 2023-02-01, days_supply 30 → covered_through 2023-03-03. Next fill 2023-03-10: gap = 7 days ≤ GRACE → continuation (same episode; do not reset time-zero). - That episode's last fill is 2023-04-10 (covered_through 2023-05-10). Next fill 2023-08-01: gap = 83 days, in (GRACE, RESTART_MAX]. Check for an intervening AE diagnosis (e.g., a hepatotoxicity dx + drug discontinuation in 2023-05) → none found → restart (new persistence episode; same chronic exposure for a cumulative-dose model). - Suppose instead an inpatient dx of drug-induced hepatitis appears 2023-05-15 with no further X fills for months, then X re-appears 2024-01-15. Because the stop was AE-driven (a dechallenge) and the re-initiation follows it, this is a rechallenge — flagged for the dechallenge-positive/rechallenge-positive safety analysis, not silently merged. - A fill of X appearing 2025-06-01, > NEW_EPISODE days after the prior covered end and accompanied by a re-qualifying indication, opens a new episode: reset washout and time-zero for a new-user-style contrast. Diagnostics: pre/post episode counts, the distribution of computed gaps with the threshold cut points overlaid, patient-level timelines for a sample, the share of "gaps" occurring during unobservable MA spans, and a sensitivity analysis varying GRACE (15/30/60), RESTART_MAX (90/180), and the AE-window used to define a dechallenge.

Worked example

Scenario

Patient 2047 is prescribed methotrexate (an oral immunomodulator used for rheumatoid arthritis) starting January 10, 2023. She fills it twice in the spring and appears to be continuing therapy without interruption. Then she stops for several months after developing abnormal liver labs in May — a safety-driven dechallenge. Her rheumatologist rechallenges her in October at a lower dose. We want to label each fill as continuation, restart, or rechallenge, and identify which fills belong to Episode 1 versus Episode 2.

Dataset

Pharmacy claims rows for patient 2047 (methotrexate only, one row per fill, already cleaned for duplicates).

person_idfill_datedrugdays_supplycovered_through
20472023-01-10methotrexate902023-04-09
20472023-04-05methotrexate902023-07-03
20472023-10-15methotrexate902024-01-12

Steps

  • Fill A (Jan 10): This is the patient's very first fill of methotrexate in the data. It opens Episode 1, and Jan 10 becomes her index date — her day-zero.

  • Fill A covers Jan 10 through Apr 9 (90 days). Fill B arrives Apr 5 — that is 4 days BEFORE covered_through, so the gap is actually negative (an early refill). Negative or zero gap means the patient never ran out; Fill B is a continuation of Episode 1.

  • Fill B covers Apr 5 through Jul 3. Now check Fill C: it arrives Oct 15. The gap = Oct 15 minus Jul 3 = 104 days. That gap is too long to be a normal continuation (our grace period is 30 days).

  • Before labeling Fill C a restart, we check whether a safety event drove the stop. The claims data shows an abnormal-liver-labs diagnosis code on May 22, 2023 — that is 49 days after covered_through (Jul 3 minus May 22 = 42 days before covered_through, well within a 90-day look-around window). This counts as a dechallenge.

  • Because the stop was safety-driven and the patient is now restarting the same drug, Fill C is a RECHALLENGE. It opens Episode 2 with a new index date of Oct 15, 2023.

  • Episode 1 spans Jan 10 – Jul 3 (174 days of covered time). Episode 2 begins Oct 15 (the rechallenge). The gap between covered_through of Episode 1 and the rechallenge fill is 104 days.

Result

Label

Episode 1 (continuation): Jan 10 – Jul 3, 2023 (174 covered days across 2 fills). Episode 2 (rechallenge): starts Oct 15, 2023. Fill C is flagged as a safety rechallenge — not a routine restart — because the May 22 liver-labs event is within 90 days of the end of Episode 1.

Value

2 episodes; Fill C state = rechallenge

Timeline Spec

Title

Restart vs. rechallenge: one methotrexate patient with a safety-driven dechallenge

Window
Start

2023-01-10

End

2024-01-12

Label

Observation window: Jan 10 2023 – Jan 12 2024 (367 days)

Events
  • Label

    Fill A — Episode 1 opens (index date)

    Start

    2023-01-10

    Length Days

    90

    Quantity

    90 days_supply

  • Label

    Fill B — continuation (early refill, 4 days before covered_through)

    Start

    2023-04-05

    Length Days

    90

    Quantity

    90 days_supply

  • Label

    Fill C — rechallenge (Episode 2 opens, new index date)

    Start

    2023-10-15

    Length Days

    90

    Quantity

    90 days_supply

Spans
  • Kind

    exposed

    Start

    2023-01-10

    End

    2023-07-03

    Label

    Episode 1: 174 covered days (continuation)

  • Kind

    gap

    Start

    2023-07-04

    End

    2023-10-14

    Label

    104-day gap — dechallenge gap (liver-labs AE May 22)

  • Kind

    exposed

    Start

    2023-10-15

    End

    2024-01-12

    Label

    Episode 2: 90 covered days (rechallenge)

Adverse Event
Label

Liver-labs AE — dechallenge trigger

Date

2023-05-22

Result
Label

2 episodes. Fill C = rechallenge (not restart) because AE date May 22 is within 90 days of Episode 1 covered_through Jul 3.

Value

rechallenge

Caption

Timeline for patient 2047 on methotrexate. Fills A and B form a single continuous episode (Episode 1) because Fill B arrives before Fill A runs out. The 104-day gap is classified as a dechallenge gap, not a routine break, because the liver-labs adverse event on May 22 falls within the 90-day look-around window. Fill C is therefore a rechallenge — it opens Episode 2 with a fresh index date — rather than a plain restart. In a safety study, this dechallenge-positive / rechallenge-positive sequence is evidence that the drug may have caused the liver problem.

Alt Text

Horizontal timeline for one patient showing two colored exposure bars separated by a gap. Episode 1 runs January 10 to July 3 2023 and is made up of two fills (Fill A and Fill B) with Fill B beginning before Fill A expired. A liver-labs adverse-event marker sits on May 22 2023 inside the gap period. Episode 2 begins October 15 2023 and is labeled as a rechallenge because the adverse event is close in time to the end of Episode 1.

Runnable example

python implementation

Classify same-drug fills into continuation / restart / rechallenge / new-episode states from claims-style inputs. Required inputs (already cleaned: reversals and same-day duplicates collapsed, restricted to the target drug's NDCs, restricted to continuously...

import pandas as pd
import numpy as np

GRACE_DAYS       = 30    # consecutive fills within days_supply + GRACE extend the SAME episode
RESTART_MAX_DAYS = 180   # gap in (GRACE, RESTART_MAX] -> restart; below new-episode threshold
NEW_EPISODE_DAYS = 365   # gap > this (or new indication) -> a clinically distinct new episode
AE_WINDOW_DAYS   = 90    # an AE within this window of the prior covered end marks a dechallenge

def classify_episodes(rx: pd.DataFrame, ae: pd.DataFrame) -> pd.DataFrame:
    rx = rx.sort_values(["person_id", "fill_date"]).copy()
    rx["covered_through"] = rx["fill_date"] + pd.to_timedelta(rx["days_supply"], unit="D")
    ae_by_person = ae.groupby("person_id")["ae_date"].apply(list).to_dict()

    out_rows = []
    for pid, g in rx.groupby("person_id", sort=False):
        ae_dates = ae_by_person.get(pid, [])
        episode_id = 0
        prev_covered = None
        for row in g.itertuples(index=False):
            if prev_covered is None:
                state = "new_episode"          # first observed fill opens episode 0
            else:
                gap = (row.fill_date - prev_covered).days
                if gap <= GRACE_DAYS:
                    state = "continuation"
                else:
                    # Was the prior stop driven by an adverse event? -> rechallenge.
                    dechallenge = any(
                        0 <= (a - prev_covered).days <= AE_WINDOW_DAYS or
                        0 <= (prev_covered - a).days <= AE_WINDOW_DAYS
                        for a in ae_dates
                    )
                    if dechallenge:
                        state = "rechallenge"
                    elif gap <= RESTART_MAX_DAYS:
                        state = "restart"
                    else:
                        state = "new_episode"   # gap > NEW_EPISODE (RESTART_MAX < NEW_EPISODE) or any long gap
            if state != "continuation":
                episode_id += 1                  # restart/rechallenge/new_episode open a new analytic episode
            out_rows.append((pid, row.fill_date, row.covered_through, episode_id, state))
            # Coverage can extend if a restart overlaps the prior tail; take the later end.
            prev_covered = row.covered_through if prev_covered is None else max(prev_covered, row.covered_through)
    return pd.DataFrame(out_rows,
                        columns=["person_id", "fill_date", "covered_through", "episode_id", "state"])
r implementation

Same four-state episode classifier with data.table. Inputs mirror the Python version: rx : person_id, fill_date (Date), days_supply (integer) ae : person_id, ae_date (Date) # adverse-event dates defining a possible dechallenge Input must be pre-cleaned...

library(data.table)

GRACE_DAYS       <- 30L
RESTART_MAX_DAYS <- 180L
NEW_EPISODE_DAYS <- 365L
AE_WINDOW_DAYS   <- 90L

classify_episodes <- function(rx, ae) {
  setDT(rx); setDT(ae)
  setorder(rx, person_id, fill_date)
  rx[, covered_through := fill_date + days_supply]
  ae_list <- split(ae$ae_date, ae$person_id)

  rx[, c("episode_id", "state") := {
    eid <- 0L; prev_cov <- as.Date(NA); ad <- ae_list[[as.character(.BY$person_id)]]
    eids <- integer(.N); sts <- character(.N)
    for (i in seq_len(.N)) {
      if (is.na(prev_cov)) {
        st <- "new_episode"
      } else {
        gap <- as.integer(fill_date[i] - prev_cov)
        if (gap <= GRACE_DAYS) {
          st <- "continuation"
        } else {
          dechallenge <- !is.null(ad) && any(abs(as.integer(ad - prev_cov)) <= AE_WINDOW_DAYS)
          st <- if (dechallenge) "rechallenge"
                else if (gap <= RESTART_MAX_DAYS) "restart"
                else "new_episode"
        }
      }
      if (st != "continuation") eid <- eid + 1L
      eids[i] <- eid; sts[i] <- st
      prev_cov <- if (is.na(prev_cov)) covered_through[i] else max(prev_cov, covered_through[i])
    }
    list(eids, sts)
  }, by = person_id]
  rx[, .(person_id, fill_date, covered_through, episode_id, state)]
}