The useful part, up front

What you’ll take away

  • A time step is shared clock arithmetic; looking at a code does not start a new full interval.
  • A verifier can consider earlier steps, but time eligibility does not establish complete acceptance.
  • A matching output can be rejected after prior successful use even while its step remains eligible.
  • Short manually entered OTPs do not provide every property of a multifactor or phishing-resistant protocol.
  • A logged-in session has separate continuity and timeout rules; code turnover alone does not end or renew it.
01

The changing code and the signed-in session have different clocks

An authenticator displays a code that changes on a short schedule. After using it to sign in, you may remain in the account while many more codes appear. That does not by itself mean the old code is still being accepted. TOTP derives a code from a time counter, while a service can maintain a separate session after authentication. [1][4] The code's generation interval and the account's continuing session are different pieces of the sign-in process.

There are four useful questions: which time step generates the code, which steps the verifier currently considers, whether a matching code has already been used, and whether an established session is still valid. We will separate them with original paper examples. RFC 6238 and its HOTP foundation, RFC 4226, are informational documents from 2011 and 2005; the newer verifier and session guidance here is NIST SP 800-63B-4. [1][2][3][4] No account, secret or authentication request is used. The invented acceptance rules and session durations illustrate relationships; they are not settings recommended for a real service.

The code and the continuing session follow different relationships. Conceptual relationships, not a complete implementation. A code match alone does not establish successful authentication.
Conceptual relationships, not a complete implementation. A code match alone does not establish successful authentication. · Ameer Journal — original explanatory diagramOriginal editorial illustration; no third-party artwork reused.
02

The short code is derived from a shared secret and a moving input

TOTP does not require the verifier to send each displayed code to the authenticator. Its documented construction lets both sides derive the expected value from shared secret material and agreed parameters. [1][2] The long-lived secret and the short displayed digits do different jobs. The secret is an input to generation; the displayed value is an output used in an authentication exchange. A countdown beside that output is therefore not a countdown to replacing the underlying secret.

The moving input also distinguishes TOTP from its HOTP foundation. HOTP uses an event counter; TOTP substitutes a counter calculated from time. [1] With the same secret, algorithm and time step, recalculating during that step gives the same output. Opening the app again does not create a new step in this model. We will call the outputs for steps 300 and 301 C300 and C301. Those are labels, not usable codes. For the few steps in our worked timing cases, assume the outputs are different so that we can follow which step a submitted value represents.

03

A thirty-second step does not begin when you look at the screen

RFC 6238 recommends a default time step of 30 seconds and defines a default starting reference of the Unix epoch. [1] Use those parameters for our paper clock, with timestamps measured in seconds after that reference. At timestamp 9,000, dividing by 30 gives step 300. At 9,029, the division is 300 with a remainder, so the step is still 300. At 9,030, the counter reaches 301. The boundaries belong to the shared time calculation, not to the moment a person opens an authenticator.

Suppose someone first reads C300 at 9,012. Eighteen seconds remain until that generation step ends. Someone reading the same value at 9,029 has only one second until the boundary. Both saw a code from a thirty-second step; neither started a new thirty-second interval by looking. The interval is 9,000 inclusive to 9,030 exclusive. This describes generation only. Whether the verifier will still consider that step shortly afterward is a separate policy question, and whether the value has already been used is another.

04

The verifier can consider an earlier step after the display changes

A code can be read near a boundary and arrive after it. RFC 6238 discusses this difference between generation and receiving time, and calls for a bounded validation policy rather than assuming the two timestamps are identical. [1] For our invented verifier, consider the current step and the immediately previous step. This is a teaching rule, not a statement about every authenticator service. Other checks remain separate, and the few symbolic code values are assumed distinct.

Read C300 at 9,029 and let the request arrive at 9,031. Only two seconds have passed, but the verifier is now in step 301. A current-step-only rule would not include 300. Our current-plus-previous rule considers {300,301}, so C300 is still time-eligible. This says nothing yet about prior use or the rest of authentication. Conversely, C299 is outside that candidate set even if someone submits it at the same arrival time. The useful comparison is between the generating step and the verifier's candidate steps, not simply between two countdown displays.

A two-second delivery delay can cross a generation boundary. Original X=30s, T0=0 fixture. Read C300 at t=9029; receive at t=9031. Distinct nearby outputs; time membership only, not complete acceptance.
Original X=30s, T0=0 fixture. Read C300 at t=9029; receive at t=9031. Distinct nearby outputs; time membership only, not complete acceptance. · Ameer Journal — original explanatory diagramOriginal editorial illustration; no third-party artwork reused.
05

