TOTP Explained: How Time-Based 2FA Codes Work
TOTP is the system behind many of the rotating codes you see in authenticator apps. Your authenticator and the website keep the same secret, use the current time, and independently calculate the same short code — which is why the app can work even when it is offline.
Also available in 简体中文

You open an authenticator app and see a six-digit number.
Thirty seconds later, it changes.
The website you are signing in to somehow knows whether the new number is correct — even though the website did not send that code to your phone.
That is TOTP.
TOTP stands for Time-Based One-Time Password. It lets an authenticator and a server independently calculate the same short-lived code from two things they both know:
a shared secret + the current time
That simple relationship explains most of what users see when they use authenticator-based 2FA.
If you already have a Base32 secret, you can see this in practice with the 2FA Code Generator.
How TOTP works in plain English
A normal TOTP setup begins before you ever type a six-digit code.
When you enable authenticator-based 2FA, the service creates a secret.
A simplified example might look like this:
JBSWY3DPEHPK3PXP
The service keeps a copy of that secret.
Your authenticator gets the same secret when you scan the setup QR code or enter the setup key manually.
From that point on, both sides have the same starting information.
They also both know the current time.
So instead of the server sending a new code to your phone, each side performs the same calculation independently:
Shared secret
+
Current time window
↓
TOTP
↓
6-digit code
If both sides have the same secret, compatible TOTP settings and sufficiently synchronized clocks, they should arrive at the same result.
That is the basic idea defined by RFC 6238.
Why the code changes every 30 seconds
TOTP does not use the exact current second directly as the visible code.
It first divides time into fixed windows.
RFC 6238 defines a default time step of 30 seconds.
A simplified version looks like this:
12:00:00 ───────── 12:00:29 → Code A
12:00:30 ───────── 12:00:59 → Code B
12:01:00 ───────── 12:01:29 → Code C
Everyone inside the same time window gets the same time-step value.
That time-step value is combined with the shared secret to calculate the OTP.
Once the clock moves into the next window, the input changes, so the resulting code changes as well.
Thirty seconds is the common default, not a rule that every implementation must use in every situation. TOTP systems can be configured differently, which is one reason provisioning data may include a period value.
For most consumer authenticator setups, however, a 30-second rotation is what users will see.
How can the phone and server generate the same code?
Because TOTP is deterministic.
Given the same:
- secret
- time step
- algorithm
- code length
the calculation produces the same result.
The authenticator does not need to ask the server what today’s code is. It already has everything needed to calculate the code itself.
The server does the same calculation when you attempt to sign in.
Suppose both sides share:
Secret: JBSWY3DPEHPK3PXP
Time window: 12345678
Both independently calculate a result such as:
482913
You type 482913.
The server calculates what it expects for that time window and compares the result with what you entered.
If they match within the server’s accepted time window, authentication can continue.
The important part is that the six-digit code does not need to be delivered to the authenticator.
It is generated.
Why an authenticator app can work offline
This is one of the easiest ways to understand the difference between TOTP and SMS verification.
With SMS, a service generates or selects a code and sends it through a delivery channel.
TOTP works differently.
Once your authenticator has:
- the shared secret
- a working clock
- the correct TOTP parameters
it can calculate codes locally.
It does not need an internet connection every time a new code appears.
That is why you can put a phone into airplane mode and still see many authenticator-based TOTP codes continue to rotate.
The website still needs to receive the code you eventually submit during sign-in, but the authenticator does not need to contact that website just to generate it.
What the QR code has to do with TOTP
When a website asks you to scan a QR code while enabling 2FA, the QR code is usually a convenient way to give your authenticator the setup information it needs.
A common format is an otpauth:// URI.
For example:
otpauth://totp/Example:alice@example.com?secret=JBSWY3DPEHPK3PXP&issuer=Example
Inside that URI are pieces of information the authenticator can use.
The most important one is the secret:
secret=JBSWY3DPEHPK3PXP
The URI may also describe:
- the account
- the issuer
- whether the credential uses TOTP or HOTP
- the algorithm
- the number of digits
- the time period
Scanning the QR code saves you from typing all of that manually.
If you want to understand the secret itself in more detail, read 2FA Secret Keys: What They Are and Where to Find Them.
Why TOTP secrets often look like Base32
A TOTP secret is cryptographic key material, but users and QR-code provisioning systems need a practical way to represent that data as text.
Base32 is commonly used for this.
A Base32 secret may look like:
JBSWY3DPEHPK3PXP
Google Authenticator’s Key URI format specifies the secret parameter as a Base32-encoded value.
Base32 is not the TOTP algorithm itself.
It is simply a convenient text representation of the secret that the TOTP calculation uses.
This distinction matters:
Base32
↓
represents the secret
TOTP
↓
uses the secret + time
6-digit code
↓
is the temporary output
Users often see all three during the same setup process, which is why they are easy to mix up.
Why TOTP codes are usually six digits
TOTP ultimately produces a numeric one-time password that is easier for a person to type than a full cryptographic output.
Six digits are common.
That gives values from 000000 through 999999.
But six digits are not an absolute property of TOTP.
Provisioning formats can support different digit lengths. Google Authenticator’s documented Key URI format, for example, defines both 6- and 8-digit values, with six as the default.
So a more accurate statement is: most TOTP codes users encounter are six digits, but TOTP itself is not limited to exactly six digits.
What actually happens when you sign in
Once TOTP has been enrolled, a typical login looks like this:
Username / email
↓
Password
↓
Website asks for 2FA code
↓
Authenticator calculates TOTP
↓
You enter the current code
↓
Server calculates expected TOTP
↓
Codes match
↓
Login continues
This is why your original 2FA secret normally does not belong in the login form.
The secret stays with the authenticator.
The temporary TOTP code is what you enter during authentication.
If you have a secret but are unsure how to turn it into the code a website expects, the 2FA Code Generator accepts Base32 secrets and supported otpauth:// input.
TOTP is not the same thing as 2FA
People often use “TOTP”, “2FA code”, “OTP” and “authenticator code” as if they were interchangeable.
They overlap, but they do not mean exactly the same thing.
2FA
Two-factor authentication describes an authentication process that uses two different factors.
TOTP is one way to provide a factor.
Other 2FA systems may use:
- security keys
- passkeys
- push approvals
- SMS
- hardware tokens
- other authentication methods
So:
TOTP can be used in 2FA, but not all 2FA is TOTP.
OTP
OTP means One-Time Password or One-Time Passcode.
It is a broader category.
TOTP is one type of OTP.
TOTP
TOTP specifically means that time is used as the moving input that causes the code to change.
That is what the T stands for.
TOTP and HOTP use a different moving value
TOTP is built on HOTP, the HMAC-Based One-Time Password algorithm defined in RFC 4226.
The easiest way to distinguish them is not by the appearance of the code.
It is by asking what makes the next code different.
For HOTP:
shared secret + counter
For TOTP:
shared secret + time-derived counter
So:
| TOTP | HOTP | |
|---|---|---|
| Shared secret | Yes | Yes |
| Changing input | Time | Counter |
| Typical code change | After a time window | After the counter advances |
| Standard | RFC 6238 | RFC 4226 |
That difference is enough for this article. Synchronization and implementation differences belong on a dedicated TOTP vs HOTP page later, rather than being expanded here.
Why an otherwise correct TOTP code can fail
Understanding how TOTP works also explains several common failures.
The clocks do not agree closely enough
TOTP depends on time.
If the authenticator’s clock is far enough from the server’s clock, the two sides may calculate codes for different time windows.
The secret is wrong
Two systems with different secrets will not calculate the same code, even if every other setting matches.
The account was re-enrolled
If 2FA was reset and the service issued a new secret, an authenticator still using the old secret can continue generating perfectly valid-looking numbers.
They are simply valid for the wrong secret.
The parameters are different
Digit length, period and algorithm can be part of TOTP configuration.
A mismatch can lead to different outputs.
The code crossed into the next time window
A code near the end of its period may expire while you are switching tabs or typing.
Some services allow a small amount of clock skew or adjacent time windows, but that behavior is controlled by the verifier rather than guaranteed by TOTP itself.
If your secret appears correct but the site keeps rejecting the code, continue with 2FA Code Not Working: Common Causes and Fixes.
Try TOTP with a secret you already have
Once you understand TOTP, the whole flow becomes much less mysterious:
Secret
+
Time
↓
TOTP
↓
Temporary authentication code
If you already have a Base32 secret or supported otpauth:// URI, open the 2FA Code Generator.
Generate the current code, then use that code where the service asks for an authenticator or 2FA code. The login sequence itself is in How to Use a 2FA Secret Key: Generate a Code and Sign In.