Back to Blog

Table of Contents

Highlights

CU Optimization With setLoadedAccountsDataSizeLimit

Written By

Rex St. John

November 14, 2024

This article will explore the new Compute Budget instruction "setLoadedAccountsDataSizeLimit" and help developers understand how to use it in production. Proper use of setLoadedAccountsDataSizeLimit has the potential to dramatically reduce the number of CU used in many high performance applications.

Why was setLoadedAccountsDataSizeLimit introduced? 

The primary goal was to enable developers with low CU applications (e.g. wallets, embedded wallet providers etc) to enhance their transaction priority by reducing their requested loaded account data size. This prioritization mechanism aligns with the new Compute Budget rules, which favor transactions that optimize data usage, potentially affecting the CU (Compute Unit) cost.

Before the addition of this instruction, transactions defaulted to loading up to 64MB of account data, resulting in significant memory consumption charged at 8 CU per 32KB. This inefficient default would cost an extra 16K CUs, ultimately lowering transaction priority (calculated as (reward_to_leader)/total_CU) and increasing costs. The LoadedAccountsDataSizeLimit instruction solves this by allowing developers, especially in compute-sensitive applications like DeFi, to explicitly specify smaller data size limits. By requesting only the necessary amount of account data instead of the full 64MB default, transactions can reduce their CU consumption, improve their processing priority, and potentially achieve better cost efficiency under the new Compute Budget rules.

Who should pay attention

This optimization is particularly valuable for wallet providers and embedded wallet solutions (like Phantom, Solflare, Backpack, and Privy) that handle token transfers and other low CU operations. While general users with minimal account data usage may remain unaffected, implementing setLoadedAccountsDataSizeLimit can improve transaction priority without affecting fees. Market makers and MEV bot operators can also benefit from minimizing account data size to enhance transaction priority within each block, making it a useful feature for both simple operations and high-performance applications.

Integrating the use of setLoadedAccountsDataSizeLimit can result in significant CU reductions.

Calculating A Data Instruction In Node.js

The following is a code snippet demonstrating how to implement the new instruction (view it here on GitHub) using Node.js:

import { getSetLoadedAccountsDataSizeLimitInstruction } from "@solana-program/compute-budget";
import {
  appendTransactionMessageInstruction,
  createTransactionMessage, 
  pipe,
  setTransactionMessageFeePayerSigner,
  setTransactionMessageLifetimeUsingBlockhash,
} from "@solana/web3.js";

const transactionMessage = pipe(
  createTransactionMessage({ version: 0 }),
  m => setTransactionMessageFeePayerSigner(feePayerSigner, m),
  m => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, m),
  m => appendTransactionMessageInstruction(
    getSetLoadedAccountsDataSizeLimitInstruction({
      accountDataSizeLimit: 32 * 1024, // 32KB limit
    }),
    m,
  ),
);

Performance Improvements

By setting setLoadedAccountsDataSizeLimit, developers can request to lower the default limit of the account data size in their transactions. For instance, a default data limit of 64MB is standard, but reducing this limit (e.g., to 32KB) can reduce CU usage based on the formula "16K - actual-loaded-accounts-size". The Compute Budget limit improves Solana's block processing.

Example Performance With A Hypothetical Token Transfer

Below you will find a hypothetical scenario demonstrating the potential real-world performance improvement using setLoadedAccountsDataSizeLimit properly with an example token transfer:

  • 1 signature

  • 3 write locks(signer, from address, to address)

  • 5 accounts (signer, from address, to address, token program, compute-budget program)

  • Requested compute-budget-limit to 8000 CUs

  • Paying priority fee: 1.25 lamports per CU

Let’s further assume: 

  • The Token program instruction consumed 6000 CU

  • With 2 compute-budget instructions consume 300 CU in total, the Actual execution-cost = 6000 + 300 = 6,300 CUs

  • All accounts take up less than 10M bytes

Here is what might transpire:

| Metric                          | Without Instruction          | With 10M Limit             |
|---------------------------------|------------------------------|----------------------------|
| Loaded Account Data Size Limit  | 64M                          | 10M                        |
| Data Size Cost Calculation      | 64M * (8/32K)                | 10M * (8/32K)              |
| Data Size Cost (CUs)            | 16,000                       | 2,500                      |
| Reward to Leader Calculation    | (1 * 5000 + 1.25 * 8000)/2   | (1 * 5000 + 1.25 * 8000)/2 |
| Reward to Leader (lamports)     | 7,500                        | 7,500                      |
| Transaction Cost Formula        | 1*720 + 3*300 + 8000 + 16000 | 1*720 + 3*300 + 8000 + 2500|
| Transaction Cost (CUs)          | 25,471                       | 11,971                     |
| Priority Score                  | 0.30                         | 0.63

Priority is more than doubled if transaction explicitly requested enough bytes for loading accounts.

Closing Summary

The new Compute Budget instruction provides a means for developers to control transaction prioritization by setting a limit on account data size. While optional, it is beneficial for low-CU applications requiring high-priority processing in congested environments.

Communication and examples should target developers in high-data applications to showcase best practices in leveraging the Compute Budget, including potential cost differences and priority benefits within Solana 2.0’s enhanced processing framework.