Bitcoin Timelock Types Compared: nLockTime, CLTV, CSV, Taproot
Compare Bitcoin timelock mechanisms: nLockTime, OP_CHECKLOCKTIMEVERIFY, OP_CHECKSEQUENCEVERIFY, and Taproot timelocks. Technical reference with use cases.
Bitcoin Timelock Mechanisms Overview
Bitcoin's timelock mechanisms restrict when a transaction can be mined or when a UTXO can be spent. They are the foundation of payment channels, the Lightning Network, atomic swaps, and proposed covenant constructions like OP_VAULT. Bitcoin has four distinct timelock primitives, each operating at a different layer of the protocol.
The following table summarizes how these four mechanisms compare across the dimensions that matter most to developers building on Bitcoin Script.
| Mechanism | BIP | Level | Lock Type | Activated |
|---|---|---|---|---|
| nLockTime | Original protocol | Transaction | Absolute | Genesis (Jan 2009) |
| OP_CHECKLOCKTIMEVERIFY | BIP 65 | Script (UTXO) | Absolute | Block 388,381 (Dec 2015) |
| OP_CHECKSEQUENCEVERIFY | BIP 112 + BIP 68 | Script (UTXO) | Relative | Block 419,328 (Jul 2016) |
| Taproot script path | BIP 341 / BIP 342 | Script (UTXO) | Absolute or Relative | Block 709,632 (Nov 2021) |
For a deeper walkthrough of CLTV and CSV in practice, see our research article on Bitcoin timelocks. To decode timelock values from raw transactions, use the timelock decoder tool.
nLockTime: Transaction-Level Absolute Timelock
nLockTime is a 4-byte unsigned integer present in every Bitcoin transaction since the original Satoshi implementation. It was not introduced by a BIP: it is part of Bitcoin's genesis code from January 2009, with consensus enforcement starting at block 31,001 in December 2009.
The encoding uses a threshold at 500,000,000. Values below that threshold are interpreted as block heights: the transaction cannot be included until the chain reaches that height. Values at or above 500,000,000 are interpreted as Unix timestamps: the transaction is invalid until that time has passed. If nLockTime is 0, there is no restriction.
There is a critical interaction with the nSequence field: nLockTime is entirely ignored if every input has nSequence set to 0xFFFFFFFF. At least one input must have a lower nSequence value for the lock to be enforced. Modern Bitcoin Core wallets (since version 0.11.0) automatically set nLockTime to a recent block height as an anti-fee-sniping measure.
Limitation: nLockTime operates at the transaction level, not the UTXO level. The sender retains control of the input UTXOs and can create an alternative transaction spending the same outputs before the lock expires. This "held hostage" problem is why script-level timelocks (CLTV) were introduced.
OP_CHECKLOCKTIMEVERIFY: Script-Level Absolute Timelock
OP_CHECKLOCKTIMEVERIFY (CLTV), defined in BIP 65 by Peter Todd, activated at block 388,381 on December 14, 2015 via the IsSuperMajority deployment mechanism (requiring nVersion >= 4). It repurposes the previously unused OP_NOP2 opcode.
CLTV solves nLockTime's double-spend problem by embedding the timelock directly into the output script. The UTXO itself becomes unspendable until the specified time, regardless of who holds the signing keys. A typical script pattern is: <expiry> OP_CHECKLOCKTIMEVERIFY OP_DROP <pubkey> OP_CHECKSIG.
The opcode reads the top stack value and compares it to the spending transaction's nLockTime. Script execution fails if the stack value exceeds nLockTime, if the lock type (block height vs. timestamp) does not match, if the spending input's nSequence is 0xFFFFFFFF, or if the stack is empty. Importantly, CLTV does not pop its argument from the stack (for soft-fork compatibility), so scripts must include OP_DROP afterward.
CLTV uses the same encoding threshold as nLockTime: values below 500,000,000 specify a block height, values at or above specify a Unix timestamp. Since BIP 113 (activated alongside CSV at block 419,328), time-based comparisons use median time past (the median of the 11 preceding block timestamps) rather than the current block's timestamp.
OP_CHECKSEQUENCEVERIFY: Script-Level Relative Timelock
OP_CHECKSEQUENCEVERIFY (CSV) was introduced by three co-deployed BIPs that activated together at block 419,328 on July 4, 2016 via BIP 9 versionbits signaling: BIP 68 (redefines nSequence for relative lock-time), BIP 112 (the CSV opcode itself), and BIP 113 (median time past).
Unlike CLTV, which locks until a fixed point in time, CSV locks for a duration measured from the block in which the UTXO was confirmed. This makes it a relative timelock: it answers "how long after confirmation?" rather than "after what date?"
BIP 68 repurposes the 32-bit nSequence field with a specific bit layout. Bit 31 is the disable flag: if set, no relative lock-time is enforced. Bit 22 is the type flag: if unset, the value is measured in blocks; if set, the value is measured in 512-second intervals. Bits 0 through 15 carry the actual lock-time value, extracted with mask 0x0000FFFF. This encoding yields a maximum of 65,535 blocks (roughly 455 days) or 65,535 intervals of 512 seconds (roughly 388 days).
| Bits | Purpose | Details |
|---|---|---|
| 31 (MSB) | Disable flag | If set, no relative lock-time enforcement |
| 23-30 | Reserved | Unused, must be zero for consensus |
| 22 | Type flag | 0 = blocks, 1 = 512-second intervals |
| 16-21 | Reserved | Unused |
| 0-15 | Value | Relative lock-time (max 65,535) |
CSV requires the spending transaction to have version >= 2. Like CLTV, CSV does not pop its stack argument. The opcode was critical for enabling bidirectional payment channels and the Lightning Network, where revocation delays on commitment transactions rely on relative timelocks.
Taproot Script Path Timelocks
Taproot (BIP 341/342), activated at block 709,632 on November 14, 2021, does not introduce new timelock opcodes. Instead, it provides a dramatically better framework for deploying them. CLTV and CSV operate identically within tapscript (leaf version 0xC0) as they do in legacy and SegWit scripts.
The key advancement is Merklized Abstract Syntax Trees (MAST). A P2TR output commits to a Merkle tree of script leaves: each leaf can contain different spending conditions, including various timelock branches. When spending via a script path, only the executed leaf and its Merkle proof are revealed. All other branches remain hidden, and observers cannot determine how many alternative conditions existed.
If the cooperative key path is used (a single Schnorr signature), no scripts are revealed at all. The on-chain footprint is indistinguishable from any other single-signature Taproot spend. This is significant for protocols like the Lightning Network: cooperative channel closes use the key path with no timelock visible on-chain, while only force closes reveal the timelock branch.
Absolute vs. Relative Timelocks
The distinction between absolute and relative timelocks determines how they compose in multi-step protocols. Absolute timelocks pin conditions to a fixed point: a block height or a calendar time. Relative timelocks pin conditions to a duration after confirmation. Each type exists at both the transaction level and the script level.
| Dimension | Absolute | Relative |
|---|---|---|
| Transaction-level | nLockTime | nSequence (BIP 68) |
| Script-level | OP_CHECKLOCKTIMEVERIFY (BIP 65) | OP_CHECKSEQUENCEVERIFY (BIP 112) |
| Block encoding | Value < 500,000,000 | Bit 22 unset, bits 0-15 = block count |
| Time encoding | Value >= 500,000,000 (Unix timestamp) | Bit 22 set, bits 0-15 = 512-second intervals |
| Maximum duration | Effectively unlimited | ~455 days (blocks) or ~388 days (time) |
| Example | "Cannot spend before block 900,000" | "Cannot spend until 144 blocks after confirmation" |
A constraint developers must remember: you cannot mix block-height and timestamp encoding within the same lock type. A CLTV script using block height requires the spending transaction's nLockTime to also use block height. The same rule applies to CSV and nSequence.
Use Cases by Timelock Type
Each timelock primitive serves different protocol needs. The Lightning Network alone uses three of them in combination.
nLockTime:
- Anti-fee-sniping in standard wallet transactions (automatic since Bitcoin Core 0.11.0)
- Simple inheritance planning via pre-signed, future-dated transactions
- First-generation unidirectional payment channels (now superseded)
CLTV (absolute, script-level):
- HTLC timeout paths in Lightning Network routing, with each hop decrementing the CLTV delta
- Atomic swap refund conditions across chains
- Escrow contracts with automatic expiry
- Time-locked savings and vesting schedules
CSV (relative, script-level):
- Revocation delays on Lightning commitment transactions (the to_self_delay window for justice transactions)
- Two-stage HTLC resolution (decoupling revocation delay from HTLC timeout)
- Vault constructions with mandatory waiting periods before withdrawal
- Protocols requiring a cooling-off period after UTXO creation
Taproot timelocks:
- Privacy-preserving Lightning channels where cooperative closes hide all scripts
- Complex contracts with multiple timelock fallback branches (only the used branch is revealed)
- Advanced spending policies via Miniscript compiled to tapscript leaves
- Future covenant designs (OP_VAULT, BIP 345) that build on tapscript
For more on how these primitives compose in real protocols, see our research on Bitcoin Script programmability and Taproot and Schnorr signatures.
The nSequence Field: From Replacement to Relative Timelocks
The nSequence field's history illustrates how Bitcoin's protocol evolves. Satoshi originally designed it for transaction replacement: parties could update an unconfirmed transaction by incrementing nSequence, and miners were expected to prefer higher values. This never worked reliably because miners are incentivized to mine the most profitable transaction, not the latest version. Transaction replacement was effectively disabled, and nSequence became vestigial until BIP 68 repurposed it in 2016.
Today, nSequence serves double duty. Its primary consensus role is relative lock-time enforcement per BIP 68. It also signals opt-in Replace-By-Fee (BIP 125): any nSequence value less than 0xFFFFFFFE marks the transaction as replaceable. The value 0xFFFFFFFF disables both relative lock-time and RBF signaling. The value 0xFFFFFFFE disables relative lock-time but enables nLockTime enforcement and signals non-RBF.
Frequently Asked Questions
What is the difference between nLockTime and OP_CHECKLOCKTIMEVERIFY?
nLockTime is a transaction-level field that prevents a specific transaction from being mined before a certain block or time. CLTV (BIP 65) is a script-level opcode that prevents a UTXO from being spent by any transaction until the timelock expires. The key distinction: nLockTime can be circumvented because the sender can create a different transaction spending the same inputs. CLTV cannot be circumvented because the lock is embedded in the output script itself.
What is the difference between absolute and relative timelocks in Bitcoin?
Absolute timelocks (nLockTime, CLTV) specify a fixed point: a block height or Unix timestamp. They answer "not before X." Relative timelocks (nSequence/BIP 68, CSV/BIP 112) specify a duration after the UTXO is confirmed on-chain. They answer "not until Y blocks/seconds after confirmation." Lightning Network channels use both: CLTV for HTLC expiry and CSV for revocation delay windows.
How does the Lightning Network use Bitcoin timelocks?
The Lightning Network depends on all three script-level timelock mechanisms. HTLC timeout paths use CLTV to give each routing hop a window to claim or refund payments. Commitment transactions use CSV to enforce a revocation delay (typically 144 to 2,016 blocks) that gives the counterparty time to broadcast a penalty transaction if a revoked state is published. Taproot channel implementations hide these timelock branches behind the key path for cooperative closes, improving on-chain privacy.
Can you mix block height and timestamp timelocks in the same script?
No. Bitcoin enforces that the lock-time type must be consistent. If a CLTV script uses a block height value (below 500,000,000), the spending transaction's nLockTime must also use a block height. The same applies to CSV and nSequence: both must use either blocks (type flag unset) or 512-second intervals (type flag set). Mixing types causes script execution to fail.
What is the maximum duration for a relative timelock?
The value field in BIP 68 nSequence is 16 bits, yielding a maximum of 65,535. For block-based relative timelocks, this is 65,535 blocks: approximately 455 days at 10-minute block intervals. For time-based relative timelocks, this is 65,535 intervals of 512 seconds: approximately 388 days. Absolute timelocks (CLTV, nLockTime) have no practical upper limit and can specify dates centuries in the future.
How do Taproot timelocks improve privacy?
Taproot allows complex contracts with many spending branches (including timelocks) to be committed in a Merkle tree. When spent via a script path, only the executed branch and its Merkle proof are revealed. All other branches stay hidden. If the cooperative key path is used instead, no scripts appear on-chain at all: the spend looks identical to any single-signature P2TR payment. This is a significant upgrade for Lightning channels, where most closes are cooperative.
What is BIP 68 and how does it relate to CSV?
BIP 68 redefines the nSequence field at the transaction level to enforce relative lock-times. BIP 112 (CSV) provides the script-level opcode that verifies the spending input's nSequence meets a minimum relative lock-time. They work together: BIP 68 is the consensus rule that makes miners reject transactions whose inputs haven't aged enough, while CSV is the mechanism script authors use to require it. Both activated at block 419,328 on July 4, 2016.
This tool is for informational purposes only and does not constitute financial advice. Technical details are based on Bitcoin Improvement Proposals and publicly available protocol documentation. Always consult the relevant BIPs and Bitcoin Core source code for authoritative implementation details.
Build with Spark
Integrate bitcoin, Lightning, and stablecoins into your app with a few lines of code.
Read the docs →
