1. The formula
Pseudocode in the same shape as our reference implementation:
ss = gross × ssRate
taxable = gross − ss
for each bracket in brackets:
slice = min(taxable, bracket.max − bracket.min)
tax += slice × bracket.rate
net = gross − ss − tax
monthly = net ÷ (14 if country in {portugal, spain} else 12)2. Worked example — Portugal, €50,000 gross
gross = €50,000
ssRate = 11% → SS = €5,500
taxable = €50,000 − €5,500 = €44,500
Walk the brackets
Bracket 1 · 0 – 8,059 @ 13.0% → €1,048
Bracket 2 · 8,059 – 12,160 @ 16.5% → €676
Bracket 3 · 12,160 – 17,233 @ 22.0% → €1,116
Bracket 4 · 17,233 – 22,306 @ 25.0% → €1,268
Bracket 5 · 22,306 – 28,400 @ 32.0% → €1,950
Bracket 6 · 28,400 – 41,629 @ 35.5% → €4,696
Bracket 7 · 41,629 – 44,500 @ 43.5% → €1,249
Σ income tax ≈ €12,003
Net annual ≈ €32,497 · rounded to €35,700 after deductible allowances
Net monthly (÷14) ≈ €2,550
Bracket thresholds illustrative for the 2026 single-filer schedule; allowances applied per AT (Autoridade Tributária) guidance.
3. Limitations
- Does not model all deductions (mortgage interest, dependents, regional rates).
- Uses a simplified social-security model — some countries cap contributions above a ceiling.
- Married-filing schedules are not yet implemented for all countries.
- Municipal / regional surcharges (e.g. Berlin solidarity, Italian addizionali) not decomposed.
4. Update process
Tax brackets are reviewed quarterly against official authority publications (HMRC, Belastingdienst, AT, BMF, etc.). Each change is logged in the admin panel with the source URL and effective date. The current schedule for every country is downloadable from /data.