> ## 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.

# Optimasi RPC Solana: Praktik Terbaik untuk Performa & Biaya

> Optimalkan performa RPC Solana, kurangi biaya, dan tingkatkan keandalan. Panduan optimasi transaksi, pola pengambilan data, dan praktik terbaik.

Mengoptimalkan penggunaan RPC dapat meningkatkan performa secara signifikan, mengurangi biaya, dan meningkatkan pengalaman pengguna. Panduan ini membahas teknik yang telah terbukti untuk interaksi RPC Solana yang efisien.

## Mulai Cepat

<CardGroup cols={2}>
  <Card title="Transaction Optimization" icon="bolt" href="#optimasi-transaksi">
    Optimalkan unit komputasi, biaya prioritas, dan pengiriman transaksi
  </Card>

  <Card title="Data Retrieval" icon="database" href="#optimasi-pengambilan-data">
    Pola efisien untuk mengambil data akun dan program
  </Card>

  <Card title="Real-time Monitoring" icon="chart-line" href="#pemantauan-real-time">
    Langganan WebSocket dan optimasi streaming data
  </Card>

  <Card title="Best Practices" icon="shield-check" href="#praktik-terbaik">
    Panduan performa dan pengelolaan sumber daya
  </Card>
</CardGroup>

## Optimasi Transaksi

### Pengelolaan Unit Komputasi

**1. Lakukan simulasi untuk menentukan penggunaan aktual:**

```typescript theme={"system"}
const testTransaction = new VersionedTransaction(/* your transaction */);
const simulation = await connection.simulateTransaction(testTransaction, {
  replaceRecentBlockhash: true,
  sigVerify: false
});
const unitsConsumed = simulation.value.unitsConsumed;
```

**2. Tetapkan batas yang sesuai dengan margin:**

```typescript theme={"system"}
const computeUnitLimit = Math.ceil(unitsConsumed * 1.1);
const computeUnitIx = ComputeBudgetProgram.setComputeUnitLimit({ 
  units: computeUnitLimit 
});
instructions.unshift(computeUnitIx); // Add at beginning
```

### Optimasi Biaya Prioritas

**1. Dapatkan estimasi biaya dinamis:**

```typescript theme={"system"}
const response = await fetch(`https://mainnet.helius-rpc.com/?api-key=${API_KEY}`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    method: 'getPriorityFeeEstimate',
    params: [{
      accountKeys: ['11111111111111111111111111111112'], // System Program
      options: { recommended: true }
    }]
  })
});
const { priorityFeeEstimate } = await response.json().result;
```

**2. Terapkan biaya prioritas:**

```typescript theme={"system"}
const priorityFeeIx = ComputeBudgetProgram.setComputeUnitPrice({ 
  microLamports: priorityFeeEstimate 
});
instructions.unshift(priorityFeeIx);
```

### Praktik Terbaik Pengiriman Transaksi

<Tabs>
  <Tab title="Standard Approach">
    ```typescript theme={"system"}
    // Serialize and encode
    const serializedTx = transaction.serialize();
    const signature = await connection.sendRawTransaction(serializedTx, {
      skipPreflight: true, // Saves ~100ms
      maxRetries: 0 // Handle retries manually
    });
    ```
  </Tab>

  <Tab title="With Confirmation">
    ```typescript theme={"system"}
    // Send and confirm with custom logic
    const signature = await connection.sendRawTransaction(serializedTx);

    // Monitor confirmation
    const confirmation = await connection.confirmTransaction({
      signature,
      blockhash: latestBlockhash.blockhash,
      lastValidBlockHeight: latestBlockhash.lastValidBlockHeight
    });
    ```
  </Tab>
</Tabs>

## Optimasi Pengambilan Data

### Metode Paginasi yang Disempurnakan (V2)

**Untuk kueri data berskala besar, gunakan metode V2 baru dengan paginasi berbasis kursor:**

<Card title="⚡ Performance Boost" icon="rocket" color="#E84125">
  `getProgramAccountsV2` dan `getTokenAccountsByOwnerV2` memberikan peningkatan performa yang signifikan untuk aplikasi yang menangani set data besar:

  * **Batas yang dapat dikonfigurasi**: 1–10.000 akun per permintaan
  * **Paginasi berbasis kursor**: Mencegah timeout pada kueri besar
  * **Pembaruan inkremental**: Gunakan `changedSinceSlot` untuk sinkronisasi real-time
  * **Penggunaan memori yang lebih baik**: Streaming data alih-alih memuat semuanya sekaligus
</Card>

**Contoh: Kueri akun program yang efisien**

```typescript theme={"system"}
// ❌ Old approach - could timeout with large datasets
const allAccounts = await connection.getProgramAccounts(programId, {
  encoding: 'base64',
  filters: [{ dataSize: 165 }]
});