A one-second clock difference does not always mean one step of difference

Clock disagreement is separate from delivery delay. RFC 6238 discusses bounded allowances for drift, and NIST's OTP guidance requires a defined lifetime that considers drift, entry time and network delay. [1][3] A fixed difference in seconds does not translate into a fixed difference in the rounded-down step numbers. Whether it crosses a boundary depends on where both clocks are within the step. That distinction explains why the same small clock difference can affect two nearby attempts differently.

Keep our paper verifier and give the authenticator a clock one second ahead, with no transmission delay in this comparison. When the verifier reads 9,028, the authenticator reads 9,029; both calculate 300. One second later, the verifier reads 9,029 while the authenticator reads 9,030: the counters are 300 and 301. Our past-and-current verifier rule does not include that future 301. At verifier time 9,031, the authenticator reads 9,032 and both have 301 again. The unchanged one-second offset has produced step differences of zero, one and zero; the arithmetic does not require the clock error itself to change.

06

A code’s time eligibility can span more than its generation step

Follow step 300 itself through our same verifier rule. It is the current step from 9,000 up to, but not including, 9,030. It is the previous step from 9,030 up to 9,060. Thus it remains a candidate for a total of 60 seconds, even though it is generated for one 30-second step. At 9,060 the verifier considers 301 and 302 instead. This interval follows from our declared current-plus-previous rule, not a universal sixty-second lifetime for authenticator codes.

The sixty-second span also does not mean every person gets sixty seconds after reading the display. Reading at 9,012 leaves 48 seconds until 9,060; reading at 9,029 leaves 31. These are remaining time-eligibility intervals only. Prior successful use can make a matching value unacceptable earlier, and other authentication requirements can still fail. RFC 6238 separates bounded validation from one-time acceptance. [1] Keeping the words time-eligible attached to this calculation prevents a useful clock example from becoming a false promise that a code will always work until its final candidate boundary.

07

Matching the expected digits is different from accepting them again

The authenticator can keep displaying the same output during a step even after that output has been used successfully. That does not make a second use acceptable. RFC 6238 says the verifier must not accept a repeated attempt after the first successful validation; NIST likewise requires a given OTP to be accepted only once while valid. [1][3] The verifier therefore needs to enforce more than agreement between the submitted digits and a freshly computed expectation.

In our sequential paper record, C300 is successfully accepted at 9,008 and its successful use is recorded. At 9,010, it still matches step 300, but a second submission is rejected as already used. At 9,035, step 300 remains inside our time-candidate set, yet the earlier successful-use record still prevents acceptance. These later rejections do not contradict the code calculation. They show that a matching output and an unused output are different conditions. The record is an explanatory state sequence; it does not supply a concurrent server implementation or establish how any particular service stores its replay information.

An already used output can still match the current calculation. Sequential invented record; nearby outputs distinct and successful-use state effective before later events. This is not a concurrent verifier implementation.
Sequential invented record; nearby outputs distinct and successful-use state effective before later events. This is not a concurrent verifier implementation. · Ameer Journal — original explanatory diagramOriginal editorial illustration; no third-party artwork reused.
08

Six digits are a short representation, not an everlasting unique identifier

HOTP's documented construction reduces a larger cryptographic result to a decimal output of a chosen length. [2] With six digits, there are 1,000,000 possible strings, including values with leading zeroes. A formatting example such as 004271 has six digits even though its ordinary integer value is 4,271. This is a made-up display example, not a code generated from a secret or an instruction to enter it anywhere. The short display is designed for entry; its length does not describe the size of the underlying key.

A finite display also cannot assign a different string to every possible counter forever. If 1,000,001 counter inputs are represented by only 1,000,000 six-digit strings, at least two inputs share a string. That counting argument does not locate a collision, predict a neighboring step, or estimate a real attack's success. It explains why our timing examples stated their local distinct-output assumption. NIST also requires rate limiting for single-factor OTP outputs shorter than 64 bits. [3] Output length, bounded attempts and one-time acceptance address related limits; none can be replaced by calling the digits unique.

09

One-time use and a second factor do not establish the same property

An authenticator code can be one part of two-factor sign-in without being two factors by itself. NIST describes a single-factor OTP authenticator as proving possession of the authenticator. It separately describes a multifactor OTP authenticator that requires a local activation factor for each use. [3] Typing a displayed code does not turn that possession proof into a memorized-password factor merely because it passed through a person's memory or keyboard. The factor depends on the mechanism being proved.

