How to Compete for Transaction Priority on Arbitrum
A practical guide to Priority Gas Auctions (PGA), priority-fee bidding, and using Fast Feed to react to transaction flow faster on Arbitrum One.
PGA replaces Timeboost as the transaction-ordering policy on Arbitrum One, letting senders compete for earlier ordering by attaching a priority fee to each transaction. Fast Feed complements PGA by streaming transaction and ordering information as the sequencer adds transactions to the active block.
This guide covers how PGA and Fast Feed work, when to use them, and how to get started.
PGA + Fast Feed at a Glance
PGA
Compete for transaction priority by attaching a priority fee per gas to an individual transaction.
Fast Feed
Receive transaction and ordering updates during block construction instead of waiting for the completed block feed.

PGA
Why PGA Matters
Ordering matters when a transaction’s value depends on executing before competing activity. Common examples include arbitrage, liquidations, propAMM updates, and other time-sensitive DeFi operations.
PGA provides a per-transaction mechanism to compete for priority using standard EIP-1559 fee fields. There is no separate auction interface or registration process. Users add a priority fee only when earlier execution justifies the additional cost.
How PGA Works
PGA organizes transactions into short ordering rounds:
- Transactions arrive at the sequencer and enter an unordered waiting list.
- At the start of a PGA round, waiting transactions are placed in a priority queue.
- The sequencer calculates each transaction’s final priority.
- Transactions with higher final priority are selected first.
- Transactions arriving after the round begins wait for the next round.
On Arbitrum One, each nominal 250ms block contains two PGA rounds:
- Block time: 250ms
- PGA rounds per block: 2
- Nominal round length: 125ms

How Final Priority Is Calculated
Within a PGA round, transactions are ordered by final priority:
final_priority = priority_fee_per_gas + accumulated_boostaccumulated_boost is only added if the transaction has been waiting in the queue for longer than one PGA round.
The effective priority fee per gas is:
priority_fee_per_gas = min(
transaction.max_priority_fee_per_gas,
transaction.max_fee_per_gas - block.base_fee_per_gas
)maxPriorityFeePerGas is therefore not always the amount used for ordering. maxFeePerGas must leave enough room above the current base fee to support the intended priority fee.
If two transactions have the same final priority, the sequencer orders the one it received first. Arrival time is measured at the sequencer, not at the sender or RPC provider, and even a few milliseconds can affect tie-breaking or move a transaction into the next PGA round.

How to Use PGA
Users participate through standard EIP-1559 transactions:
- Construct the transaction.
- Set
maxFeePerGas. - Set
maxPriorityFeePerGas. - Submit the transaction normally.
PGA compares the transaction’s final priority with the other transactions competing in the same round.
// The priority fee comes from application logic
priorityFee := computePriorityFee()
// The suggested max fee is 2*baseFee + priorityFee
maxFee := new(big.Int).Add(
new(big.Int).Mul(head.BaseFee, big.NewInt(2)),
priorityFee,
)
tx := types.NewTx(&types.DynamicFeeTx{
ChainID: chainID,
Nonce: nonce,
GasTipCap: priorityFee, // GasTipCap aka maxPriorityFeePerGas
GasFeeCap: maxFee, // GasFeeCap aka maxFeePerGas
To: &to,
Value: value,
Data: data,
})
For a new transaction without an accumulated boost, the effective priority fee is the main factor determining its position. Higher priority can improve ordering, but it also increases the maximum fee the sender may pay.
A practical rule is to pay for priority only when the expected value of earlier execution exceeds the additional fee. Users can adjust this transaction by transaction rather than applying the same bid to all activity.
What Happens Without a Priority Fee
Setting a zero-priority fee (or not adding a priority-fee) is appropriate when the transaction order does not matter. A zero-tip transaction generally follows transactions with higher final priority, but it can still be included when capacity is available.
When a round cannot include every transaction, those left in the priority queue receive a virtual boost:
boost_per_round = p / 2KWhere:
- p is the priority of the last transaction included in the round.
- K is the number of PGA rounds per block.
- On Arbitrum One, K = 2.
Boosts accumulate when a transaction remains queued across multiple rounds, improving its ordering priority without increasing the fee charged to the sender. This allows paying transactions to compete for earlier execution while preventing low- and zero-tip transactions from waiting indefinitely. If a block fills before its final scheduled round, the sequencer can finalize it and begin the next block without waiting for the rest of the nominal block window.
PGA Use Cases
| Use case | Why priority matters |
|---|---|
| Atomic arbitrage | Multiple searchers may compete to capture the same onchain price discrepancy within a single transaction. |
| CEX–DEX arbitrage | The onchain leg must execute before the DEX price changes or another searcher captures the opportunity. |
| Liquidations | Several liquidators may attempt to execute against the same eligible position. |
| propAMM and market updates | Delayed price, quote, or parameter updates can expose the application to stale-state execution and inventory risk. |
PGA can also support other applications where ordering affects execution quality, profitability, or protocol operation.
Fast Feed
Get Transaction Data Faster
PGA determines transaction ordering. Fast Feed publishes individual ordering information and transactions as the sequencer adds them to the active block.
Subscribers receive these updates without waiting for the block to finish and appear on the regular block feed.

