Skip to content
← Research papers

Research paper

Catchers, umpires and hard contact

Descriptive Statcast leaderboards, their sample-size floors, and why a leaderboard is not a forecast

Abstract

This note reads three published MLB Statcast-derived leaderboards side by side: catcher and umpire out-of-zone strike rate -- the artifact's 'called/swung-strike rate', which its label says is NOT a called-strike or framing rate (both from mlb_descriptive_leaderboards.json, a fixed 2022-2023 corpus slice, corpus_id statcast_fuller_v1), and batter contact quality measured as the 90th percentile of a batter's recorded exit velocity minus the mean of that same series (atlas_mlb_batters_manifest.json, 2025 season, floor pitches_faced_2025>=300). The catcher leaderboard qualifies 113 catchers at a floor of at least 500 out-of-zone called pitches (catcher_ooz.n_qualified, catcher_ooz.floor); the top rate is Rene Pinto at 31.5 percent (n=3448), the bottom shown is Drew Millas at 21.2 percent (n=585). The umpire leaderboard qualifies 102 umpires (umpire_ooz.n_qualified); the top rate, Randy Rosenberg at 31.4 percent, sits on the smallest listed sample of any umpire, n=506. The batter contact leaderboard covers 485 hitters (n_entries); the largest gap belongs to Brett Harris at 24.6 mph (336 pitches, 102 batted balls), the smallest to Luis Arraez at 14.2 mph on a far larger sample (2393 pitches, 1072 batted balls). A separate artifact (mlb_shrinkage.json) fits its own beta-binomial prior to the same two groups and records a 28.13 percent pooled mean with kappa 834.93 for catchers and 2830.5 for umpires; neither leaderboard publishes a shrunk rate of its own, and each publishes only its top 15 and bottom 15 rows. A separate gate rejected umpire out-of-zone rate as a predictor of game totals. None of these three leaderboards is a forecast input here; they are descriptive rankings with published floors, read alongside the confounds that limit them.

1 Question

A rate leaderboard ranks entities that cleared a fixed number of recorded events by their rate in one closed historical window. This note reads three such leaderboards: catcher and umpire out-of-zone strike rate (catcher_ooz and umpire_ooz in mlb_descriptive_leaderboards.json), and batter contact quality measured as p90 minus mean recorded exit velocity (atlas_mlb_batters_manifest.json). All three carry a published minimum-sample floor, and this note asks what each rate measures, what it confounds, why its floor exists, and why sitting at the top or bottom of one describes a fixed window rather than forecasting anything.

The three are read together deliberately. A catcher's out-of-zone strike rate and an umpire's describe the same physical event from two different participants, so neither is an isolated skill measure without the other side of the same call. The batter leaderboard asks a different question -- the shape of one hitter's exit-velocity distribution -- but shares the discipline: a published floor, a fixed window, and a refusal to call the ranking predictive.

2 Data and definitions

The catcher and umpire leaderboards come from mlb_descriptive_leaderboards.json (generated_at 2026-07-24T21:46:01Z; site module as_of 2026-07-24), drawn from a fixed 2022-2023 Statcast pull, corpus_id statcast_fuller_v1, observation_window.as_of 2026-07-05 (observation_window.seasons=2022_2023). Its source_note records that the leaderboards derive from local Statcast parquets, this committed JSON being the artifact, with no predictive claim (source_note). The umpire cut carries its own corpus_id, statcast_fuller_v1_x_probables, one step removed from the top-level corpus_id; the source does not document what that extra join changes (umpire_ooz.corpus_id).

The batter contact leaderboard comes from a separate 2025-season artifact, atlas_mlb_batters_manifest.json, generated_at 2026-07-23T01:25:10Z, covering 485 batters (n_entries). Every entry shares the same as_of date, 2025-09-28 (entries[].as_of), and each entry's floors field names the Statcast columns behind eligibility -- pitches_faced, launch_speed, estimated_woba_using_speedangle (entries[].floors). Both artifacts are pitch-level Statcast pulls (statcast_showcase: data/cache/statcast/statcast_fuller__2025.parquet, 693037 pitches), not the MLB in-game price-tick corpus carrying a documented data-integrity notice elsewhere on this site; that quarantine does not apply here.

