Sequence
Size
4 bytes
Format
Little-Endian
Description
Transaction version as defined by the sender.
Example
ffffffff
Byte Visualization
The sequence field is a 4-byte unsigned integer that appears in each transaction input.
Originally intended for "high-frequency trades". it now serves different purposes including Replace-By-Fee (RBF) and relative timelocks.
Let's examine our transaction to understand this better:


In our example transaction, we can see the sequence value is 0xffffffff
. This is the default sequence value (4294967295 in decimal) which:
- Disables relative timelocks (BIP 68)
- Indicates RBF (Replace-By-Fee) is not enabled
- Represents the traditional "final" sequence number
1- Sequence Values
Value Range | Decimal Range | Description | Common Use Cases |
---|---|---|---|
0xffffffff | 4294967295 | Default value |
|
< 0xf0000000 | < 4026531840 | RBF signaling |
|
< 0x80000000 | < 2147483648 | Relative timelock |
|
0 | 0 | Minimum value |
|
We will cover Replace-By-Fee (RBF) and relative timelocks in detail in separate topics. Now just understand what a sequence number is and its range.
Note
These ranges are hierarchical - a value that enables relative timelocks (< 0x80000000) also automatically enables RBF (< 0xf0000000).
2- Implementation Example
Here's how you might parse a transaction input's sequence number:
def parse_sequence(raw_tx: bytes, offset: int = 0) -> tuple[int, int]:
"""
Parse a sequence number from raw transaction bytes
Args:
raw_tx: Raw transaction bytes
offset: Starting position in bytes
Returns:
(sequence, new_offset)
"""
# Read 4 bytes for sequence
sequence_bytes = raw_tx[offset:offset + 4]
# Convert to integer (little-endian)
sequence = int.from_bytes(sequence_bytes, 'little')
return sequence, offset + 4
3- Historical Context
Original Design
Satoshi originally designed the sequence number for "high-frequency trades" - a way to update transactions before they were mined. The idea was to create payment channels between parties, where each new payment would increment the sequence number. However, this design was vulnerable to miner manipulation and was later replaced by better payment channel designs like the Lightning Network.
4- Modern Uses
Replace-By-Fee (RBF)
When a transaction's input has a sequence number below 0xf0000000, it signals that the transaction can be replaced by a version with higher fees. This is useful when network fees increase and you want to speed up confirmation of your transaction.
Relative Timelocks
BIP 68 introduced relative timelocks using sequence numbers below 0x80000000. This allows an input to specify a minimum age (in blocks or time) relative to its previous output before it can be spent.
def is_rbf_enabled(sequence: int) -> bool:
"""Check if RBF is enabled for this sequence number"""
return sequence < 0xf0000000
def is_relative_timelock(sequence: int) -> bool:
"""Check if relative timelock is enabled"""
return sequence < 0x80000000
Note
The sequence field must be interpreted differently depending on the transaction version. Relative timelocks (BIP 68) only apply to transactions version 2 or higher.