> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cosmos.network/llms.txt
> Use this file to discover all available pages before exploring further.

# BeginBlocker and EndBlocker

<Note>
  **Synopsis**
  `BeginBlocker` and `EndBlocker` are optional methods module developers can implement in their module. They will be triggered at the beginning and at the end of each block respectively, when the [`BeginBlock`](/sdk/v0.47/learn/advanced/baseapp#beginblock) and [`EndBlock`](/sdk/v0.47/learn/advanced/baseapp#endblock) ABCI messages are received from the underlying consensus engine.
</Note>

<Note>
  ### Pre-requisite Readings

  * [Module Manager](/sdk/v0.47/build/building-modules/module-manager)
</Note>

## BeginBlocker and EndBlocker

`BeginBlocker` and `EndBlocker` are a way for module developers to add automatic execution of logic to their module. This is a powerful tool that should be used carefully, as complex automatic functions can slow down or even halt the chain.

When needed, `BeginBlocker` and `EndBlocker` are implemented as part of the [`BeginBlockAppModule` and `BeginBlockAppModule` interfaces](/sdk/v0.47/build/building-modules/module-manager#appmodule). This means either can be left-out if not required. The `BeginBlock` and `EndBlock` methods of the interface implemented in `module.go` generally defer to `BeginBlocker` and `EndBlocker` methods respectively, which are usually implemented in `abci.go`.

The actual implementation of `BeginBlocker` and `EndBlocker` in `abci.go` are very similar to that of a [`Msg` service](/sdk/v0.47/build/building-modules/msg-services):

* They generally use the [`keeper`](/sdk/v0.47/build/building-modules/keeper) and [`ctx`](/sdk/v0.47/learn/advanced/context) to retrieve information about the latest state.
* If needed, they use the `keeper` and `ctx` to trigger state-transitions.
* If needed, they can emit [`events`](/sdk/v0.47/learn/advanced/events) via the `ctx`'s `EventManager`.

A specificity of the `EndBlocker` is that it can return validator updates to the underlying consensus engine in the form of an [`[]abci.ValidatorUpdates`](/cometbft/v0.38/spec/abci/Methods#endblock). This is the preferred way to implement custom validator changes.

It is possible for developers to define the order of execution between the `BeginBlocker`/`EndBlocker` functions of each of their application's modules via the module's manager `SetOrderBeginBlocker`/`SetOrderEndBlocker` methods. For more on the module manager, click [here](/sdk/v0.47/build/building-modules/module-manager#manager).

See an example implementation of `BeginBlocker` from the `distribution` module:

```go expandable theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
package distribution

import (
    
	"time"

	abci "github.com/tendermint/tendermint/abci/types"
    "github.com/cosmos/cosmos-sdk/telemetry"
	sdk "github.com/cosmos/cosmos-sdk/types"
    "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
    "github.com/cosmos/cosmos-sdk/x/distribution/types"
)

// BeginBlocker sets the proposer for determining distribution during endblock
// and distribute rewards for the previous block.
func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, k keeper.Keeper) {
    defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker)

	// determine the total power signing the block
	var previousTotalPower int64
    for _, voteInfo := range req.LastCommitInfo.GetVotes() {
    previousTotalPower += voteInfo.Validator.Power
}

	// TODO this is Tendermint-dependent
	// ref https://github.com/cosmos/cosmos-sdk/issues/3095
    if ctx.BlockHeight() > 1 {
    k.AllocateTokens(ctx, previousTotalPower, req.LastCommitInfo.GetVotes())
}

	// record the proposer for when we payout on the next block
    consAddr := sdk.ConsAddress(req.Header.ProposerAddress)

k.SetPreviousProposerConsAddr(ctx, consAddr)
}
```

and an example implementation of `EndBlocker` from the `staking` module:

```go expandable theme={"theme":{"light":"github-light-high-contrast","dark":"github-dark-high-contrast"}}
package staking

import (
    
	"time"

	abci "github.com/tendermint/tendermint/abci/types"
    "github.com/cosmos/cosmos-sdk/telemetry"
	sdk "github.com/cosmos/cosmos-sdk/types"
    "github.com/cosmos/cosmos-sdk/x/staking/keeper"
    "github.com/cosmos/cosmos-sdk/x/staking/types"
)

// BeginBlocker will persist the current header and validator set as a historical entry
// and prune the oldest entry based on the HistoricalEntries parameter
func BeginBlocker(ctx sdk.Context, k *keeper.Keeper) {
    defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyBeginBlocker)

k.TrackHistoricalInfo(ctx)
}

// Called every block, update validator set
func EndBlocker(ctx sdk.Context, k *keeper.Keeper) []abci.ValidatorUpdate {
    defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), telemetry.MetricKeyEndBlocker)

return k.BlockValidatorUpdates(ctx)
}
```
