Overview
The Queue API provides information about network-wide queue statistics and estimated wait times. Use this to understand current chain demand, estimate activation times for new validators, and plan validator operations.
API Endpoint: This guide uses /api/v2/ethereum/queues for network-wide queue statistics. Per-validator queue tracking is coming soon.
Why Track Queues?
Estimate Activation Times Understand how long new deposits will take to activate based on current queue length.
Customer Communication Provide accurate ETAs to staking customers for deposits and withdrawals.
Chain Demand Insights Monitor queue lengths to understand overall network staking demand.
Exit Planning Plan validator exits based on current exit queue processing rate.
Network Queue Statistics
Get overall network queue lengths and processing rates:
curl --request POST \
--url https://beaconcha.in/api/v2/ethereum/queues \
--header 'Authorization: Bearer <YOUR_API_KEY>' \
--header 'Content-Type: application/json' \
--data '{"chain": "mainnet"}'
Response
{
"data" : {
"deposit_queue" : {
"deposit_count" : 1250 ,
"balance" : "40000000000000000000000" ,
"estimated_processed_at" : 1736500000 ,
"churn" : "2048000000000000000000"
},
"exit_queue" : {
"validator_count" : 450 ,
"estimated_processed_at" : 1736300000 ,
"churn" : "256000000000000000000"
},
"withdrawal_sweep" : {
"estimated_sweep_delay" : {
"epoch" : 150 ,
"ts" : 57600
}
}
}
}
Response Fields
Deposit Queue
Field Description deposit_queue.deposit_countTotal deposits waiting (includes top-ups; not deduplicated by validator) deposit_queue.balanceTotal ETH value in the deposit queue (in wei) deposit_queue.estimated_processed_atEstimated Unix timestamp when the entire deposit queue will be processed deposit_queue.churnETH processed per epoch (current churn limit, in wei)
Exit Queue
Field Description exit_queue.validator_countNumber of validators waiting to exit exit_queue.estimated_processed_atEstimated Unix timestamp when the entire exit queue will be processed exit_queue.churnETH processed per epoch (current churn limit, in wei)
Withdrawal Sweep
Field Description withdrawal_sweep.estimated_sweep_delay.epochCurrent sweep delay in epochs withdrawal_sweep.estimated_sweep_delay.tsCurrent sweep delay in seconds
Sweep Delay: After becoming eligible for withdrawal, validators may wait up to ~10 days for the automatic sweep to process their balance. The sweep cycles through all validators sequentially.
Calculate Wait Times
Use the queue data to estimate activation and exit times:
import requests
from datetime import datetime, timezone
API_KEY = "<YOUR_API_KEY>"
def get_network_queues ():
"""Fetch network-wide queue statistics."""
response = requests.post(
"https://beaconcha.in/api/v2/ethereum/queues" ,
headers = {
"Authorization" : f "Bearer { API_KEY } " ,
"Content-Type" : "application/json"
},
json = { "chain" : "mainnet" }
)
return response.json()
def format_wait_time ( seconds : int ) -> str :
"""Convert seconds to human-readable duration."""
if seconds < 3600 :
return f " { seconds // 60 } minutes"
elif seconds < 86400 :
return f " { seconds // 3600 :.1f} hours"
else :
return f " { seconds // 86400 :.1f} days"
def print_queue_report ():
"""Print a network queue status report."""
data = get_network_queues()
now = int (datetime.now(timezone.utc).timestamp())
queue_data = data.get( "data" , {})
print ( "Network Queue Status Report" )
print ( "=" * 60 )
# Deposit queue
deposit_queue = queue_data.get( "deposit_queue" , {})
if deposit_queue:
deposit_count = deposit_queue.get( "deposit_count" , 0 )
balance_wei = int (deposit_queue.get( "balance" , "0" ))
balance_eth = balance_wei / 1e18
churn_wei = int (deposit_queue.get( "churn" , "0" ))
churn_eth = churn_wei / 1e18
est_processed = deposit_queue.get( "estimated_processed_at" )
print ( f " \n Deposit Queue:" )
print ( f " Pending deposits: { deposit_count :,} " )
print ( f " Total value: { balance_eth :,.2f} ETH" )
print ( f " Churn rate: { churn_eth :,.0f} ETH/epoch" )
if est_processed:
wait_seconds = max ( 0 , est_processed - now)
print ( f " Queue clears in: { format_wait_time(wait_seconds) } " )
# Exit queue
exit_queue = queue_data.get( "exit_queue" , {})
if exit_queue:
validator_count = exit_queue.get( "validator_count" , 0 )
churn_wei = int (exit_queue.get( "churn" , "0" ))
churn_eth = churn_wei / 1e18
est_processed = exit_queue.get( "estimated_processed_at" )
print ( f " \n Exit Queue:" )
print ( f " Pending exits: { validator_count :,} " )
print ( f " Churn rate: { churn_eth :,.0f} ETH/epoch" )
if est_processed:
wait_seconds = max ( 0 , est_processed - now)
print ( f " Queue clears in: { format_wait_time(wait_seconds) } " )
# Withdrawal sweep
sweep = queue_data.get( "withdrawal_sweep" , {})
if sweep:
delay = sweep.get( "estimated_sweep_delay" , {})
delay_seconds = delay.get( "ts" , 0 )
delay_epochs = delay.get( "epoch" , 0 )
print ( f " \n Withdrawal Sweep:" )
print ( f " Current delay: ~ { delay_epochs } epochs ( { format_wait_time(delay_seconds) } )" )
# Example usage
print_queue_report()
Example Output: Network Queue Status Report
============================================================
Deposit Queue:
Pending deposits: 1,250
Total value: 40,000.00 ETH
Churn rate: 2,048 ETH/epoch
Queue clears in: 4.2 days
Exit Queue:
Pending exits: 450
Churn rate: 256 ETH/epoch
Queue clears in: 3.5 hours
Withdrawal Sweep:
Current delay: ~150 epochs (16.0 hours)
const API_KEY = '<YOUR_API_KEY>' ;
async function getNetworkQueues () {
const response = await fetch (
'https://beaconcha.in/api/v2/ethereum/queues' ,
{
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ API_KEY } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({ chain: 'mainnet' })
}
);
return response . json ();
}
function formatWaitTime ( seconds ) {
if ( seconds < 3600 ) return ` ${ Math . floor ( seconds / 60 ) } minutes` ;
if ( seconds < 86400 ) return ` ${ ( seconds / 3600 ). toFixed ( 1 ) } hours` ;
return ` ${ ( seconds / 86400 ). toFixed ( 1 ) } days` ;
}
async function printQueueReport () {
const data = await getNetworkQueues ();
const now = Math . floor ( Date . now () / 1000 );
const queueData = data . data || {};
console . log ( 'Network Queue Status Report' );
console . log ( '=' . repeat ( 60 ));
// Deposit queue
const depositQueue = queueData . deposit_queue || {};
if ( Object . keys ( depositQueue ). length > 0 ) {
const depositCount = depositQueue . deposit_count || 0 ;
const balanceWei = BigInt ( depositQueue . balance || '0' );
const balanceEth = Number ( balanceWei ) / 1e18 ;
const churnWei = BigInt ( depositQueue . churn || '0' );
const churnEth = Number ( churnWei ) / 1e18 ;
const estProcessed = depositQueue . estimated_processed_at ;
console . log ( ' \n Deposit Queue:' );
console . log ( ` Pending deposits: ${ depositCount . toLocaleString () } ` );
console . log ( ` Total value: ${ balanceEth . toLocaleString () } ETH` );
console . log ( ` Churn rate: ${ churnEth . toLocaleString () } ETH/epoch` );
if ( estProcessed ) {
const waitSeconds = Math . max ( 0 , estProcessed - now );
console . log ( ` Queue clears in: ${ formatWaitTime ( waitSeconds ) } ` );
}
}
// Exit queue
const exitQueue = queueData . exit_queue || {};
if ( Object . keys ( exitQueue ). length > 0 ) {
const validatorCount = exitQueue . validator_count || 0 ;
const churnWei = BigInt ( exitQueue . churn || '0' );
const churnEth = Number ( churnWei ) / 1e18 ;
const estProcessed = exitQueue . estimated_processed_at ;
console . log ( ' \n Exit Queue:' );
console . log ( ` Pending exits: ${ validatorCount . toLocaleString () } ` );
console . log ( ` Churn rate: ${ churnEth . toLocaleString () } ETH/epoch` );
if ( estProcessed ) {
const waitSeconds = Math . max ( 0 , estProcessed - now );
console . log ( ` Queue clears in: ${ formatWaitTime ( waitSeconds ) } ` );
}
}
// Withdrawal sweep
const sweep = queueData . withdrawal_sweep || {};
if ( Object . keys ( sweep ). length > 0 ) {
const delay = sweep . estimated_sweep_delay || {};
const delaySeconds = delay . ts || 0 ;
const delayEpochs = delay . epoch || 0 ;
console . log ( ' \n Withdrawal Sweep:' );
console . log ( ` Current delay: ~ ${ delayEpochs } epochs ( ${ formatWaitTime ( delaySeconds ) } )` );
}
}
printQueueReport ();
Estimate Activation Time for New Deposits
Use the deposit queue balance and churn rate to estimate when new deposits will activate:
def estimate_activation_time ( deposit_eth : float = 32 ):
"""
Estimate activation time for new deposits.
Uses the current deposit queue balance (in ETH) and churn rate to estimate
when new deposits would activate if deposited now.
Args:
deposit_eth: Amount of ETH to deposit (32-2048 ETH per validator post-Pectra)
"""
data = get_network_queues()
queue_data = data.get( "data" , {})
deposit_queue = queue_data.get( "deposit_queue" , {})
# Current queue balance (total ETH waiting)
balance_wei = int (deposit_queue.get( "balance" , "0" ))
balance_eth = balance_wei / 1e18
# Churn rate (ETH processed per epoch, in wei)
churn_wei = int (deposit_queue.get( "churn" , "0" ))
churn_eth = churn_wei / 1e18
# Time constants
SECONDS_PER_EPOCH = 384
# New deposits add to the queue
total_eth_ahead = balance_eth + deposit_eth
# Epochs to process all ETH ahead in queue
epochs_to_wait = total_eth_ahead / churn_eth if churn_eth > 0 else 0
# Convert to seconds
seconds_to_wait = epochs_to_wait * SECONDS_PER_EPOCH
print ( f "Deposit Queue Analysis" )
print ( f " Current queue: { balance_eth :,.0f} ETH" )
print ( f " Churn rate: { churn_eth :,.0f} ETH/epoch" )
print ( f "" )
print ( f " If you deposit { deposit_eth :,.0f} ETH now:" )
print ( f " Estimated wait: { format_wait_time( int (seconds_to_wait)) } " )
# Example: Estimate wait time for depositing 320 ETH (10 validators at 32 ETH each)
estimate_activation_time( 320 )
The deposit_count field includes top-ups and is not deduplicated by validator. For accurate activation estimates, use balance (total ETH in queue) divided by the churn rate (ETH processed per epoch). Post-Pectra, validators can have effective balances from 32 ETH to 2048 ETH.
Use Cases
1. Customer Communication
Display current queue status on your staking platform:
def get_customer_facing_queue_status ():
"""Get queue information formatted for customer display."""
data = get_network_queues()
queue_data = data.get( "data" , {})
now = int (datetime.now(timezone.utc).timestamp())
deposit_queue = queue_data.get( "deposit_queue" , {})
exit_queue = queue_data.get( "exit_queue" , {})
# Calculate wait times
deposit_wait = None
if deposit_queue.get( "estimated_processed_at" ):
deposit_wait = max ( 0 , deposit_queue[ "estimated_processed_at" ] - now)
exit_wait = None
if exit_queue.get( "estimated_processed_at" ):
exit_wait = max ( 0 , exit_queue[ "estimated_processed_at" ] - now)
return {
"activation_queue" : {
"pending_count" : deposit_queue.get( "deposit_count" , 0 ),
"estimated_wait" : format_wait_time(deposit_wait) if deposit_wait else "Unknown"
},
"exit_queue" : {
"pending_count" : exit_queue.get( "validator_count" , 0 ),
"estimated_wait" : format_wait_time(exit_wait) if exit_wait else "Unknown"
}
}
# Use in your customer dashboard
status = get_customer_facing_queue_status()
print ( f "New deposits: ~ { status[ 'activation_queue' ][ 'estimated_wait' ] } to activate" )
print ( f "Exits: ~ { status[ 'exit_queue' ][ 'estimated_wait' ] } to process" )
2. Monitoring Queue Trends
Track queue lengths over time to identify patterns:
from datetime import datetime, timezone
def log_queue_snapshot ():
"""Log current queue status for trend analysis."""
data = get_network_queues()
queue_data = data.get( "data" , {})
timestamp = datetime.now(timezone.utc).isoformat()
deposit_queue = queue_data.get( "deposit_queue" , {})
exit_queue = queue_data.get( "exit_queue" , {})
log_entry = {
"timestamp" : timestamp,
"deposit_count" : deposit_queue.get( "deposit_count" , 0 ),
"deposit_balance_eth" : int (deposit_queue.get( "balance" , "0" )) / 1e18 ,
"exit_count" : exit_queue.get( "validator_count" , 0 ),
"exit_churn_eth" : int (exit_queue.get( "churn" , "0" )) / 1e18
}
print ( f "[ { timestamp } ] Deposits: { log_entry[ 'deposit_count' ] :,} , "
f "Exits: { log_entry[ 'exit_count' ] :,} " )
return log_entry
# Run periodically (e.g., every hour via cron)
log_queue_snapshot()
Best Practices
Poll Periodically Queue lengths change as validators enter and exit. Poll every 1-4 hours for accurate estimates.
Account for Variability Queue processing speed varies with network conditions. Provide time ranges, not exact times.
Monitor Churn Rate The churn rate determines how fast queues are processed. Track it to understand network capacity.
Coming Soon
Per-Validator Queue Tracking: A future API update will provide queue status for specific validators, including individual activation and exit ETAs. Stay tuned for updates.
For detailed API specifications, see the Network section in the V2 API Docs sidebar.