Skip to main content
Events allow your program to emit structured data that clients can subscribe to and monitor. Anchor provides two ways to emit events: through program logs with emit! or through Cross Program Invocations with emit_cpi!.

Defining Events

Define events using the #[event] attribute on a struct:
Events can contain any data types that implement AnchorSerialize and AnchorDeserialize.

Emitting Events with emit!

The emit! macro is the simpler approach, writing events to program logs using the sol_log_data() syscall:

How emit! Works

  1. Serializes the event data
  2. Calls sol_log_data() to write to program logs
  3. Encodes data as base64 with the prefix Program data:

Program Logs Output

When an event is emitted, it appears in the logs:

Emitting Events with emit_cpi!

The emit_cpi! macro emits events through a Cross Program Invocation, including the data in the instruction data instead of logs. This approach is more reliable when working with data providers that might truncate logs.

Setup

Enable the event-cpi feature in Cargo.toml:

Usage

The #[event_cpi] attribute must be added to the accounts struct. It automatically includes additional accounts required for the self-CPI.

Subscribing to Events in TypeScript

Using emit! Events

Listen to events with addEventListener():

Using emit_cpi! Events

For CPI events, fetch the transaction and decode manually:

Complete Example

Here’s a real-world example from a token staking program:

emit! vs emit_cpi!

Best Practices

  1. Keep events small: Only include necessary data to minimize compute costs
  2. Add timestamps: Always include a timestamp for event ordering
  3. Use descriptive names: Name events clearly (e.g., TokensMinted, UserRegistered)
  4. Version events: Consider adding a version field for future compatibility
  5. Test event emission: Write tests to verify events are emitted correctly
  6. Document events: Explain when each event is emitted and what data it contains

Limitations

  • Log truncation: RPC providers may truncate program logs (use emit_cpi! for critical events)
  • No event history: Events are only available in transaction logs, not stored on-chain
  • Size limits: Very large events may hit transaction size limits
For production applications requiring reliable event indexing, consider using Geyser gRPC services from providers like Triton or Helius.