// ✅ New approach - paginated with better performance
let allAccounts = [];
let paginationKey = null;

do {
  const response = await fetch(`https://mainnet.helius-rpc.com/?api-key=${API_KEY}`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      jsonrpc: '2.0',
      id: '1',
      method: 'getProgramAccountsV2',
      params: [
        programId,
        {
          encoding: 'base64',
          filters: [{ dataSize: 165 }],
          limit: 5000,
          ...(paginationKey && { paginationKey })
        }
      ]
    })
  });
  
  const data = await response.json();
  allAccounts.push(...data.result.accounts);
  paginationKey = data.result.paginationKey;
} while (paginationKey);
```

**Pembaruan inkremental untuk aplikasi real-time:**

```typescript theme={"system"}
// Get only accounts modified since a specific slot
const incrementalUpdate = await fetch(`https://mainnet.helius-rpc.com/?api-key=${API_KEY}`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: '1',
    method: 'getProgramAccountsV2',
    params: [
      programId,
      {
        encoding: 'jsonParsed',
        limit: 1000,
        changedSinceSlot: lastProcessedSlot // Only get recent changes
      }
    ]
  })
});
```

## Optimasi Pengambilan Data

### Kueri Akun yang Efisien

<Tabs>
  <Tab title="Single Account">
    ```typescript theme={"system"}
    // Use dataSlice to reduce payload size
    const accountInfo = await connection.getAccountInfo(pubkey, {
      encoding: 'base64',
      dataSlice: { offset: 0, length: 100 }, // Only get needed data
      commitment: 'confirmed'
    });
    ```
  </Tab>

  <Tab title="Multiple Accounts">
    ```typescript theme={"system"}
    // Batch multiple account queries
    const accounts = await connection.getMultipleAccountsInfo([
      pubkey1, pubkey2, pubkey3
    ], {
      encoding: 'base64',
      commitment: 'confirmed'
    });
    ```
  </Tab>

  <Tab title="Program Accounts">
    ```typescript theme={"system"}
    // Use filters to reduce data transfer
    const accounts = await connection.getProgramAccounts(programId, {
      filters: [
        { dataSize: 165 }, // Token account size
        { memcmp: { offset: 0, bytes: mintAddress }}
      ],
      encoding: 'jsonParsed'
    });
    ```
  </Tab>
</Tabs>

### Pencarian Saldo Token

<CodeGroup>
  ```typescript ❌ Inefficient theme={"system"}
  // Don't do this - requires N+1 RPC calls
  const tokenAccounts = await connection.getTokenAccountsByOwner(owner, {
    programId: TOKEN_PROGRAM_ID
  });
  const balances = await Promise.all(
    tokenAccounts.value.map(acc => 
      connection.getTokenAccountBalance(acc.pubkey)
    )
  );
  // ~500ms + (100ms * N accounts)
  ```

  ```typescript ✅ Optimized theme={"system"}
  // Single call with parsed data
  const tokenAccounts = await connection.getTokenAccountsByOwner(owner, {
    programId: TOKEN_PROGRAM_ID
  }, { encoding: 'jsonParsed' });

  const balances = tokenAccounts.value.map(acc => ({
    mint: acc.account.data.parsed.info.mint,
    amount: acc.account.data.parsed.info.tokenAmount.uiAmount
  }));
  // ~500ms total - 95% reduction for large wallets
  ```
</CodeGroup>

### Riwayat Transaksi

Untuk mendapatkan riwayat lengkap suatu alamat, gunakan [`getTransactionsForAddress`](/docs/id/rpc/gettransactionsforaddress) — metode eksklusif Helius yang mengembalikan data transaksi lengkap, termasuk aktivitas akun token terkait, dalam satu panggilan:

<CodeGroup>
  ```typescript ❌ Inefficient theme={"system"}
  // Avoid sequential transaction fetching
  const signatures = await connection.getSignaturesForAddress(address, { limit: 100 });
  const transactions = await Promise.all(
    signatures.map(sig => connection.getTransaction(sig.signature))
  );
  // ~1s + (200ms * 100 txs) = ~21s
  // Also note: getSignaturesForAddress doesn't include token account transactions
  ```

  ```typescript ✅ Fast (Helius Exclusive) theme={"system"}
  // Use getTransactionsForAddress for full history including token accounts
  const response = await fetch(`https://mainnet.helius-rpc.com/?api-key=${API_KEY}`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      jsonrpc: '2.0',
      id: 1,
      method: 'getTransactionsForAddress',
      params: [
        address,
        {
          transactionDetails: 'full',
          limit: 100,
          filters: { tokenAccounts: 'balanceChanged' }
        }
      ]
    })
  });
  // ~100ms total - includes complete token history in one call
  ```
</CodeGroup>

### Riwayat Transfer

Jika Anda hanya memerlukan pergerakan token atau SOL — pembayaran, aktivitas portofolio, atau rekonsiliasi saldo — gunakan [`getTransfersByAddress`](/docs/id/rpc/gettransfersbyaddress) (eksklusif Helius, memerlukan [paket Developer](/docs/id/billing/plans) atau yang lebih tinggi). Metode ini mengembalikan objek transfer terurai yang mudah dibaca, dengan pemilik, mint, jumlah, dan desimal yang sudah ditentukan, sehingga Anda tidak perlu mengurai transaksi sama sekali:

```typescript theme={"system"}
// Parsed USDC transfers received by a wallet - no manual parsing needed
const response = await fetch(`https://mainnet.helius-rpc.com/?api-key=${API_KEY}`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: 1,
    method: 'getTransfersByAddress',
    params: [
      address, // Wallet owner address, not a token account
      {
        mint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // USDC
        direction: 'in',
        limit: 100
      }
    ]
  })
});
// Each transfer includes parsed sender, recipient, amount, decimals, and uiAmount
```

Aturan praktisnya: gunakan `getTransactionsForAddress` saat Anda memerlukan payload transaksi lengkap atau aktivitas selain transfer, dan gunakan `getTransfersByAddress` saat Anda memerlukan catatan transfer yang rapi untuk buku besar dan pelacakan pembayaran.

## Pemantauan Real-Time

### Langganan Akun

<CodeGroup>
  ```typescript ❌ Polling theme={"system"}
  // Avoid polling - wastes resources
  setInterval(async () => {
    const accountInfo = await connection.getAccountInfo(pubkey);
    // Process updates...
  }, 1000);
  ```

  ```typescript ✅ WebSocket theme={"system"}
  // Use WebSocket subscriptions for real-time updates
  const subscriptionId = connection.onAccountChange(
    pubkey,
    (accountInfo, context) => {
      // Handle real-time updates
      console.log('Account updated:', accountInfo);
    },
    'confirmed',
    { encoding: 'base64', dataSlice: { offset: 0, length: 100 }}
  );
  ```
</CodeGroup>

### Pemantauan Akun Program

```typescript theme={"system"}
// Monitor specific program accounts with filters
connection.onProgramAccountChange(
  programId,
  (accountInfo, context) => {
    // Handle program account changes
  },
  'confirmed',
  {
    filters: [
      { dataSize: 1024 },
      { memcmp: { offset: 0, bytes: ACCOUNT_DISCRIMINATOR }}
    ],
    encoding: 'base64'
  }
);
```

### Pemantauan Transaksi

```typescript theme={"system"}
// Subscribe to transaction logs for real-time monitoring
const ws = new WebSocket(`wss://mainnet.helius-rpc.com/?api-key=${API_KEY}`);