Catcher out-of-zone strike rate qualifies 113 catchers at a floor of at least 500 out-of-zone called pitches (catcher_ooz.n_qualified, catcher_ooz.floor = 'n_ooz_called>=500'). Umpire out-of-zone strike rate qualifies 102 umpires (umpire_ooz.n_qualified); the source publishes no separate floor for this group, though the smallest listed sample, Randy Rosenberg at n=506, sits close to the catcher group's 500-pitch threshold -- consistent with, but not confirmed as, the same floor. Batter contact quality qualifies 485 batters at a floor of at least 300 pitches faced in 2025 (entries[].floors = 'pitches_faced_2025>=300 (yields 485/671 batters)'). Neither out-of-zone group publishes a full table: the artifact lists 15 top and 15 bottom rows each (catcher_ooz.top, catcher_ooz.bottom, umpire_ooz.top, umpire_ooz.bottom), so 83 of the 113 catchers and 72 of the 102 umpires are counted in n_qualified and never named.

3 Method

The artifact names this metric 'Out-of-zone called/swung-strike rate' and calls it a descriptive stat, cruder than model-based framing, and explicitly NOT a called-strike or framing rate (catcher_ooz.label, umpire_ooz.label). Its numerator therefore counts out-of-zone pitches ruled a strike by call together with out-of-zone pitches the batter swung at; its denominator is the entity's published n_ooz_called. That single ratio confounds four things: umpire zone judgment, catcher receiving technique, pitcher command (how far outside the pitch actually was), and count (a batter takes a borderline pitch more readily on 3-0 than 0-2). None is separated out.

A single out-of-zone strike call has exactly one pitcher, one catcher, and one umpire attached to it, so a catcher's rate and an umpire's rate cannot both be read as independent skill numbers without acknowledging overlapping games. The published leaderboards are not paired by game or battery -- no joint catcher-umpire table exists -- so this note reads them as two views of one mechanism, not a matched comparison.

P90 minus mean exit velocity subtracts a batter's mean recorded exit velocity from the 90th percentile of that same launch_speed series (avg_exit_velo, exit_velo_p90); it is a derived difference of two published fields, both rounded to 0.1 mph. The mean describes the center of a batter's contact distribution; the gap to the 90th percentile describes how far his own top decile reaches above it. Two batters can share a mean and differ sharply here: one has a fat right tail, the other's hardest-hit balls barely clear his average. This artifact measures only recorded exit velocity, not outcomes.

p90_minus_mean_exit_velo (mph) = exit_velo_p90 - avg_exit_velo, both operands published to 0.1 mph over the same recorded launch_speed series

All three leaderboards use a minimum-event floor: 500 out-of-zone called pitches for catchers, an apparently similar unstated threshold for umpires, and 300 pitches faced for batter contact. A floor exists because a rate over a handful of events is dominated by sampling noise. The leaderboard artifact does not shrink its published rates and names no shrinkage target for its floor. A separate artifact records one of its own: mlb_shrinkage.json fits a beta-binomial prior by method of moments over the same fixed 2022-2023 slice and publishes pooled_mean 0.2813, kappa 834.93 across 113 catchers and 2830.5 across 102 umpires, and a posterior mean shrunk_i = (k_i + alpha)/(n_i + alpha + beta) for named entities (mlb_shrinkage.json method, groups[key=catcher_ooz].kappa, groups[key=umpire_ooz].kappa, groups[key=catcher_ooz].pooled_mean). Its own confounds call that single-prior exchangeability a modeling choice, not a fact. The two artifacts are reported side by side here, not one derived from the other. Batter contact appears in neither, so its 300-pitch floor is the only published guard against small-sample noise there.

4 Results

Table 1 lists the top and bottom six of the 113 qualified catchers by out-of-zone strike rate (catcher_ooz.top, catcher_ooz.bottom).

