Written and maintained by CASRAI Editorial Board
Last updated
The degrees of freedom (df) of a two-sample t-test depend on which version of the test you run: n₁ + n₂ − 2 for the pooled (equal-variance) test, and a smaller, usually non-integer value from the Welch-Satterthwaite equation for the unequal-variance test. This guide shows both on the same data, with every step of the arithmetic, so you can see exactly how df, t and p change.
Degrees of freedom for a two-sample t-test: definition
In a two-sample t-test the degrees of freedom are the parameter that selects which t distribution the test statistic is compared against. When the two groups are assumed to share one population variance, df is the total number of observations minus the two group means that had to be estimated: n₁ + n₂ − 2. When that assumption is dropped, df is estimated from the data and is no longer a simple count. Software reports it as the t-test’s parameter (R) or df (SciPy). For the wider idea, see the general guide to degrees of freedom in statistics.
Formula: degrees of freedom of a two-sample t-test, with every symbol explained
Degrees of freedom when variances are equal (pooled)
The NIST/SEMATECH e-Handbook of Statistical Methods gives, for the equal-variance case:
ν = N₁ + N₂ − 2, with the test statistic T = (Ȳ₁ − Ȳ₂) / (sp × √(1/N₁ + 1/N₂)) and sp² = ((N₁ − 1)s₁² + (N₂ − 1)s₂²) / (N₁ + N₂ − 2).
Degrees of freedom when variances are unequal (Welch-Satterthwaite)
For the unequal-variance statistic T = (Ȳ₁ − Ȳ₂) / √(s₁²/N₁ + s₂²/N₂), the same handbook gives:
ν = (s₁²/N₁ + s₂²/N₂)² / [ (s₁²/N₁)²/(N₁ − 1) + (s₂²/N₂)²/(N₂ − 1) ]
- N₁, N₂: the two sample sizes.
- Ȳ₁, Ȳ₂: the two sample means.
- s₁², s₂²: the two sample variances (divisor n − 1).
- sp: the pooled standard deviation (see pooled standard deviation).
- ν (nu): the degrees of freedom.
Two properties follow directly from the Welch-Satterthwaite formula. Write w₁ = s₁²/N₁ and w₂ = s₂²/N₂. By the Cauchy-Schwarz inequality, (w₁ + w₂)² ≤ (w₁²/(N₁ − 1) + w₂²/(N₂ − 1)) × (N₁ + N₂ − 2), so Welch df never exceeds N₁ + N₂ − 2. Because the denominator is at most (w₁ + w₂)² divided by the smaller of N₁ − 1 and N₂ − 1, Welch df is also never below min(N₁, N₂) − 1.
Worked example: pooled df versus Welch df on the same data
Two independent groups (illustrative numbers, computed for this guide): Group A (n₁ = 8): 24, 27, 31, 22, 29, 26, 30, 25. Group B (n₂ = 10): 35, 28, 41, 22, 38, 45, 30, 33, 39, 26.
| Quantity | Group A | Group B |
|---|---|---|
| Mean | 26.75 | 33.70 |
| Sample variance s² | 9.6429 | 52.4556 |
| s²/n | 9.6429 / 8 = 1.2054 | 52.4556 / 10 = 5.2456 |
The variance ratio is 52.4556 / 9.6429 ≈ 5.44, and the group sizes differ, so this is the situation where pooling is questionable. The mean difference is 26.75 − 33.70 = −6.95.
Pooled test (equal variances assumed)
- df = 8 + 10 − 2 = 16.
- sp² = (7 × 9.6429 + 9 × 52.4556) / 16 = 539.60 / 16 = 33.725, so sp = 5.807.
- Standard error = √(33.725 × (1/8 + 1/10)) = √7.5881 = 2.7547.
- t = −6.95 / 2.7547 = −2.523, two-sided p = 0.0226.
Welch test (unequal variances)
- Sum of the two variance terms: 1.2054 + 5.2456 = 6.4509.
- Numerator: 6.4509² = 41.614.
- Denominator: 1.2054² / 7 + 5.2456² / 9 = 0.2076 + 3.0573 = 3.2649.
- df = 41.614 / 3.2649 = 12.746.
- Standard error = √6.4509 = 2.5399, so t = −6.95 / 2.5399 = −2.736, two-sided p = 0.0172.
| Version | df | t | Two-sided p | Critical t (α = .05, two-sided) |
|---|---|---|---|---|
| Pooled | 16 | −2.523 | 0.0226 | 2.120 |
| Welch | 12.746 | −2.736 | 0.0172 | 2.165 |
Welch df (12.746) is lower than the pooled 16, which raises the critical value from 2.120 to 2.165. Here the larger-variance group is also the larger group, so the Welch standard error is smaller than the pooled one and t grows in magnitude. Both tests reject at α = .05 in this example, but the numbers reported are different.
Interpretation: what the df value tells you
| What you see | What it means |
|---|---|
| df = n₁ + n₂ − 2 exactly | The pooled (equal-variance) formula was used. |
| df is a non-integer such as 12.746 | The Welch-Satterthwaite approximation was used. This is correct output, not an error. |
| Welch df much smaller than n₁ + n₂ − 2 | Variances and group sizes are unbalanced; df sits well below the pooled count (but never below min(n₁, n₂) − 1). |
| Welch df close to n₁ + n₂ − 2 | The two sample variances are close to equal, so the Welch df approaches the pooled count (it equals n₁ + n₂ − 2 exactly when the groups are the same size and have identical variances). |
Smaller df means a t distribution with heavier tails, so a larger |t| is needed for the same p-value. For more on reading the statistic itself, see how to interpret the t-statistic and the t-test overview.
Assumptions and common mistakes
- Independence. The two samples must be independent. For paired data use the paired t-test, whose df is n − 1.
- Using n₁ + n₂ − 2 for a Welch test. If the software ran Welch, the df is the Welch-Satterthwaite value, not the simple count.
- Different tool defaults. R’s
t.testsetsvar.equal = FALSEby default and applies the Welch approximation; SciPy’sttest_indsetsequal_var=Trueby default and runs the pooled test. The same data therefore give different df, t and p unless you set the argument yourself. - Rounding df before looking up p. Use the unrounded df with software. If you use a printed table, rounding down gives a conservative critical value.
- Choosing the test from a variance test alone. A significance test for equal variances (see Levene’s test) is one input to the choice. Whatever you choose, state which version you ran.
How to report it (APA example)
APA style reports the degrees of freedom in parentheses after the t symbol. For the Welch result above, with df reported to two decimals: t(12.75) = −2.74, p = .017. For the pooled result: t(16) = −2.52, p = .023. Say in the text which version was run, for example “Welch’s t-test for unequal variances”, and report the group means and standard deviations alongside it.
How to calculate it in Excel, R or Python
Excel
Excel’s T.TEST(array1, array2, tails, type) takes type 2 for a two-sample test assuming equal variance and type 3 for unequal variance, and returns only a probability, not the df. Compute df from the formulas, with Group A in A2:A9 and Group B in B2:B11:
Pooled df: =COUNT(A2:A9)+COUNT(B2:B11)-2
Welch df: =(VAR.S(A2:A9)/COUNT(A2:A9)+VAR.S(B2:B11)/COUNT(B2:B11))^2/((VAR.S(A2:A9)/COUNT(A2:A9))^2/(COUNT(A2:A9)-1)+(VAR.S(B2:B11)/COUNT(B2:B11))^2/(COUNT(B2:B11)-1))
R
a <- c(24,27,31,22,29,26,30,25)
b <- c(35,28,41,22,38,45,30,33,39,26)
t.test(a, b)$parameter # Welch (default): 12.74607
t.test(a, b, var.equal = TRUE)$parameter # pooled: 16
See also running a t-test in R.
Python (SciPy)
import numpy as np
from scipy import stats
a = [24,27,31,22,29,26,30,25]
b = [35,28,41,22,38,45,30,33,39,26]
w = stats.ttest_ind(a, b, equal_var=False) # Welch
p = stats.ttest_ind(a, b) # pooled (default)
print(w.df, p.df) # 12.746..., 16.0 (df attribute: SciPy 1.11.0 or later)
# by hand, any version:
w1 = np.var(a, ddof=1)/len(a); w2 = np.var(b, ddof=1)/len(b)
print((w1+w2)**2 / (w1**2/(len(a)-1) + w2**2/(len(b)-1)))
In SPSS the independent-samples output shows both rows; see the independent-samples t-test in SPSS.
Frequently asked questions
What is the degrees of freedom for a two-sample t-test?
It is n₁ + n₂ − 2 when the pooled equal-variance test is used, and the Welch-Satterthwaite value when variances are not assumed equal. The Welch value is at most n₁ + n₂ − 2.
Why is the degrees of freedom for a two sample t test not a whole number?
The Welch-Satterthwaite equation estimates df from both sample variances and sizes, and the result is generally fractional. Software accepts it directly.
Which degrees of freedom does my software use by default?
R’s t.test defaults to var.equal = FALSE (Welch). SciPy’s ttest_ind defaults to equal_var=True (pooled). Excel’s T.TEST uses whatever type (2 or 3) you supply.
Should I round Welch degrees of freedom?
Not when software computes the p-value. For a printed table, round down for a conservative result, and report two decimals in the write-up.
For a comparison with the z-test, see z-test vs t-test.
Sources
- NIST/SEMATECH e-Handbook of Statistical Methods, section 1.3.5.3 “Two-Sample t-Test for Equal Means”, itl.nist.gov/div898/handbook/eda/section3/eda353.htm (checked 2026-10-29).
- R Documentation,
stats::t.test, stat.ethz.ch/R-manual/R-devel/library/stats/html/t.test.html (checked 2026-10-29). - SciPy documentation,
scipy.stats.ttest_ind, docs.scipy.org/doc/scipy/reference/generated/scipy.stats.ttest_ind.html (checked 2026-10-29). - Microsoft Support, T.TEST function, support.microsoft.com/en-us/office/t-test-function-d4e08ec3-c545-485f-962e-276f7cbed055 (checked 2026-10-29).