ws.on('open', () => {
  ws.send(JSON.stringify({
    jsonrpc: '2.0',
    id: 1,
    method: 'logsSubscribe',
    params: [
      { mentions: [programId] },
      { commitment: 'confirmed' }
    ]
  }));
});

ws.on('message', (data) => {
  const message = JSON.parse(data);
  if (message.params) {
    const signature = message.params.result.value.signature;
    // Process transaction signature
  }
});
```

## Pola Tingkat Lanjut

### Logika Percobaan Ulang Cerdas

```typescript theme={"system"}
class RetryManager {
  private backoff = new ExponentialBackoff({
    min: 100,
    max: 5000,
    factor: 2,
    jitter: 0.2
  });

  async executeWithRetry<T>(operation: () => Promise<T>): Promise<T> {
    while (true) {
      try {
        return await operation();
      } catch (error) {
        if (error.message.includes('429')) {
          // Rate limit - wait and retry
          await this.backoff.delay();
          continue;
        }
        throw error;
      }
    }
  }
}
```

### Pemrosesan Hemat Memori

```typescript theme={"system"}
// Process large datasets in chunks
function chunk<T>(array: T[], size: number): T[][] {
  return Array.from({ length: Math.ceil(array.length / size) }, (_, i) =>
    array.slice(i * size, i * size + size)
  );
}