Catcher out-of-zone strike rate (n_qualified=113, floor n_ooz_called>=500)
CatcherOut-of-zone strike rateOut-of-zone called pitches (n)
Rene Pinto31.5%3448
Austin Barnes30.5%6707
Alejandro Kirk30.5%10963
Patrick Bailey30.4%5657
Roberto Perez30.2%1637
Sandy Leon30.2%2537
P.J. Higgins25.0%1946
Elias Diaz25.0%14540
Robinson Chirinos24.6%3989
Carlos Perez23.9%1277
Cooper Hummel21.8%914
Drew Millas21.2%585

Top six then bottom six of 15 published rows per side. Source: mlb_descriptive_leaderboards.json, catcher_ooz.top[]/catcher_ooz.bottom[], as_of 2026-07-24.

Rene Pinto's top-ranked raw rate of 31.5 percent (n=3448) appears in the shrinkage artifact as raw_rate 0.3147 with shrunk_rate 0.3082 (groups[key=catcher_ooz].top_by_shrunk) -- under that separate prior the leaderboard's top spot is 0.65 points smaller. At the other end, four of the six lowest-rate catchers shown here -- P.J. Higgins, Carlos Perez (n=1277), Cooper Hummel, and Drew Millas -- are also named among the group's largest published regressions, all at n below 2000 (groups[key=catcher_ooz].biggest_regressors); Drew Millas's is pulled up 4.08 points to 25.28 percent, the largest movement in that group. A second Carlos Perez (n=2234, rate 25.3 percent) appears in the same list, distinguished only by sample size.

Table 2 lists the top and bottom six of the 102 qualified umpires by the same out-of-zone strike-rate measure (umpire_ooz.top, umpire_ooz.bottom).

Umpire out-of-zone strike rate (n_qualified=102)
UmpireOut-of-zone strike rateOut-of-zone called pitches (n)
Randy Rosenberg31.4%506
Bill Miller30.8%8815
Laz Diaz30.2%7197
Doug Eddings30.2%8181
Andy Fletcher30.0%8328
Lance Barrett29.9%8184
John Bacon26.7%2933
Pat Hoberg26.6%8269
Mark Wegner26.3%6755
Carlos Torres26.0%8472
David Arrieta25.9%754
Derek Thomas25.2%2608

Top six then bottom six of 15 published rows per side. Source: mlb_descriptive_leaderboards.json, umpire_ooz.top[]/umpire_ooz.bottom[], as_of 2026-07-24.

Randy Rosenberg tops the umpire list at 31.4 percent, on the smallest sample of any listed umpire, n=506; the shrinkage artifact carries the same raw_rate (0.3142) and the group's largest regression, a shrunk_rate of 28.63 percent, a 2.79-point movement (groups[key=umpire_ooz].biggest_regressors). David Arrieta and Derek Thomas, both in Table 2's bottom six, are also in that list, each moved up 1.51 to 1.79 points once shrunk. Across Tables 1 and 2 the entity at the extreme of a raw-rate ranking is disproportionately likely to carry a small sample and a large shrinkage-implied correction.

This site separately tested whether an umpire's out-of-zone rate predicts a game's total runs, beyond a league-and-park baseline, across 103 umpires; the result was a REJECT -- a planted-null test with the umpire assignment shuffled produced an equal-or-larger improvement than the real assignment, read as ump identity not moving game totals (umpire_totals_gate.verdict, umpire_totals_gate.verdict_reason, umpire_totals_gate.n_umpires). The same artifact reports a second null: a park-factor field finite for none of its 29 rows (park_factor_null.n_rows=29, park_factor_null.n_finite_park_factor=0), too sparse to publish (park_factor_null.verdict). Both sit beside these leaderboards: the source publishes rankings it cannot validate as predictive.

Table 3 lists the eight largest and eight smallest published gaps between a batter's 90th-percentile recorded exit velocity and his own mean, among the 485 batters who cleared the 300-pitches-faced floor (entries[].key_numbers).

