Events with emit!
#[event] types and emit! macro write structured logs indexers can parse. Prefer events over ad-hoc msg! for observable state changes.
Search across all documentation pages
#[event] types and emit! macro write structured logs indexers can parse. Prefer events over ad-hoc msg! for observable state changes.
#[event]
pub struct TradeExecuted {
pub user: Pubkey,
pub amount_in: u64,
pub amount_out: u64,
}
emit!(TradeExecuted { user: ctx.accounts.user.key(), amount_in, amount_out });When to reach for this: Indexers, analytics, or clients need reliable post-hoc observation.
#[event]
pub struct PositionOpened {
pub owner: Pubkey,
pub market: Pubkey,
pub size: u64,
pub timestamp: i64,
}
pub fn open_position(ctx: Context<OpenPosition>, size: u64) -> Result<()> {
let clock = Clock::get()?;
emit!(PositionOpened {
owner: ctx.accounts.owner.key(),
market: ctx.accounts.market.key(),
size,
timestamp: clock.unix_timestamp,
});
Ok(())
}What this demonstrates:
Classic emit! triggers a self-CPI that some indexers rely on. For guaranteed capture in all runtimes, see emit_cpi!.
Include keys needed to join off-chain data; avoid huge blobs in events.
| Alternative | Use When | Don't Use When |
|---|---|---|
| emit_cpi! | Reliable capture | Simple local dev |
| Account state only | No logs needed | Indexer-driven analytics |
| Geyser gRPC | Infrastructure heavy | App-level events |
Custom codes in IDL plus #[msg] strings.
emit_cpi! costs more CU but improves capture reliability.
Avoid except behind feature flags.
From IDL via Anchor or Codama codegen.
Yes, #[event] types are listed.
Yes with @ MyError::Variant.
Each log line and formatted string.
anchor test expecting error codes.
Yes, but not an API contract; use events.
See Related for events.
Stack versions: This page was written for Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0, and LiteSVM 0.6.x.
Reviewed by Chris St. John·Last updated Jul 19, 2026