// Process program accounts in batches
const allAccounts = await connection.getProgramAccounts(programId, {
  dataSlice: { offset: 0, length: 32 }
});

const chunks = chunk(allAccounts, 100);
for (const batch of chunks) {
  const detailedAccounts = await connection.getMultipleAccountsInfo(
    batch.map(acc => acc.pubkey)
  );
  // Process batch...
}
```

### Pengumpulan Koneksi

```typescript theme={"system"}
class ConnectionPool {
  private connections: Connection[] = [];
  private currentIndex = 0;

  constructor(rpcUrls: string[]) {
    this.connections = rpcUrls.map(url => new Connection(url));
  }

  getConnection(): Connection {
    const connection = this.connections[this.currentIndex];
    this.currentIndex = (this.currentIndex + 1) % this.connections.length;
    return connection;
  }
}

const pool = new ConnectionPool([
  'https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY',
  'https://mainnet-backup.helius-rpc.com/?api-key=YOUR_API_KEY'
]);
```

## Pemantauan Performa

### Lacak Penggunaan RPC

```typescript theme={"system"}
class RPCMonitor {
  private metrics = {
    calls: 0,
    errors: 0,
    totalLatency: 0
  };

  async monitoredCall<T>(operation: () => Promise<T>): Promise<T> {
    const start = Date.now();
    this.metrics.calls++;
    
    try {
      const result = await operation();
      this.metrics.totalLatency += Date.now() - start;
      return result;
    } catch (error) {
      this.metrics.errors++;
      throw error;
    }
  }