Fast Feed messages are published before block finalization. In the rare occurrence of the sequencer failing before completing the block, a transaction previously sent through Fast Feed may not appear in the finalized block. Fast Feed is therefore intended for low-latency observation, not canonical chain synchronization or historical data access.
How to Use Fast Feed
Fast Feed access follows four steps:
- Obtain access: Purchase a feed ticket for the relevant access period through the onchain feed-ticket contract. Note that feed tickets are priced in a manner solely to deter spam.
- Authenticate: Supply the registered API credential during the connection handshake.
- Connect: Open an authenticated WebSocket connection to the Fast Feed relay.
- Consume messages: Process transaction and ordering messages as the sequencer publishes them.
The relay authenticates subscribers and prevents external clients from connecting directly to the sequencer.

func run(ctx context.Context, url string, header http.Header) error {
log.Printf("connecting to %s", url)
conn, err := dial(ctx, url, header)
if err != nil {
return fmt.Errorf("dial: %w", err)
}
defer func() { _ = conn.CloseNow() }()
conn.SetReadLimit(-1)
log.Printf("connected")
for {
_, data, err := conn.Read(ctx)
if err != nil {
if ctx.Err() != nil {
return ctx.Err()
}
var closeErr websocket.CloseError
if errors.As(err, &closeErr) {
return fmt.Errorf(
"server closed connection: status %d %q",
closeErr.Code,
closeErr.Reason,
)
}
return fmt.Errorf("read: %w", err)
}
var msg feedMessage
if err := json.Unmarshal(data, &msg); err != nil {
log.Printf("skipping undecodable message: %v", err)
continue
}
if msg.Version != feedMessageVersion {
log.Printf(
"skipping message with version %d, expected %d",
msg.Version,
feedMessageVersion,
)
continue
}
printMessage(&msg)
}
}
Fast Feed starts at the current head and does not cache historical messages. Subscribers receive only messages published after their connection is established.
Detailed purchase instructions, endpoint information, message schemas, and reference-client code are available in the technical documentation.
A Note for Chain Operators
Fast Feed can also reduce connection races on chains using first-come, first-served ordering.
When latency varies across regular-feed connections, searchers may open many connections to increase the chance of receiving data first. This raises infrastructure costs for chain operators.
A consistently faster paid feed can make redundant regular-feed connections less useful with the following benefits:
PGA + Fast Feed in Practice
PGA and Fast Feed support different parts of the same loop:
For example:
- Fast Feed publishes a transaction added to the active block.
- A searcher identifies an atomic-arbitrage opportunity.
- The searcher constructs a transaction and sets its priority fee.
- The transaction enters the next eligible PGA round.
- PGA ranks it against the other transactions in that round.
- If selected, it is added to the active block and published through Fast Feed.

Start implementing PGA + Fast Feed
Read the PGA and Fast Feed technical documentation for:
- How PGA ordering and priority fees work
- How to enable PGA on an Arbitrum chain
- Fast Feed subscription and API-key authentication
- WebSocket message format
- Transaction and receipt schemas
- Fast Feed operational limits and final-state reconciliation





