> ## Documentation Index
> Fetch the complete documentation index at: https://www.helius.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Solana Priority Fee Estimation: Account Keys Method

> Estimate Solana priority fees using account keys with the Helius Priority Fee API. Quick fee estimates for pre-transaction analysis and batch operations.

> [!NOTE]
>
> **Advanced Method**: Get priority fee estimates using account keys for specialized use cases like pre-transaction analysis, batch operations, and account pattern research.

## Overview

The account keys method provides a simpler alternative to transaction serialization when you need quick fee estimates or want to estimate fees before constructing the complete transaction.

> [card] Advanced Use Cases
>
> * Pre-transaction analysis
> * Batch account operations
> * Market research and patterns
> * Specialized architectures

> [card] Trade-offs
>
> * Less accurate than serialized transactions
> * No instruction-specific analysis
> * Best for account-level patterns

> [!WARNING]
>
> **Recommendation**: For most applications, use the [serialized transaction method](https://www.helius.dev/docs/priority-fee/estimating-fees-using-serialized-transaction.md) instead. This account keys method is for specialized use cases where you need account-level analysis or pre-transaction planning.

## When to Use Account Keys

> [tab] Ideal Use Cases
>
> > [card] Pre-transaction Planning
> >
> > Get fee estimates before constructing complete transactions
>
> > [card] Simplified Integration
> >
> > When your architecture makes transaction serialization difficult
>
> > [card] Quick Market Analysis
> >
> > Analyze fee patterns for specific accounts without building transactions
>
> > [card] Multi-account Analysis
> >
> > Understand fee patterns across multiple accounts independently

> [tab] Specialized Scenarios
>
> **Research & Analysis**: When studying fee patterns across different accounts and programs
>
> **Batch Operations**: When analyzing fee patterns across many accounts simultaneously
>
> **Pre-planning**: For cost estimation before building complex transaction workflows
>
> **Custom Architectures**: When system constraints prevent transaction serialization

## Quick Start

**1. Identify Accounts**

Determine which accounts will be involved in your transaction

**2. Call the API**

Make a request with the account keys and desired priority level

**3. Apply the Fee**

Use the estimate to set priority fee in your transaction

### Basic Example

```javascript JavaScript theme={"system"}
import { ComputeBudgetProgram } from "@solana/web3.js";

// 1. Identify accounts involved in your transaction
const accountKeys = [
  "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", // Token program
  "YOUR_WALLET_ADDRESS",                          // Your wallet
  "RECIPIENT_ADDRESS"                             // Recipient
];

// 2. Get priority fee estimate
const priorityFee = await getPriorityFeeEstimate(connection, accountKeys, "Medium");

// 3. Add to your transaction
const priorityFeeIx = ComputeBudgetProgram.setComputeUnitPrice({
  microLamports: priorityFee
});
transaction.add(priorityFeeIx);
```

```python Python theme={"system"}
import requests

# Get priority fee estimate
def get_priority_fee_estimate(account_keys, priority_level="Medium"):
    response = requests.post(
        "https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY",
        json={
            "jsonrpc": "2.0",
            "id": "1",
            "method": "getPriorityFeeEstimate",
            "params": [{
                "accountKeys": account_keys,
                "options": {
                    "priorityLevel": priority_level,
                    "recommended": True
                }
            }]
        }
    )
    return response.json()["result"]["priorityFeeEstimate"]

# Usage
accounts = ["ACCOUNT_1", "ACCOUNT_2", "ACCOUNT_3"]
fee = get_priority_fee_estimate(accounts, "High")
print(f"Priority fee: {fee} micro-lamports")
```

## Implementation Guide

### Core Function

Here's a reusable function for getting priority fee estimates:

```javascript theme={"system"}
async function getPriorityFeeEstimate(connection, accountKeys, priorityLevel = "Medium") {
  const response = await fetch(connection.rpcEndpoint, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      jsonrpc: "2.0",
      id: "1",
      method: "getPriorityFeeEstimate",
      params: [{
        accountKeys: accountKeys,
        options: { 
          priorityLevel: priorityLevel,
          recommended: true 
        }
      }]
    })
  });
  
  const result = await response.json();
  
  if (result.error) {
    throw new Error(`Fee estimation failed: ${JSON.stringify(result.error)}`);
  }
  
  return result.result.priorityFeeEstimate;
}
```

### Complete Example with Multiple Priority Levels

> [accordion] Expand to see full implementation
>
> ```javascript theme={"system"}
> const { 
>   Connection, 
>   PublicKey, 
>   Transaction, 
>   ComputeBudgetProgram 
> } = require("@solana/web3.js");
>
> // Initialize connection
> const connection = new Connection("https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY");
>
> async function analyzeAccountPriorityFees() {
>   // Define accounts involved in your transaction
>   const accountKeys = [
>     "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", // Token program
>     "YOUR_WALLET_ADDRESS",                          // Your wallet
>     "TOKEN_ACCOUNT_ADDRESS",                        // Token account
>     "RECIPIENT_ADDRESS"                             // Recipient
>   ];
>
>   try {
>     // Get estimates for different priority levels
>     const [lowFee, mediumFee, highFee, veryHighFee] = await Promise.all([
>       getPriorityFeeEstimate(connection, accountKeys, "Low"),
>       getPriorityFeeEstimate(connection, accountKeys, "Medium"), 
>       getPriorityFeeEstimate(connection, accountKeys, "High"),
>       getPriorityFeeEstimate(connection, accountKeys, "VeryHigh")
>     ]);
>
>     console.log("Priority Fee Estimates:");
>     console.log(`Low:      ${lowFee} micro-lamports`);
>     console.log(`Medium:   ${mediumFee} micro-lamports`);
>     console.log(`High:     ${highFee} micro-lamports`);
>     console.log(`VeryHigh: ${veryHighFee} micro-lamports`);
>
>     // Get all levels at once for comparison
>     const allLevels = await getAllPriorityLevels(connection, accountKeys);
>     console.log("\nAll priority levels:", allLevels);
>
>     return {
>       low: lowFee,
>       medium: mediumFee,
>       high: highFee,
>       veryHigh: veryHighFee,
>       allLevels
>     };
>   } catch (error) {
>     console.error("Error getting priority fees:", error);
>     throw error;
>   }
> }
>
> // Helper function to get all priority levels
> async function getAllPriorityLevels(connection, accountKeys) {
>   const response = await fetch(connection.rpcEndpoint, {
>     method: "POST",
>     headers: { "Content-Type": "application/json" },
>     body: JSON.stringify({
>       jsonrpc: "2.0",
>       id: "1",
>       method: "getPriorityFeeEstimate",
>       params: [{
>         accountKeys: accountKeys,
>         options: { 
>           includeAllPriorityFeeLevels: true
>         }
>       }]
>     })
>   });
>
>   const result = await response.json();
>
>   if (result.error) {
>     throw new Error(`Fee estimation failed: ${JSON.stringify(result.error)}`);
>   }
>
>   return result.result.priorityFeeLevels;
> }
>
> // Run the analysis
> analyzeAccountPriorityFees();
> ```

## Account Types & Strategies

> [tab] Program Accounts
>
> High-volume program accounts typically show higher priority fees due to competition.
>
> ```javascript theme={"system"}
> // Popular program accounts
> const programAccounts = [
>   "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", // Token program
>   "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL", // Associated token program
>   "M2mx93ekt1fmXSVkTrUL9xVFHkmME8HTUi5Cyc5aF7K"  // Metaplex program
> ];
>
> const programFees = await getPriorityFeeEstimate(connection, programAccounts, "Medium");
> console.log(`Program account fees: ${programFees} micro-lamports`);
> ```
>
> > [!NOTE]
> >
> > **Expected behavior**: Higher fees due to high transaction volume and competition.

> [tab] User Wallets
>
> Active user wallets may have different fee patterns based on their activity.
>
> ```javascript theme={"system"}
> // Active user wallets
> const userWallets = [
>   "USER_WALLET_1", // Active trader
>   "USER_WALLET_2"  // Regular user
> ];
>
> const walletFees = await getPriorityFeeEstimate(connection, userWallets, "Medium");
> console.log(`User wallet fees: ${walletFees} micro-lamports`);
> ```
>
> > [!TIP]
> >
> > **Pro tip**: Include both sender and recipient wallets for more accurate estimates.

> [tab] Token Accounts
>
> Specific token accounts can show varying patterns based on token popularity.
>
> ```javascript theme={"system"}
> // Popular token accounts
> const tokenAccounts = [
>   "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", // USDC mint
>   "So11111111111111111111111111111111111111112",  // SOL mint
>   "YOUR_TOKEN_ACCOUNT"                            // Your specific token account
> ];
>
> const tokenFees = await getPriorityFeeEstimate(connection, tokenAccounts, "Medium");
> ```

## Advanced Configuration Options

> [accordion] Empty Slot Evaluation
>
> The `evaluateEmptySlotAsZero` option is particularly useful for account-based estimates:
>
> ```javascript theme={"system"}
> async function compareEmptySlotHandling(accountKeys) {
>   const withEmptyAsZero = await fetch(connection.rpcEndpoint, {
>     method: "POST",
>     headers: { "Content-Type": "application/json" },
>     body: JSON.stringify({
>       jsonrpc: "2.0",
>       id: "1",
>       method: "getPriorityFeeEstimate",
>       params: [{
>         accountKeys: accountKeys,
>         options: { 
>           priorityLevel: "Medium",
>           evaluateEmptySlotAsZero: true // Default: true
>         }
>       }]
>     })
>   });
>
>   const withoutEmptyAsZero = await fetch(connection.rpcEndpoint, {
>     method: "POST", 
>     headers: { "Content-Type": "application/json" },
>     body: JSON.stringify({
>       jsonrpc: "2.0",
>       id: "1",
>       method: "getPriorityFeeEstimate", 
>       params: [{
>         accountKeys: accountKeys,
>         options: {
>           priorityLevel: "Medium",
>           evaluateEmptySlotAsZero: false
>         }
>       }]
>     })
>   });
>
>   const result1 = await withEmptyAsZero.json();
>   const result2 = await withoutEmptyAsZero.json();
>
>   console.log(`With empty as zero: ${result1.result.priorityFeeEstimate}`);
>   console.log(`Without empty as zero: ${result2.result.priorityFeeEstimate}`);
> }
> ```
>
> > [!NOTE]
> >
> > When `true` (default), slots with no transactions are treated as zero fees rather than excluded. This provides more balanced estimates for accounts with sparse activity.

> [accordion] Include Details
>
> Request detailed information about each account's fee patterns:
>
> ```javascript theme={"system"}
> async function getDetailedFeeEstimate(connection, accountKeys) {
>   const response = await fetch(connection.rpcEndpoint, {
>     method: "POST",
>     headers: { "Content-Type": "application/json" },
>     body: JSON.stringify({
>       jsonrpc: "2.0",
>       id: "1",
>       method: "getPriorityFeeEstimate",
>       params: [{
>         accountKeys: accountKeys,
>         options: { 
>           includeDetails: true,
>           priorityLevel: "Medium"
>         }
>       }]
>     })
>   });
>
>   const result = await response.json();
>   console.log("Detailed fee analysis:", result.result);
>   return result.result;
> }
> ```
>
> This returns additional information about how fees were calculated for each account.

> [accordion] Custom Lookback Period
>
> Adjust the number of slots analyzed for fee estimation:
>
> ```javascript theme={"system"}
> async function getCustomLookbackEstimate(accountKeys, lookbackSlots = 50) {
>   const response = await fetch(connection.rpcEndpoint, {
>     method: "POST",
>     headers: { "Content-Type": "application/json" },
>     body: JSON.stringify({
>       jsonrpc: "2.0",
>       id: "1",
>       method: "getPriorityFeeEstimate",
>       params: [{
>         accountKeys: accountKeys,
>         options: { 
>           priorityLevel: "Medium",
>           lookbackSlots: lookbackSlots  // 1-150, default is 150
>         }
>       }]
>     })
>   });
>
>   const result = await response.json();
>   return result.result.priorityFeeEstimate;
> }
>
> // Compare different lookback periods
> const shortTerm = await getCustomLookbackEstimate(accountKeys, 50);   // Recent trends
> const longTerm = await getCustomLookbackEstimate(accountKeys, 150);   // Historical average
>
> console.log(`Short-term estimate: ${shortTerm} micro-lamports`);
> console.log(`Long-term estimate: ${longTerm} micro-lamports`);
> ```
>
> > [!TIP]
> >
> > **Smaller lookback**: More recent, potentially volatile data
> >
> > **Larger lookback**: More stable, historical context

## Best Practices for Account Selection

> [card] Include Writable Accounts
>
> **Priority**: Focus on accounts that will be modified
>
> ```javascript theme={"system"}
> const writableAccounts = [
>   "YOUR_WALLET",        // Paying fees
>   "TOKEN_ACCOUNT",      // Being modified  
>   "RECIPIENT_ACCOUNT"   // Receiving tokens
> ];
> ```

> [card] Add Key Programs
>
> **Context**: Include relevant program accounts
>
> ```javascript theme={"system"}
> const programAccounts = [
>   "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA", // Token program
>   "CUSTOM_PROGRAM_ID"                           // Your program
> ];
> ```

## Error Handling & Fallbacks

```javascript Robust Implementation theme={"system"}
class AccountBasedFeeEstimator {
  constructor(connection) {
    this.connection = connection;
    this.fallbackFee = 10000; // 10k micro-lamports fallback
  }

  async getEstimate(accountKeys, priorityLevel = "Medium") {
    try {
      // Primary attempt
      const estimate = await this.getPrimaryEstimate(accountKeys, priorityLevel);
      return estimate;
    } catch (error) {
      console.warn("Primary estimate failed:", error.message);
      
      // Fallback to different configuration
      try {
        return await this.getFallbackEstimate(accountKeys, priorityLevel);
      } catch (fallbackError) {
        console.warn("Fallback estimate failed:", fallbackError.message);
        return this.fallbackFee;
      }
    }
  }

  async getPrimaryEstimate(accountKeys, priorityLevel) {
    const response = await fetch(this.connection.rpcEndpoint, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        jsonrpc: "2.0",
        id: "1",
        method: "getPriorityFeeEstimate",
        params: [{
          accountKeys: accountKeys,
          options: { 
            priorityLevel: priorityLevel,
            recommended: true 
          }
        }]
      })
    });

    const result = await response.json();
    if (result.error) {
      throw new Error(result.error.message);
    }
    
    return result.result.priorityFeeEstimate;
  }

  async getFallbackEstimate(accountKeys, priorityLevel) {
    // Try with fewer accounts or different settings
    const coreAccounts = accountKeys.slice(0, 3); // Take first 3 accounts
    
    const response = await fetch(this.connection.rpcEndpoint, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        jsonrpc: "2.0",
        id: "1",
        method: "getPriorityFeeEstimate",
        params: [{
          accountKeys: coreAccounts,
          options: { 
            priorityLevel: "Medium", // Use medium as fallback
            evaluateEmptySlotAsZero: true
          }
        }]
      })
    });

    const result = await response.json();
    if (result.error) {
      throw new Error(result.error.message);
    }
    
    return result.result.priorityFeeEstimate;
  }
}

// Usage
const estimator = new AccountBasedFeeEstimator(connection);
const fee = await estimator.getEstimate(accountKeys, "High");
```

```javascript Simple Error Handling theme={"system"}
async function safeGetPriorityFee(accountKeys, priorityLevel = "Medium") {
  try {
    return await getPriorityFeeEstimate(connection, accountKeys, priorityLevel);
  } catch (error) {
    console.warn(`Priority fee estimation failed: ${error.message}`);
    
    // Return reasonable fallback based on priority level
    const fallbacks = {
      "Low": 1000,
      "Medium": 5000,
      "High": 15000,
      "VeryHigh": 50000
    };
    
    return fallbacks[priorityLevel] || 5000;
  }
}
```

## Limitations & Considerations

> [!WARNING]
>
> **Account-based method limitations:**
>
> 1. **Less accurate for read-only accounts** - The algorithm focuses on writable accounts
> 2. **No instruction-specific analysis** - Can't consider specific operations
> 3. **Account activity dependency** - Less accurate for inactive accounts
> 4. **No transaction size consideration** - Doesn't account for transaction complexity

> [!NOTE]
>
> **When to upgrade to serialized transactions:**
>
> * Production applications requiring highest accuracy
> * Complex transactions with multiple instructions
> * When instruction-specific fee patterns matter
> * Performance-critical applications

## Related Resources

> [card] [Serialized Transactions](https://www.helius.dev/docs/priority-fee/estimating-fees-using-serialized-transaction.md)
>
> More accurate method using full transaction serialization

> [card] [API Reference](https://www.helius.dev/docs/api-reference/priority-fee/getpriorityfeeestimate.md)
>
> Complete API documentation and parameters


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.