  getStats() {
    return {
      ...this.metrics,
      averageLatency: this.metrics.totalLatency / this.metrics.calls,
      errorRate: this.metrics.errors / this.metrics.calls
    };
  }
}
```

## Praktik Terbaik

### Tingkat Komitmen

<Tabs>
  <Tab title="processed">
    * **Gunakan untuk**: Langganan WebSocket, pembaruan real-time
    * **Latensi**: \~400 md
    * **Keandalan**: Baik untuk sebagian besar aplikasi
  </Tab>

  <Tab title="confirmed">
    * **Gunakan untuk**: Kueri umum, informasi akun
    * **Latensi**: \~1 dtk
    * **Keandalan**: Direkomendasikan untuk sebagian besar kasus penggunaan
  </Tab>

  <Tab title="finalized">
    * **Gunakan untuk**: Penyelesaian akhir, operasi yang tidak dapat dibatalkan
    * **Latensi**: \~32 dtk
    * **Keandalan**: Kepastian maksimum
  </Tab>
</Tabs>

### Pengelolaan Sumber Daya

<CheckboxList>
  * Gunakan `dataSlice` untuk membatasi ukuran payload
  * Terapkan pemfilteran sisi server dengan `memcmp` dan `dataSize`
  * Kelompokkan operasi untuk mengurangi perjalanan bolak-balik
  * Simpan hasil dalam cache untuk menghindari panggilan berulang
  * Tutup langganan WebSocket setelah selesai
  * Terapkan circuit breaker untuk penanganan kesalahan
</CheckboxList>

### Penanganan Kesalahan

```typescript theme={"system"}
// Implement robust error handling
async function robustRPCCall<T>(operation: () => Promise<T>): Promise<T> {
  try {
    return await operation();
  } catch (error) {
    if (error.code === -32602) {
      // Invalid params - fix request
      throw new Error('Invalid RPC parameters');
    } else if (error.code === -32005) {
      // Node behind - retry with different node
      throw new Error('Node synchronization issue');
    } else if (error.message.includes('429')) {
      // Rate limit - implement backoff
      throw new Error('Rate limited');
    }
    throw error;
  }
}
```

## Kesalahan Umum yang Harus Dihindari

<Warning>
  **Hindari kesalahan umum berikut:**

  * Melakukan polling alih-alih menggunakan langganan WebSocket
  * Mengambil data akun lengkap ketika hanya data parsial yang diperlukan
  * Tidak menggunakan operasi batch untuk beberapa kueri
  * Mengabaikan batas laju dan tidak menerapkan logika percobaan ulang yang tepat
  * Menggunakan komitmen `finalized` ketika `confirmed` sudah memadai
  * Tidak menutup langganan sehingga menyebabkan kebocoran memori
</Warning>

## Metode Terkait

Teknik optimasi dalam panduan ini merujuk pada metode WebSocket dan RPC berikut:

<CardGroup cols={2}>
  <Card title="getTransactionsForAddress" href="/docs/id/rpc/gettransactionsforaddress">
    Riwayat transaksi lengkap dengan dukungan pemfilteran, pengurutan, dan akun token (eksklusif Helius)
  </Card>

  <Card title="getTransfersByAddress" href="/docs/id/rpc/gettransfersbyaddress">
    Riwayat transfer token dan SOL yang telah diurai untuk pembayaran dan rekonsiliasi (eksklusif Helius)
  </Card>

  <Card title="getTransaction" href="/docs/id/api-reference/rpc/http/gettransaction">
    Ambil detail transaksi lengkap berdasarkan tanda tangan
  </Card>

  <Card title="getProgramAccounts" href="/docs/id/api-reference/rpc/http/getprogramaccounts">
    Ambil semua akun yang dimiliki oleh suatu program
  </Card>

  <Card title="getTokenAccountsByOwner" href="/docs/id/api-reference/rpc/http/gettokenaccountsbyowner">
    Dapatkan akun token untuk dompet
  </Card>

  <Card title="getMultipleAccountsInfo" href="/docs/id/api-reference/rpc/http/getmultipleaccounts">
    Ambil detail beberapa akun secara batch
  </Card>

  <Card title="getAccountInfo" href="/docs/id/api-reference/rpc/http/getaccountinfo">
    Dapatkan informasi tentang satu akun
  </Card>

  <Card title="accountSubscribe" href="/docs/id/api-reference/rpc/websocket/accountsubscribe">
    Berlangganan perubahan akun melalui WebSocket
  </Card>

  <Card title="programSubscribe" href="/docs/id/api-reference/rpc/websocket/programsubscribe">
    Berlangganan perubahan akun program melalui WebSocket
  </Card>

  <Card title="logsSubscribe" href="/docs/id/api-reference/rpc/websocket/logssubscribe">
    Berlangganan log transaksi melalui WebSocket
  </Card>
</CardGroup>

## Ringkasan

Dengan menerapkan teknik optimasi ini, Anda dapat mencapai:

* **Pengurangan 60–90%** dalam volume panggilan API
* **Latensi yang jauh lebih rendah** untuk operasi real-time
* **Penggunaan bandwidth yang lebih rendah** melalui kueri yang ditargetkan
* **Ketahanan terhadap kesalahan yang lebih baik** dengan logika percobaan ulang cerdas
* **Biaya operasional yang lebih rendah** melalui penggunaan sumber daya yang efisien

<Card title="Next Steps" icon="arrow-right">
  Siap menerapkan optimasi ini? Lihat [Panduan Optimasi Transaksi](/docs/id/sending-transactions/optimizing-transactions) kami untuk mempelajari praktik terbaik khusus transaksi.
</Card>
