Skip to main content
Address lookup tables (LUTs) let Solana transactions reference many accounts by compact table indexes instead of embedding every account address directly in the transaction message. They are most useful when a transaction touches many accounts: swaps, routing, portfolio actions, batch operations, and anything that risks hitting Solana’s transaction size limits. Solana Tracker’s Ridge custom RPC methods make LUT discovery practical. Instead of scanning lookup table accounts yourself, you can ask for the exact table shape you need:
  • LUTs owned by a wallet authority.
  • LUTs that contain one account or token mint.
  • LUTs that contain every account in a set.
  • A best-effort LUT set for reducing transaction size.
Each Lookup Table RPC method costs 1 credit per call.

When to use these methods

Use the LUT methods when you are building, simulating, or optimizing Solana transactions and need to know whether accounts are already available through lookup tables.
GoalMethod
Inspect LUTs controlled by a walletgetLookupTablesByAuthority
Find LUTs that contain an accountgetLookupTablesByAccount
Find LUTs that contain a token mintgetLookupTablesByMint
Find LUTs that cover multiple accountsgetLookupTablesByAccounts
Start with getLookupTablesByAccounts when your goal is transaction optimization. Use the single-account methods when you are exploring where a specific account or mint appears.

RPC endpoint

All examples use JSON-RPC 2.0 over HTTP:
https://rpc-mainnet.solanatracker.io/?api_key=YOUR_API_KEY

Find LUTs by authority

Use getLookupTablesByAuthority to inspect lookup tables owned by a wallet authority. This is helpful for wallets, bots, and infrastructure that maintain their own LUTs.
curl "https://rpc-mainnet.solanatracker.io/?api_key=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "getLookupTablesByAuthority",
    "params": [{
      "authority": "WalletPubkey...",
      "limit": 100,
      "cursor": null,
      "mintsOnly": false,
      "includeDeactivated": false
    }]
  }'
The response is paginated:
{
  "lookupTables": [
    {
      "pubkey": "LUTPubkey...",
      "authority": "WalletPubkey...",
      "deactivationSlot": 18446744073709551615,
      "addressCount": 12,
      "addresses": ["Account1...", "Account2..."],
      "mints": ["Mint1..."],
      "slot": 423867852
    }
  ],
  "nextCursor": "LUTPubkey...",
  "hasMore": false,
  "count": 1
}
deactivationSlot uses 18446744073709551615 to represent an active LUT.

Find LUTs containing one account

Use getLookupTablesByAccount when you already know an account that will appear in a transaction and want to find LUTs that contain it.
curl "https://rpc-mainnet.solanatracker.io/?api_key=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "getLookupTablesByAccount",
    "params": [{
      "account": "SomeAccountPubkey...",
      "owner": null,
      "limit": 100,
      "cursor": null
    }]
  }'
Matched results include transaction-optimization metadata:
FieldMeaning
addressIndexPosition of the matched account in the LUT
matchedAccountsAccounts from your query found in this LUT
matchedAddressIndicesLUT indexes for the matched accounts
estimatedBytesSavedApproximate bytes saved by referencing matched accounts through the LUT

Find LUTs containing a mint

getLookupTablesByMint is the same lookup pattern as getLookupTablesByAccount, but the parameter name is mint.
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "getLookupTablesByMint",
  "params": [{
    "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
    "limit": 100
  }]
}
Use this when a transaction is token-centric and you want to discover LUTs that already contain the mint address.

Find LUTs for a full account set

getLookupTablesByAccounts has two modes: intersection mode and best-set mode.

Intersection mode

Intersection mode returns LUTs that contain every account you provide. Use it when you need one table that covers the full set.
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "getLookupTablesByAccounts",
  "params": [{
    "accounts": ["AccountA...", "AccountB..."],
    "owner": null,
    "limit": 100,
    "cursor": null
  }]
}

Best-set mode

Best-set mode is the fastest way to answer: “Which LUTs should I attach to save the most transaction space?” Set bestSet: true and pass the full account list your transaction needs:
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "getLookupTablesByAccounts",
  "params": [{
    "accounts": ["AccountA...", "AccountB...", "AccountC..."],
    "bestSet": true,
    "maxLookupTables": 8,
    "candidateLimit": 5000,
    "perAccountLimit": 500
  }]
}
The response tells you what the selected LUTs cover:
{
  "lookupTables": [
    {
      "pubkey": "LUT1...",
      "matchedAccounts": ["AccountA...", "AccountB..."],
      "matchedAddressIndices": [3, 17],
      "estimatedBytesSaved": 62
    }
  ],
  "coveredAccounts": ["AccountA...", "AccountB..."],
  "uncoveredAccounts": ["AccountC..."],
  "estimatedBytesSaved": 62,
  "count": 1
}

Best-set tuning

ParameterDefaultUse it when
maxLookupTables8You want to cap how many LUTs your transaction uses
candidateLimit5000You need to limit total candidate tables considered
perAccountLimit500One account appears in too many LUTs and candidate search is too broad
For most applications, keep the defaults and only tune after measuring transaction build time and response size.

Example: choose LUTs before building a transaction

The typical flow is:
  1. Collect the accounts your transaction will reference.
  2. Call getLookupTablesByAccounts with bestSet: true.
  3. Attach returned LUTs to your transaction builder.
  4. Keep uncoveredAccounts as normal account keys.
const accounts = [
  "AccountA...",
  "AccountB...",
  "AccountC..."
];

const { result } = await fetch(
  "https://rpc-mainnet.solanatracker.io/?api_key=YOUR_API_KEY",
  {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      jsonrpc: "2.0",
      id: 1,
      method: "getLookupTablesByAccounts",
      params: [{
        accounts,
        bestSet: true,
        maxLookupTables: 8
      }]
    })
  }
).then(r => r.json());

console.log("Use LUTs:", result.lookupTables.map(lut => lut.pubkey));
console.log("Covered:", result.coveredAccounts);
console.log("Still inline:", result.uncoveredAccounts);
console.log("Estimated bytes saved:", result.estimatedBytesSaved);

Practical tips

  • Use bestSet: true for transaction-size optimization, not for exhaustive discovery.
  • Use owner when you only trust or care about LUTs controlled by a specific authority.
  • Use mintsOnly on authority lookups when you are building token-oriented UX and do not need every stored address.
  • Treat estimatedBytesSaved as a planning signal, then still simulate the final transaction.
  • Keep pagination logic for authority, account, and mint searches. Popular accounts can appear in many LUTs.

getLookupTablesByAccounts

Find LUTs for multiple accounts or get a best-fit LUT set.

Credits and Rate Limits

Review credit costs and plan limits for RPC calls.