Batter contact quality: p90 minus mean exit velocity (n=485 eligible, floor pitches_faced_2025>=300)
BatterP90 minus mean (mph)Mean exit velo (mph)P90 exit velo (mph)Recorded batted balls (n)Pitches faced (n)
Brett Harris24.678.3102.9102336
Blake Dunn24.476.4100.876300
Michael Helman24.177.4101.5160405
Martin Maldonado23.579.7103.2136543
Colson Montgomery23.583.2106.73491088
Jhonkensy Noel23.483.8107.2191532
Giancarlo Stanton23.386.3109.62941222
Nate Eaton23.381.2104.5117338
Steven Kwan15.980.596.410012723
Alex Freeland15.983.799.6105429
Keibert Ruiz15.782.798.4369838
Justin Turner15.482.497.8290774
Hyeseong Kim15.380.996.2214660
DJ LeMahieu15.086.8101.8167539
Leo Rivas14.580.995.4126521
Luis Arraez14.281.295.410722393

Top eight then bottom eight of 485 eligible batters, ranked by the derived difference exit_velo_p90 minus avg_exit_velo. Source: atlas_mlb_batters_manifest.json, entries[].key_numbers, entries[].floors, entries[].as_of=2025-09-28.

The pattern in Table 3 is visible without a statistical test, and it runs one way only: all eight of the largest gaps belong to batters with fewer than 350 recorded batted balls (entries[].key_numbers.n_batted_balls), while among the eight smallest only four sit at 290 or more, including Luis Arraez (1072) and Steven Kwan (1001); the other four sit between 105 and 214. The 300-pitch floor does not bound the batted-ball count directly: Blake Dunn clears it exactly yet has only 76 recorded batted balls behind his 24.4 mph gap, the second-largest published. A 90th-percentile statistic over roughly 70-100 values is noisier than one over 1000, though both cleared the same floor.

Source moduleMlb Descriptive LeaderboardsPublished catcher and umpire out-of-zone strike rate leaderboards, plus the park-factor null and the umpire-totals REJECT, all from a fixed 2022-2023 Statcast slice (mlb_descriptive_leaderboards.json).No chart is published for this source. Open the module page for its table of measurements.

5 Robustness and what would falsify this

Every cross-reference checked lines up: Rene Pinto's, Randy Rosenberg's, David Arrieta's and Derek Thomas's n and raw rate match across mlb_descriptive_leaderboards.json and mlb_shrinkage.json to the rounding each publishes. A mismatch would indicate a stale artifact or a data-pull error; none was found.

Every regression checked matches the mechanism's direction: a raw rate above the 28.13 percent pooled mean is pulled down, one below it pulled up, across both biggest_regressors lists. A row breaking that would point to a fitting error in the prior; none does.

  • A published shrunk version of the batter contact gap, collapsing toward zero for the lowest-batted-ball rows as the catcher and umpire rates do, would confirm the same mechanism there; it does not exist.
  • A joint catcher-umpire table showing the two rates move independently would separate their contributions; no such table is published.
  • A forward test of the contact gap against a later season, showing the ranking holds out of sample, would move this toward a stable measurement; none is published.

6 Limitations

This is a description of three fixed leaderboards and their sample-size floors, not a validated skill measurement or a forecast input.

  • Zone definition: out-of-zone is defined against the rulebook zone at the pitch's location, not any umpire's personal zone; no per-umpire boundary tolerance is published, so two umpires with different real zones could show similar rates for different reasons.
  • Season mixing: the catcher and umpire leaderboards mix all 2022-2023 games into one rate per entity, and the umpire cut's corpus_id differs from the top-level corpus_id in a way the source does not document.
  • Floors: the published floors differ across the three leaderboards and are event-count, not variance-based; Table 3 shows a batter can clear the pitches-faced floor with a batted-ball sample under 100.
  • Not a forecast input: the umpire rate was tested directly as a predictor of game totals and rejected (umpire_totals_gate.verdict); no equivalent test is published for the other two.
  • No shrinkage for batter contact: this leaderboard is not covered by the site's shrinkage artifact, so no small-sample-adjusted version of the gap is available.

7 How to read this on the site

