---
title: Best Practices
description:
  "The best practices for Solana program development, including: optimize
  compute, fuzzing, repo structure, indexing, and more."
seoTitle: "What are best practices for Solana program development?"
keywords:
  - solana best practices
  - program best practices
  - program development
  - program security
  - development best practices
  - smart contract best practices
  - solana smart contracts
h1: Solana Program Best Practices
---

> This is a beta version of the [Solana Toolkit](/docs/toolkit/), and is
> still a WIP. Please post all feedback as a GitHub issue
> [here](https://github.com/solana-foundation/developer-content/issues/new?title=%5Btoolkit%5D%20).

## Optimize Compute Usage

To prevent abuse of computational resources, each transaction is allocated a
"compute budget". This budget specifies details about
[compute units](/docs/core/fees#compute-units) and includes:

- the compute costs associated with different types of operations the
  transaction may perform (compute units consumed per operation),
- the maximum number of compute units that a transaction can consume (compute
  unit limit),
- and the operational bounds the transaction must adhere to (like account data
  size limits)

When the transaction consumes its entire compute budget (compute budget
exhaustion), or exceeds a bound such as attempting to exceed the
[max call stack depth](https://github.com/anza-xyz/agave/blob/b7bbe36918f23d98e2e73502e3c4cba78d395ba9/program-runtime/src/compute_budget.rs#L138)
or
[max loaded account](/docs/core/fees#accounts-data-size-limit)
data size limit, the runtime halts the transaction processing and returns an
error. Resulting in a failed transaction and no state changes (aside from the
transaction fee being
[collected](/docs/core/fees#fee-collection)).

### Additional References

- [How to Optimize Compute](/developers/guides/advanced/how-to-optimize-compute).
- [How to Request Optimal Compute](/developers/guides/advanced/how-to-request-optimal-compute)

## Saving Bumps

> Program Derived Address (PDAs) are addresses that PDAs are addresses that are
> deterministically derived and look like standard public keys, but have no
> associated private keys. These PDAs are derived using a numerical value,
> called a "bump", to guarantee that the PDA is off-curve and cannot have an
> associated private key. It "bumps" the address off the cryptographic curve.

Saving the bump to your Solana smart contract account state ensures
deterministic address generation, efficiency in address reconstruction, reduced
transaction failure, and consistency across invocations.

### Additional References

- [How to derive a PDA](/docs/core/pda#how-to-derive-a-pda)
- [PDA Bumps Core Concepts](/docs/core/pda#canonical-bump)
- [Bump Seed Canonicalization Lesson](/developers/courses/program-security/bump-seed-canonicalization)

## Payer-Authority Pattern

The Payer-Authority pattern is an elegant way to handle situations where the
account’s funder (payer) differs from the account’s owner or manager
(authority). By requiring separate signers and validating them in your onchain
logic, you can maintain clear, robust, and flexible ownership semantics in your
program.

### Shank Example

```rust
// Create a new account.
#[account(0, writable, signer, name="account", desc = "The address of the new account")]
#[account(1, writable, signer, name="payer", desc = "The account paying for the storage fees")]
#[account(2, optional, signer, name="authority", desc = "The authority signing for the account creation")]
#[account(3, name="system_program", desc = "The system program")]
CreateAccountV1(CreateAccountV1Args),
```

### Anchor Example

```rust
#[derive(Accounts)]
pub struct CreateAccount<'info> {
    /// The address of the new account
    #[account(init, payer = payer_one, space = 8 + NewAccount::MAXIMUM_SIZE)]
    pub account: Account<'info, NewAccount>,

    /// The account paying for the storage fees
    #[account(mut)]
    pub payer: Signer<'info>,

    /// The authority signing for the account creation
    pub authority: Option<Signer<'info>>,

    // The system program
    pub system_program: Program<'info, System>
}
```

### Additional References

- [Metaplex Guide on Payer-Authority Pattern](https://developers.metaplex.com/guides/general/payer-authority-pattern)
- [Helium Program Library using the Payer-Authority Pattern](https://github.com/helium/helium-program-library/blob/master/programs/data-credits/src/instructions/change_delegated_sub_dao_v0.rs#L18)

## Invariants

Implement invariants, which are functions that you can call at the end of your
instruction to assert specific properties because they help ensure the
correctness and reliability of programs.

```rust
require!(amount > 0, ErrorCode::InvalidAmount);
```

### Additional References

- [Complete Project Code Example](https://github.com/solana-developers/developer-bootcamp-2024/blob/main/project-9-token-lottery/programs/token-lottery/src/lib.rs#L291)

## Optimize Indexing

You can make indexing easier by placing static size fields at the beginning and
variable size fields at the end of your onchain structures.