Replay resistance is also different from phishing resistance. NIST does not classify manually entered OTP authentication as phishing-resistant, because manual entry does not bind the output to the specific session being authenticated. [3] A short lifetime and rejection after successful use remain useful constraints, but they do not establish that missing binding. This distinction is enough for the current article: we do not reproduce a passkey migration or recovery guide. When describing an authenticator, say which property it provides and which authentication step uses it, instead of treating the changing display as proof of every account-security property.

One-time use, factor type and session binding answer different questions. Scoped to the cited NIST guidance. A changing manually entered OTP is not proof of every authentication property.
Scoped to the cited NIST guidance. A changing manually entered OTP is not proof of every authentication property. · Ameer Journal — original explanatory diagramOriginal editorial illustration; no third-party artwork reused.
10

After authentication, a session carries a different kind of continuity

A service can start an authenticated session after a successful sign-in and use a separate session secret to recognize continuing interactions. NIST's session guidance describes that arrangement and treats browser cookies as one possible session mechanism. [4] The session is not created again every time the authenticator's code changes. This explains how someone can remain signed in while the original OTP has become both used and too old for another authentication attempt.

It also explains the reverse situation. A session may end while the authenticator continues generating perfectly ordinary codes. The session ending has not, by itself, changed the authenticator's shared secret or stopped its clock. These conclusions follow from the separate states in the described model. NIST distinguishes termination, reauthentication and session continuity. [4] A new displayed code is not evidence that an earlier session remains active; an active session is not evidence that the earlier code may be reused. Ask which record the service is evaluating before interpreting either observation.

11

Activity can move an idle deadline without moving the overall deadline

NIST distinguishes an inactivity timeout from an overall session timeout. Activity resets the former, while successful reauthentication resets both in the described model. [4] For a separate invented example, start a session at 10:00 with a twenty-minute overall limit and a five-minute inactivity limit. These chosen durations are not NIST's compliance limits. The initial deadlines are 10:20 overall and 10:05 idle. Activity at 10:03 moves the idle deadline to 10:08; activity at 10:07 moves it to 10:12.

If nothing else happens, the session ends at 10:12 under that idle rule. In a different continuation with sufficiently frequent activity through 10:19, the idle deadline reaches 10:24 but the overall deadline remains 10:20, so that earlier limit ends the session. A third continuation successfully reauthenticates at 10:18 while still active: its new overall deadline is 10:38 and its idle deadline is 10:23. The difference between ordinary activity and reauthentication changes the arithmetic. None of these deadlines is obtained by counting how many thirty-second authenticator codes have appeared.

12

Identify which event succeeded before explaining what remains valid

When an authenticator experience seems inconsistent, describe the actual event. A code appearing proves that the app displayed an output. A time-eligible match answers a narrower question than a completed sign-in. A successful sign-in may establish a session, and later page activity can belong to that session without accepting the original code again. These distinctions follow the generation, verifier and session mechanisms in the cited documents. [1][3][4] They make the observations compatible without assuming that every continued page view reuses an OTP.

For an account owner, use the service's supported sign-in and session controls and keep an unsuccessful attempt separate from a known successful one. For a maintainer, distinguish the relevant counter window, successful-use result, authentication completion and session expiry in the explanation. The examples do not require publishing keys or recording usable codes in a diagnostic report. A clear report can say that a step was outside the declared window, that a matching value was already consumed, or that an idle session ended. Those are different conclusions, and the changing digits alone do not choose among them.

Different session events move different deadlines. Original session starts 10:00; overall 20min, idle 5min. These are invented durations, not NIST limits. The rows are alternative continuations.
Original session starts 10:00; overall 20min, idle 5min. These are invented durations, not NIST limits. The rows are alternative continuations. · Ameer Journal — original explanatory diagramOriginal editorial illustration; no third-party artwork reused.
Follow the evidence

Sources & further reading

Explore the references behind this guide. External pages may change after our review.

  1. RFC 6238 — TOTP: Time-Based One-Time Password Algorithm (May 2011)
    IETF / RFC Editor · Accessed 7 Nov 2026
  2. RFC 4226 — HOTP: An HMAC-Based One-Time Password Algorithm (December 2005)
    IETF / RFC Editor · Accessed 7 Nov 2026
  3. Authenticators
    NIST · Accessed 7 Nov 2026
  4. Session Management
    NIST · Accessed 7 Nov 2026

Article updated 7 Nov 2026.

Found something we should revisit?

Good explanations get better with thoughtful feedback.

Suggest a correction