On the site, the mlb_descriptive_leaderboards module page carries the same 15-up-and-15-down rows per group this note excerpts -- no full 113-catcher or 102-umpire table is published anywhere -- plus the park-factor null and the umpire-totals REJECT in full; the atlas_mlb_batters_manifest data behind Table 3 is browsable per batter, including key_numbers fields not used here (velo_seen percentiles, average estimated wOBA on contact). The research-lab pages 'MLB catcher out-of-zone strike rate selections' and 'Batter exit velocity: P90 versus mean' present these same rows in sortable form, and 'How sample size changes a rate leaderboard' works through the shrinkage mechanism in full. The count-context inspector page shows how count-leverage class shifts pitch mix, one of the confounds named above.

Evidence

  1. mlb_descriptive_leaderboards.jsonas_of 2026-07-24Source path: /analytics/m/mlb_descriptive_leaderboards/
    Evidence field inventory (30 paths)
    • generated_at
    • source_note
    • observation_window.seasons
    • observation_window.corpus_id
    • observation_window.as_of
    • catcher_ooz.floor
    • catcher_ooz.label
    • catcher_ooz.n_qualified
    • catcher_ooz.top[].name
    • catcher_ooz.top[].n_ooz_called
    • catcher_ooz.top[].ooz_strike_rate
    • catcher_ooz.bottom[].name
    • catcher_ooz.bottom[].n_ooz_called
    • catcher_ooz.bottom[].ooz_strike_rate
    • umpire_ooz.corpus_id
    • umpire_ooz.label
    • umpire_ooz.n_qualified
    • umpire_ooz.top[].name
    • umpire_ooz.top[].n_ooz_called
    • umpire_ooz.top[].ooz_strike_rate
    • umpire_ooz.bottom[].name
    • umpire_ooz.bottom[].n_ooz_called
    • umpire_ooz.bottom[].ooz_strike_rate
    • umpire_totals_gate.verdict
    • umpire_totals_gate.verdict_reason
    • umpire_totals_gate.n_umpires
    • park_factor_null.verdict
    • park_factor_null.n_rows
    • park_factor_null.n_finite_park_factor
    • confounds
  2. mlb_shrinkage.jsonas_of 2026-07-24Source path: /analytics/m/mlb_shrinkage/
    Evidence field inventory (21 paths)
    • method
    • confounds
    • groups[key=catcher_ooz].pooled_mean
    • groups[key=catcher_ooz].kappa
    • groups[key=catcher_ooz].n_entities
    • groups[key=catcher_ooz].biggest_regressors[].name
    • groups[key=catcher_ooz].biggest_regressors[].n
    • groups[key=catcher_ooz].biggest_regressors[].raw_rate
    • groups[key=catcher_ooz].biggest_regressors[].shrunk_rate
    • groups[key=catcher_ooz].biggest_regressors[].regression
    • groups[key=catcher_ooz].top_by_shrunk[].name
    • groups[key=catcher_ooz].top_by_shrunk[].raw_rate
    • groups[key=catcher_ooz].top_by_shrunk[].shrunk_rate
    • groups[key=umpire_ooz].pooled_mean
    • groups[key=umpire_ooz].kappa
    • groups[key=umpire_ooz].n_entities
    • groups[key=umpire_ooz].biggest_regressors[].name
    • groups[key=umpire_ooz].biggest_regressors[].n
    • groups[key=umpire_ooz].biggest_regressors[].raw_rate
    • groups[key=umpire_ooz].biggest_regressors[].shrunk_rate
    • groups[key=umpire_ooz].biggest_regressors[].regression
  3. atlas_mlb_batters_manifest.jsonas_of 2026-07-23Source file: /data/showcase/atlas_mlb_batters_manifest.json (no module page)
    Evidence field inventory (10 paths)
    • generated_at
    • n_entries
    • entries[].entity
    • entries[].key_numbers.batter_id
    • entries[].key_numbers.avg_exit_velo
    • entries[].key_numbers.exit_velo_p90
    • entries[].key_numbers.pitches_faced
    • entries[].key_numbers.n_batted_balls
    • entries[].floors
    • entries[].as_of
  4. statcast_showcase.jsondate not publishedSource path: /analytics/m/statcast_showcase/
    Evidence field inventory (4 paths)
    • source
    • n_pitches
    • sport
    • caveat
Back to research papers