How JWT expiration works - cover art

JWT and security 14 min read

How JWT expiration works

July 15, 2026 · 14 min read

JWTs expire because self-contained tokens cannot be revoked instantly without extra infrastructure. Time claims exp and nbf bound the valid window in Unix seconds (UTC). Misconfigured clocks and missing leeway cause flaky 401s that look like random auth failures.

Time-related claims at a glance

{
  "sub": "user_42",
  "iat": 1718701200,
  "nbf": 1718701200,
  "exp": 1718704800
}

The exp claim in production

Access tokens commonly live 5–15 minutes; ID tokens may be shorter. Always set exp at issue time - never rely on clients to discard tokens. APIs should fail closed: expired token means 401, not partial access. Log exp minus server time in debug mode to spot skew quickly.

nbf and scheduled activation

nbf delays validity until a future moment - useful for pre-issued tokens or maintenance windows. Fewer validators enforce nbf than exp; enable both in your library for symmetry. If nbf is in the future, treat the token as invalid even if exp is far ahead.

Clock skew and leeway

Servers, laptops, and containers drift. NTP keeps most systems within seconds, but VMs restored from snapshots may jump. Libraries support leeway (e.g. 30–60 seconds) added to exp and subtracted from nbf so minor skew does not break auth. Do not set leeway to minutes - that widens replay windows.

import jwt
from datetime import timedelta

payload = jwt.decode(
    token,
    key,
    algorithms=["HS256"],
    leeway=timedelta(seconds=30),
    options={"require": ["exp", "sub"]},
)

Refresh tokens and rotation

Short exp limits stolen-token damage but annoys users if login is frequent. Issue a long-lived refresh token (opaque or JWT) stored securely; exchange it for new access tokens. Rotate refresh tokens on each use and detect reuse to catch theft. Decode access tokens locally to confirm new exp after refresh.

FAQ

Are JWT exp times UTC?
Yes. exp and nbf are NumericDate seconds since Unix epoch in UTC. Display layers convert to local time.
What leeway should I use?
Typically 30–60 seconds. Increase only if you have proven clock sync problems, and monitor NTP on servers.
Can a token be valid after exp if the signature verifies?
No compliant verifier should accept it. Signature proves integrity, not that time claims are still satisfied.
Should refresh tokens have exp?
Yes. Longer than access tokens, but bounded. Pair with rotation and revoke on logout.

Related: Debug invalid JWT errors

Browse all tools