Personal Finance for India Module 2 – Your first salary: offer, payslip and benefits
CTC vs in-hand pay: reading an offer letter
Split a CTC into what reaches your account and what does not, work out pay in hand under both tax regimes, and see what the 50 % wage rule changes.
What you will learn
- Split a CTC into monthly pay, pay that may come, retirement money and insurance
- Calculate monthly pay in hand from gross pay under both tax regimes
- Apply the Labour Codes' 50 % wage rule to a pay structure and its PF and gratuity
- Identify the lines of an offer that depend on conditions or may have to be repaid
Before you start
What you’ll learn · Before you start
What you will learn
- Split a CTC into monthly pay, pay that may come, retirement money and insurance
- Calculate monthly pay in hand from gross pay under both tax regimes
- Apply the Labour Codes' 50 % wage rule to a pay structure and its PF and gratuity
- Identify the lines of an offer that depend on conditions or may have to be repaid
Before you start
On this page
Asha’s offer letter says ₹6,50,000 a year, and her first salary credit is ₹42,000. Twelve credits of ₹42,000 come to ₹5,04,000, so where does the other ₹1,46,000 go?
None of it is lost. A cost to company (CTC): Everything an employer expects to spend on an employee in a year: monthly pay, variable pay, its own PF contribution, a gratuity provision and benefits such as insurance. Only part of it reaches the employee's bank account each month., is what an employer expects to spend on you in a year, and only part of it is paid into your account each month. Below you will split Asha’s CTC line by line, take her pay down to the ₹42,000 in her account, see what each tax regime does to it, test a pay structure against the Labour Codes’ 50 % rule, and sort the lines of an offer you can count on from those that depend on conditions. Everything here is education only, worked from the laws and the employer’s documents; none of it is advice on which offer, product or tax regime to choose.
A CTC is your employer’s cost, not your pay
Asha’s offer letter breaks her CTC into eight lines:
| Line of the offer letter | A year | A month |
|---|---|---|
| Basic pay | ₹3,00,000 | ₹25,000 |
| House rent allowance (HRA) | ₹1,20,000 | ₹10,000 |
| Conveyance allowance | ₹60,000 | ₹5,000 |
| Leave travel allowance | ₹62,400 | ₹5,200 |
| Variable pay, a target | ₹50,000 | once a year |
| Employer’s PF contribution | ₹36,000 | ₹3,000 |
| Gratuity, 4.81 % of basic pay | ₹14,430 | none |
| Group health insurance | ₹7,170 | none |
| CTC | ₹6,50,000 |
The eight lines behave in four ways. The first four are her pay, paid with each month’s salary; together they are her gross pay: A month's pay before any deduction: basic pay plus the allowances. The employee's own PF, professional tax and income tax come out of it; the employer's PF contribution is not part of it.. Variable pay is a target that her rating and the company’s results decide. The employer’s contribution to her Employees' Provident Fund (EPF): The savings account EPFO keeps for each member: 12 % of PF wages from the employee and the part of the employer's 12 % that does not go to the pension scheme, with interest declared for each year. More in “EPF, EPS and VPF: your provident fund” goes to her PF account and her pension, and the gratuity line is money set aside for a lump sum that the law pays only after five years of service. The insurance premium buys cover, not cash. Step through where each rupee of the CTC goes:
The drawing shows the whole scene; its 6 steps are listed below.
Every step as text
- The whole cost. Asha's offer letter says CTC ₹6,50,000 a year. It is everything her employer expects to spend on her in a year, and only part of it is paid to her.
- Pay that comes monthly. Basic pay, house rent allowance and two allowances come with each month's salary, ₹5,42,400 a year or ₹45,200 a month before deductions. That is 83.4 % of the CTC.
- Pay that may come. Variable pay of ₹50,000 is a target, paid once a year if her rating and the company's results allow it. The dashed arrow marks money that may not arrive, 7.7 % of the CTC.
- Money kept for later. The employer's PF, ₹36,000, goes to her provident fund account and her pension, not to her bank. The gratuity line, ₹14,430, is set aside for a lump sum paid only after five years of service. Together they are 7.8 %.
- Cover, not cash. ₹7,170 is the premium her employer pays an insurer for group health cover. She can use the cover if she is in hospital, but the money never reaches her. That is 1.1 % of the CTC.
- What reaches her. Only the monthly pay reaches her bank account every month, and only after her own PF, professional tax and any income tax come out of it. Her pay in hand is ₹42,000.
The program adds the lines up exactly and works out one month:
"""Asha's offer letter: where each rupee of a Rs 6,50,000 CTC goes, and what reaches her account each month.
Asha and her offer are invented for the lesson. The rules are the ones the lesson cites: she and her employer each pay
12 % of her PF wages (Rs 25,000 a month, the EPF wage ceiling), the gratuity line is the common 4.81 % of basic pay,
and Maharashtra's professional tax for a woman paid more than Rs 25,000 a month is Rs 200 (Rs 300 in February). Her
income tax under the new regime is nil (the next program works it out). Money is worked with the decimal module.
"""
from decimal import ROUND_HALF_UP, Decimal
def inr(amount, places="1"):
"""Rupees with Indian digit grouping: 542400 -> "₹5,42,400"; places="0.01" keeps paise."""
value = Decimal(amount).quantize(Decimal(places), rounding=ROUND_HALF_UP)
whole, _, paise = str(abs(value)).partition(".")
head, tail = whole[:-3], whole[-3:]
groups = []
while len(head) > 2:
groups.insert(0, head[-2:])
head = head[:-2]
if head:
groups.insert(0, head)
text = ",".join(groups + [tail]) if groups else tail
return ("−" if value < 0 else "") + "₹" + text + ("." + paise if paise else "")
def share(part, whole):
return (Decimal(part) / Decimal(whole) * 100).quantize(Decimal("0.1"), rounding=ROUND_HALF_UP)
# Each line of the offer letter: (name, rupees a year, where the money goes)
OFFER = [
("Basic pay", 300000, "Paid with each month's salary"),
("House rent allowance", 120000, "Paid with each month's salary"),
("Conveyance allowance", 60000, "Paid with each month's salary"),
("Leave travel allowance", 62400, "Paid with each month's salary"),
("Variable pay (target)", 50000, "Paid once a year, if earned"),
("Employer's PF", 36000, "Kept for her retirement"),
("Gratuity (4.81 % of basic)", 14430, "Kept for her retirement"),
("Group health insurance", 7170, "Paid to an insurer"),
]
CTC = sum(amount for _, amount, _ in OFFER)
print(f"Part 1: Asha's CTC of {inr(CTC)} a year, by where it goes")
groups = {}
for _, amount, where in OFFER:
groups[where] = groups.get(where, 0) + amount
for where, amount in groups.items():
print(f" {where:<31}{inr(amount):>10}{share(amount, CTC):>7} %")
print()
print("Part 2: one month's pay")
basic = Decimal(300000) / 12
gross = Decimal(groups["Paid with each month's salary"]) / 12
pf_wages = min(basic, Decimal(25000))
own_pf = (pf_wages * Decimal("0.12")).quantize(Decimal("1"), rounding=ROUND_HALF_UP)
professional_tax = Decimal(200)
tds = Decimal(0)
in_hand = gross - own_pf - professional_tax - tds
print(f" {'Gross pay':<30}{inr(gross):>12}")
print(f" {'Her PF, 12 % of ' + inr(pf_wages):<30}{inr(-own_pf):>12}")
print(f" {'Professional tax':<30}{inr(-professional_tax):>12}")
print(f" {'Income tax (TDS), new regime':<30}{inr(-tds):>12}")
print(f" {'In hand':<30}{inr(in_hand):>12}")
twelfth = Decimal(CTC) / 12
print(f" {'A twelfth of the CTC':<30}{inr(twelfth, '0.01'):>12}")
print(f" In hand is {share(in_hand, twelfth)} % of a twelfth of the CTC.")
print(f" In February, with ₹300 of professional tax: {inr(in_hand - 100)}.")
print()
print("Part 3: the gratuity line")
per_year = basic / 26 * 15
print(f" Counted in the CTC each year: {inr(14430):>11}")
print(f" Earned by a completed year (÷ 26 × 15): {inr(per_year, '0.01'):>9}")
print(" Paid only after five years of continuous service.")
print(f" Leaving after three years: {inr(3 * 14430)} counted, ₹0 paid.") Output
Part 1: Asha's CTC of ₹6,50,000 a year, by where it goes Paid with each month's salary ₹5,42,400 83.4 % Paid once a year, if earned ₹50,000 7.7 % Kept for her retirement ₹50,430 7.8 % Paid to an insurer ₹7,170 1.1 % Part 2: one month's pay Gross pay ₹45,200 Her PF, 12 % of ₹25,000 −₹3,000 Professional tax −₹200 Income tax (TDS), new regime ₹0 In hand ₹42,000 A twelfth of the CTC ₹54,166.67 In hand is 77.5 % of a twelfth of the CTC. In February, with ₹300 of professional tax: ₹41,900. Part 3: the gratuity line Counted in the CTC each year: ₹14,430 Earned by a completed year (÷ 26 × 15): ₹14,423.08 Paid only after five years of continuous service. Leaving after three years: ₹43,290 counted, ₹0 paid.
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 ctc_breakup.py
Its first part is the figure in numbers: 83.4 % of the CTC is monthly pay, and 16.6 % is money she cannot spend this month, or perhaps ever. Its last part shows why the gratuity line deserves a second look. The offer counts ₹14,430 a year for it, a common shortcut of 4.81 % of basic pay, while a completed year of service earns ₹14,423.08 by the formula of section 53 of the Code on Social Security, 2020. More important, a permanent employee who resigns before five years of continuous service is paid no gratuity at all, so three years in this job would count ₹43,290 in her CTC that she never receives.
Comparing two offers by their CTC
Wrong: “the second offer is ₹6,80,000, so it pays ₹30,000 more”. Right: “compare the gross pay and the pay in hand first, then what is kept for later and what depends on conditions”. A larger CTC can be a larger variable target, a costlier insurance line or a gratuity line you never reach.
Checkpoint
Check: What a CTC holds besides pay
In-hand pay is gross pay less your PF, professional tax and TDS
Asha’s gross pay is ₹45,200 a month. Three deductions stand between it and her account, and each is set by a different rule:
- Her own PF. She pays 12 % of her PF wages into her provident fund and her employer adds 12 % of its own, as EPFO’s guidance on the ₹25,000 wage ceiling: The monthly PF wages, ₹25,000, up to which EPF, EPS and EDLI membership is required. Contributions on wages above it may be worked out on the ceiling instead. More in “EPF, EPS and VPF: your provident fund” sets out. Her PF wages are her basic pay, ₹25,000, so her share is ₹3,000 a month.
- Professional tax. Some States tax employment, and the Constitution caps the tax at ₹2,500 a year for one person (article 276(2)). Maharashtra’s schedule charges a woman paid more than ₹25,000 a month ₹200 a month and ₹300 in February, ₹2,500 in all.
- Income tax deducted at source. Her employer deducts each month a share of the tax it expects on her year’s salary (section 392 of the Income-tax Act, 2025). For Asha that share is nil, as the next section shows.
Follow her pay through the three deductions:
The drawing shows the whole scene; its 5 steps are listed below.
Every step as text
- Gross pay. Her basic pay, house rent allowance, conveyance and leave travel allowances add up to ₹45,200. Her employer's own PF contribution is not in this figure; it sits in the CTC on top of it.
- Her PF. Twelve per cent of her PF wages of ₹25,000, ₹3,000, goes to her provident fund account. It is still her money, but she cannot spend it this month.
- Professional tax. Maharashtra charges a woman paid more than ₹25,000 a month ₹200 of professional tax, and ₹300 in February, ₹2,500 a year in all.
- TDS. Her employer deducts each month a share of the income tax it expects on her year's salary. Under the new regime her tax for the year is nil, so nothing is deducted.
- In hand. ₹42,000 is credited to her account, 77.5 % of a twelfth of her CTC. In February, with ₹300 of professional tax, it is ₹41,900.
₹42,000 reaches her account, 77.5 % of a twelfth of her CTC, and ₹41,900 in February. Notice what was never deducted: her employer’s ₹3,000 of PF. It is paid on top of her gross pay, inside the CTC, and EPFO’s guidance adds that an employer’s statutory contribution cannot be turned into a deduction from the employee just by calling it part of the CTC.
Thinking both shares of PF come out of your pay
Wrong: “₹6,000 of PF is cut from my salary every month”. Right: “₹3,000 is cut from my gross pay; my employer’s ₹3,000 is paid on top of it, into my PF account and my pension”.
Checkpoint
Check: From gross pay to pay in hand
The tax regime changes your TDS, not your gross pay
The Income-tax Act, 2025 taxes a salary in one of two ways, and the employer’s TDS follows the one it is told to assume. The The default way the Income-tax Act, 2025 taxes an individual: lower slab rates, a standard deduction of ₹75,000 from salary and a rebate up to ₹12 lakh of income, but few other deductions. is the default (section 202): nil tax on the first ₹4 lakh of income, a standard deduction of ₹75,000 from salary, and a rebate that cancels the tax when income is ₹12 lakh or less (section 156), but almost no other deductions. The old regime, which a person can choose instead, taxes income above ₹2.5 lakh and gives a ₹50,000 standard deduction, but it lets professional tax, part of the HRA of someone who pays rent, and up to ₹1,50,000 of items such as your own PF (section 123) come off first. Its rebate stops at ₹5 lakh of income. A person with no business income makes the final choice for the year with the return (section 202(4)(b)).
The program works out Asha’s tax both ways in two cases: renting her share of a flat in Pune for ₹11,000 a month, and living at home with no rent to pay:
"""Asha's income tax for Tax Year 2026-27 under both regimes, renting in Pune and living at home, and her pay in hand.
Rules (Income-tax Act, 2025, with the rates of the Finance Act, 2026): new regime slabs of section 202(1) and a
standard deduction of Rs 75,000; old regime slabs (nil to Rs 2.5 lakh, 5 %, 20 %, 30 %) and a standard deduction of
Rs 50,000, with professional tax, the HRA exemption of rule 279 and her own PF under section 123 also deducted; the
rebate of section 156 (new regime: tax up to Rs 60,000 when income is at most Rs 12 lakh, with marginal relief; old
regime: up to Rs 12,500 when income is at most Rs 5 lakh); 4 % cess; income and tax rounded to Rs 10 (section 516).
Asha is invented; her rent is her share of a flat, Rs 11,000 a month.
"""
from decimal import ROUND_HALF_UP, Decimal
D = Decimal
def inr(amount, places="1"):
"""Rupees with Indian digit grouping: 1381120 -> "₹13,81,120"; places="0.01" keeps paise."""
value = D(amount).quantize(D(places), rounding=ROUND_HALF_UP)
whole, _, paise = str(abs(value)).partition(".")
head, tail = whole[:-3], whole[-3:]
groups = []
while len(head) > 2:
groups.insert(0, head[-2:])
head = head[:-2]
if head:
groups.insert(0, head)
text = ",".join(groups + [tail]) if groups else tail
return ("−" if value < 0 else "") + "₹" + text + ("." + paise if paise else "")
def round_to_ten(amount):
"""Section 516: drop the paise, then round to the nearest ₹10 (a last digit of 5 or more rounds up)."""
rupees = int(amount)
return rupees - rupees % 10 + (10 if rupees % 10 >= 5 else 0)
def slab_tax(income, slabs):
"""Tax on income for slabs given as (upper limit or None, rate)."""
tax, lower = D(0), D(0)
for upper, rate in slabs:
top = income if upper is None else min(income, D(upper))
if top > lower:
tax += (top - lower) * D(rate)
if upper is None or income <= upper:
break
lower = D(upper)
return tax
NEW = [(400000, "0"), (800000, "0.05"), (1200000, "0.10"), (1600000, "0.15"), (2000000, "0.20"), (2400000, "0.25"), (None, "0.30")]
OLD = [(250000, "0"), (500000, "0.05"), (1000000, "0.20"), (None, "0.30")]
def tax_payable(income, regime):
income = D(round_to_ten(income))
tax = slab_tax(income, NEW if regime == "new" else OLD)
if regime == "new" and income <= 1200000:
tax = D(0) # the rebate covers all of it up to ₹60,000, and the slabs give ₹60,000 at ₹12 lakh
elif regime == "new":
tax = min(tax, income - 1200000) # marginal relief
elif income <= 500000:
tax = max(D(0), tax - min(tax, D(12500)))
return D(round_to_ten(tax * D("1.04"))), income
SALARY = D(542400 + 50000) # fixed pay for the year plus her variable pay
BASIC, HRA, OWN_PF, PROFESSIONAL_TAX = D(300000), D(120000), D(36000), D(2500)
def hra_exempt(rent_a_month):
"""Rule 279: the least of the HRA received, rent less 10 % of salary, and 50 % of salary in Pune."""
if rent_a_month == 0:
return D(0)
return min(HRA, max(D(0), 12 * D(rent_a_month) - BASIC / 10), BASIC / 2)
print(f"Salary for the year: {inr(SALARY)}, variable pay included")
print()
print(f"{'Case':<17}{'Regime':<7}{'Income':>11}{'Tax':>10}{'In hand':>11}")
for case, rent in (("Renting in Pune", 11000), ("Living at home", 0)):
new_income = SALARY - 75000
old_income = SALARY - hra_exempt(rent) - 50000 - PROFESSIONAL_TAX - OWN_PF
for regime, income in (("new", new_income), ("old", old_income)):
tax, counted = tax_payable(income, regime)
in_hand = D(45200) - 3000 - 200 - tax / 12
print(f"{case:<17}{regime:<7}{inr(counted):>11}{inr(tax):>10}{inr(in_hand):>11}")
print()
tax, counted = tax_payable(old_income, "old")
print(f"Living at home, the old regime counts {inr(counted)}: {inr(counted - 500000)} above")
print(f"₹5,00,000, where its rebate stops. Its tax of {inr(tax)} a year is")
print(f"{inr(tax / 12, '0.01')} of TDS a month; the new regime takes nothing.") Output
Salary for the year: ₹5,92,400, variable pay included Case Regime Income Tax In hand Renting in Pune new ₹5,17,400 ₹0 ₹42,000 Renting in Pune old ₹4,01,900 ₹0 ₹42,000 Living at home new ₹5,17,400 ₹0 ₹42,000 Living at home old ₹5,03,900 ₹13,810 ₹40,849 Living at home, the old regime counts ₹5,03,900: ₹3,900 above ₹5,00,000, where its rebate stops. Its tax of ₹13,810 a year is ₹1,150.83 of TDS a month; the new regime takes nothing.
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 regime_takehome.py
Renting, neither regime takes anything. In the new regime her ₹5,92,400 of salary less ₹75,000 is ₹5,17,400, well inside the rebate. In the old regime the HRA exemption, the ₹50,000, professional tax and her own PF bring her to ₹4,01,900, inside that regime’s ₹5 lakh line. Living at home she has no rent to claim, so the old regime counts ₹5,03,900, just ₹3,900 above the line where its rebate stops, and the tax jumps to ₹13,810 a year: ₹1,150.83 off every month’s pay if payroll spreads it evenly. The new regime has no such jump just above ₹12 lakh, because its rebate tapers: the tax before cess never exceeds the income above ₹12 lakh.
Read the regime on your payslip
Payroll needs to know which regime to assume, and its TDS follows that choice all year. If a payslip shows a regime you did not expect, ask payroll before the deductions pile up; the choice you make with the return decides the year’s tax.
Checkpoint
Check: How the tax regime changes TDS
The 50 per cent wage rule can raise PF and gratuity on a low basic
PF and gratuity are worked out on wages, and the four Labour Codes, which the government has brought into force, define wages the same way for both (Code on Wages, 2019, section 2(y); Code on Social Security, 2020, section 2(88)). wages (Labour Codes): Pay as the Labour Codes count it for PF and gratuity: all remuneration except listed items such as house rent and conveyance allowances. If the listed items are more than half of all pay, the excess is added back to wages. are all remuneration, including basic pay, dearness allowance and retaining allowance, except a list of payments: house rent allowance, conveyance allowance, travel concessions, overtime, commission, the employer’s own PF contribution and a few more. Pay that the list does not name, a special allowance for example, counts as wages from the start. The rule that reshapes salary structures is a proviso: if the listed payments are more than half of all the pay, the excess is added back to wages.
Asha’s structure passes the test: her HRA, conveyance and leave travel allowances are ₹20,200 of her ₹45,200, 44.7 %, so her wages are her basic pay. A structure that keeps basic pay low does not pass. Follow the test on an offer of ₹40,000 a month with a basic pay of ₹15,000:
The drawing shows the whole scene; its 6 steps are listed below.
Every step as text
- All the pay. The offer pays ₹40,000 a month: basic pay of ₹15,000, house rent allowance of ₹15,000, a conveyance allowance of ₹6,000 and a leave travel allowance of ₹4,000.
- The exclusions. House rent allowance, conveyance allowance and travel concessions are on the Codes' list of payments that are not wages. Here they come to ₹25,000, 62.5 % of the pay.
- The limit. The exclusions may be at most half of all the pay. Half of ₹40,000 is ₹20,000, so these exclusions are ₹5,000 over the limit.
- The add-back. The ₹5,000 above half is treated as wages. Without the rule, wages would be only the ₹15,000 of basic pay.
- The wages. Wages under the Codes are ₹15,000 of basic pay plus the ₹5,000 added back, ₹20,000 a month.
- What follows. PF is 12 % of ₹20,000, ₹2,400 a month on each side instead of ₹1,800, and a year of service earns ₹11,538.46 of gratuity instead of ₹8,653.85.
The program runs the same test on both structures:
"""The Labour Codes' 50 % rule on two monthly pay structures, and what it changes in PF and gratuity.
"Wages" (Code on Wages, 2019, section 2(y); Code on Social Security, 2020, section 2(88)) are all remuneration,
including basic pay, dearness allowance and retaining allowance, but not the listed exclusions, among them house rent
allowance, conveyance allowance and travel concessions. If the exclusions are more than half of all remuneration, the
excess is added back to wages. Both structures are invented; this program leaves the employer's own PF contribution
out of the test. PF is 12 % of wages up to the Rs 25,000 ceiling; gratuity is 15 days' wages (wages / 26 x 15) for each
year of service.
"""
from decimal import ROUND_HALF_UP, Decimal
D = Decimal
def inr(amount, places="1"):
"""Rupees with Indian digit grouping: 11538.46 -> "₹11,538.46" with places="0.01"."""
value = D(amount).quantize(D(places), rounding=ROUND_HALF_UP)
whole, _, paise = str(abs(value)).partition(".")
head, tail = whole[:-3], whole[-3:]
groups = []
while len(head) > 2:
groups.insert(0, head[-2:])
head = head[:-2]
if head:
groups.insert(0, head)
text = ",".join(groups + [tail]) if groups else tail
return ("−" if value < 0 else "") + "₹" + text + ("." + paise if paise else "")
EXCLUDED = {"House rent allowance", "Conveyance allowance", "Leave travel allowance"}
STRUCTURES = {
"Asha's offer": {"Basic pay": 25000, "House rent allowance": 10000, "Conveyance allowance": 5000, "Leave travel allowance": 5200},
"A low-basic offer": {"Basic pay": 15000, "House rent allowance": 15000, "Conveyance allowance": 6000, "Leave travel allowance": 4000},
}
for n, (name, parts) in enumerate(STRUCTURES.items()):
if n:
print()
total = D(sum(parts.values()))
excluded = D(sum(v for k, v in parts.items() if k in EXCLUDED))
basic = D(parts["Basic pay"])
added = max(D(0), excluded - total / 2)
wages = total - excluded + added
share = (excluded / total * 100).quantize(D("0.1"))
print(f"{name}: pay {inr(total)} a month, exclusions {inr(excluded)} ({share} %)")
print(f" Half of the pay is {inr(total / 2)}; added back: {inr(added)}; wages: {inr(wages)}")
print(f" {'Worked on':<15}{'PF each side':>14}{'Gratuity a year':>17}")
for label, base in (("basic pay", basic), ("wages", wages)):
pf = (min(base, D(25000)) * D("0.12")).quantize(D("1"), rounding=ROUND_HALF_UP)
gratuity = base / 26 * 15
print(f" {label:<15}{inr(pf):>14}{inr(gratuity, '0.01'):>17}") Output
Asha's offer: pay ₹45,200 a month, exclusions ₹20,200 (44.7 %) Half of the pay is ₹22,600; added back: ₹0; wages: ₹25,000 Worked on PF each side Gratuity a year basic pay ₹3,000 ₹14,423.08 wages ₹3,000 ₹14,423.08 A low-basic offer: pay ₹40,000 a month, exclusions ₹25,000 (62.5 %) Half of the pay is ₹20,000; added back: ₹5,000; wages: ₹20,000 Worked on PF each side Gratuity a year basic pay ₹1,800 ₹8,653.85 wages ₹2,400 ₹11,538.46
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 wage_rule.py
On the low-basic offer the rule lifts wages from ₹15,000 to ₹20,000. PF rises from ₹1,800 to ₹2,400 a month on each side, so ₹600 less reaches the account each month while ₹1,200 more goes into PF and pension, and each year of service earns ₹11,538.46 of gratuity instead of ₹8,653.85. On Asha’s offer nothing changes.
One detail is read two ways: whether the employer’s own PF contribution, itself on the list, also joins the test. The program leaves it out. Counted in, it raises the low-basic offer’s wages a little further, to ₹21,276.50 in the Labour Code salary calculator, which can work the test out either way.
Labour Code Salary Structure Calculator (India) Enter each line of a pay structure and see the wages, PF and gratuity the 50 % rule gives.Key idea
Under the Labour Codes a structure can no longer keep PF and gratuity small by keeping basic pay small: when the listed allowances pass half of all pay, the excess counts as wages.
Checkpoint
Check: The Labour Codes' 50 % wage rule
Read what is promised, what depends and what you repay
An offer letter is also the start of a contract, and its conditions decide how much of the CTC you ever receive. Below the numbers, Asha’s letter has two clauses that matter for money: variable pay of “up to ₹50,000”, paid on her rating and the company’s results, and a notice period of two months. Other offers add a joining bonus that must be repaid if you resign within a year, or shares that vest over several years. Each kind of line behaves differently when plans change. Answer the questions about your own offer, and the table marks what you can count on:
Answer the questions above: the table then marks what fits your case and says why the rest does not.
| Line of the offer | Reaches your bank account | Known when you sign | If you leave within a year |
|---|---|---|---|
| Monthly pay | Good every month, after your PF, professional tax and TDS | Good the amounts are written in the letter | Good paid for every month you work |
| Variable pay | Mixed once a year, in cash, when it is paid | Poor a target: a rating and results decide it | Poor the plan's rules for leavers decide it |
| Joining bonus | Good with an early salary, as the letter says | Good a fixed amount in the letter | Poor repaid if the letter has a clause that says so |
| Employer's PF | Poor goes to your PF account and pension, not to your bank | Good 12 % of your PF wages | Good stays yours: it moves with you to the next employer |
| Gratuity line | Poor a lump sum paid only when you leave | Mixed set by law, but only after five years of service | Poor a permanent job pays nothing before five years |
| Group health insurance | Poor paid to an insurer, never to you | Good the cover is described in the employer's policy | Poor group cover can end when you leave |
| Shares that vest later | Poor shares, and only once they vest | Mixed their value moves with the share price | Poor the plan decides what happens to shares not yet vested |
How the answers decide
- “Could you leave this job within its first year?” Yes, possibly: rules out Gratuity line and Shares that vest later and adds a caveat to Joining bonus and Variable pay. Leaving within a year, a permanent job pays no gratuity and shares not yet vested are not yours; a joining bonus may have to be repaid, and variable pay follows the plan's rules for leavers.
- “Are you planning your monthly budget from this offer?” Yes: rules out Variable pay, Joining bonus, Employer's PF, Gratuity line, Group health insurance and Shares that vest later. Only monthly pay arrives every month. Build the budget on your pay in hand and treat every other line as money that comes later, or not at all.
- “Does the letter say variable pay depends on a rating or on results?” Yes: adds a caveat to Variable pay. A target that depends on a rating and on results can be paid in full, in part or not at all.
In short: plan your month on the pay in hand alone, treat variable pay and bonuses as money that may not arrive, and read every clause that says repay, recover or forfeit before you sign. Shares that vest later, such as restricted stock units, are not cash when they are granted, and they carry tax rules of their own, which a later lesson on ESOPs and RSUs covers.
A notice period has a price
A notice period is time you must serve before you leave. If the letter lets you leave sooner by paying for the notice you do not serve, two months at Asha’s gross pay would be ₹90,400, so read the clause before you sign and again before you resign.
Checkpoint
Check: Lines that depend on conditions
Practise: two offers, line by line
Questions on offers and pay, from sorting the lines of a CTC to the 50 % rule. The idea your answers show to be weakest comes first, and every figure in them can be checked against this page:
Practice that adapts to you
Practise this lesson
12 questions about 5 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.
Sort your own offer
Take your own offer letter, or one you have been sent, and write each line under one of four heads: paid every month, may be paid, kept for later, insurance. Then take the monthly lines down to pay in hand with your PF, your State’s professional tax and the TDS under the regime you expect.
Interview questions
Warm-up (fresher): What is the difference between CTC and in-hand salary?
CTC is what the employer expects to spend on you in a year; in-hand salary is what reaches your bank account each month. Between them sit two kinds of difference. Some lines of the CTC are never paid to you monthly: the employer’s PF contribution goes to your PF and pension, the gratuity line is paid only after five years of service, variable pay is a target paid once a year if earned, and insurance premiums buy cover. Then your own deductions come out of the monthly gross pay: your 12 % of PF, your State’s professional tax and the TDS your employer works out. On a ₹6,50,000 CTC with ₹45,200 of gross pay, a first-jobber in Maharashtra under the new regime has ₹42,000 in hand, 77.5 % of a twelfth of the CTC.
Warm-up (fresher): What does the 50 % rule of the Labour Codes do to a salary structure?
It stops a structure from keeping PF and gratuity small by keeping basic pay small. The Codes define wages as all remuneration except a list of payments such as HRA, conveyance allowance and travel concessions. If those listed payments are more than half of all the pay, the excess is added back to wages, and PF, gratuity and other wage-linked dues are worked out on the larger figure. A structure of ₹40,000 with basic pay of ₹15,000 and ₹25,000 of listed allowances has ₹5,000 added back: its wages are ₹20,000, PF becomes ₹2,400 a month on each side instead of ₹1,800, and a year of service earns ₹11,538.46 of gratuity instead of ₹8,653.85. Pay in hand falls by the extra PF.
Key takeaways
- A CTC is the employer’s cost: only its monthly pay lines reach your account, while its PF, gratuity, variable and insurance lines arrive later, partly or never.
- Pay in hand is gross pay less your own 12 % of PF, your State’s professional tax and the TDS your employer works out; the employer’s share of PF is paid on top of your gross pay.
- The regime you declare changes TDS, not gross pay: Asha pays nothing under the new regime, and the old regime would take ₹13,810 a year if she had no rent to claim.
- Under the Labour Codes, listed allowances above half of all pay count as wages, so a low basic pay no longer keeps PF and gratuity low.
- Count only the monthly pay as certain: variable pay, bonuses with repayment clauses, gratuity before five years and unvested shares depend on conditions.
Terms in this lesson
- cost to company (CTC)
- Everything an employer expects to spend on an employee in a year: monthly pay, variable pay, its own PF contribution, a gratuity provision and benefits such as insurance. Only part of it reaches the employee's bank account each month.
- gross pay
- A month's pay before any deduction: basic pay plus the allowances. The employee's own PF, professional tax and income tax come out of it; the employer's PF contribution is not part of it.
- wages (Labour Codes)
- Pay as the Labour Codes count it for PF and gratuity: all remuneration except listed items such as house rent and conveyance allowances. If the listed items are more than half of all pay, the excess is added back to wages.
References
- The Code on Wages, 2019 (section 2(y): definition of wages) (Legislative Department, Ministry of Law and Justice)
- The Code on Social Security, 2020 (sections 2(88) and 53) (Legislative Department, Ministry of Law and Justice)
- Government makes the four Labour Codes effective (Press Information Bureau, Ministry of Labour and Employment)
- Revision of the EPFO statutory wage ceiling: frequently asked questions (Employees' Provident Fund Organisation)
- Notification S.O. 5109(E): wage ceiling of ₹25,000 a month (Ministry of Labour and Employment)
- The Income-tax Act, 2025 (sections 19, 123, 156, 202, 392 and 516) (Legislative Department, Ministry of Law and Justice)
- The Finance Act, 2026 (First Schedule: rates of income-tax) (Legislative Department, Ministry of Law and Justice)
- Income-tax Rules, 2026 (rule 279: house rent allowance) (Central Board of Direct Taxes, Ministry of Finance)
- The Constitution of India (article 276: taxes on professions and employments) (Legislative Department, Ministry of Law and Justice)
- Rate schedules under the Profession Tax Act, 1975 (Department of Goods and Services Tax, Government of Maharashtra)
Related tools
Report a problem with this lesson
Kept only in this browser. Your Learn progress