---
title: Decide methods for the Go SDK
slug: feature-experimentation/docs/decide-methods-go
docTags: 
createdAt: 2026-08-05T20:39:56.000Z
---

Use the decide methods to return feature flag decisions for a user. Each decision includes whether the flag is enabled and which variation the user receives.

## Decide

Returns a decision for a specific feature flag and user.

**Minimum SDK version** – v1.6.0+

### Description

The decide method handles the variation decision for an individual experiment. It returns a decision result for a flag key for a user in an `OptimizelyDecision` object and contains the data required to deliver the flag rule.

This method ensures that Feature Experimentation properly buckets the user in experiment analytics, and you should use it if there is no need for pre-rendering decisions.

:::hint{type="info"}
Decide is a method of the UserContext object. See [OptimizelyUserContext](docId\:YD23vbbeambJxxmSEXUo8) for details.
:::

See the  [OptimizelyDecision](docId\:bAl3piZKbSaDKyKI7TlBE) for details of the returned decision object.

### Key features

- **Single experiment decision** – Returns the variation for a specific experiment.
- **Bucketing in results** – Ensures Feature Experimentation records the user in the experiment results page for proper analysis.
- **Complement to decide all method** – If you use the [decide all method](archbee-doc-SzZh7C_1dl_7tXmTs7bEq.mdx) to pre-fetch variations, you should also call the decide method for each experiment that the user interacts with. This dual approach guarantees that Feature Experimentation accurately tracks the user's participation and that the correct variation is served through caching.
- **CMAB support** – For CMAB experiments, decisions are automatically cached to reduce latency. The cache is invalidated when CMAB attributes change or TTL expires. Use CMAB-specific decide options (`IGNORE_CMAB_CACHE`, `INVALIDATE_USER_CMAB_CACHE`, and  `RESET_CMAB_CACHE`) to override default caching behavior. See the following CMAB cache control information.

### Parameters

The following table describes parameters for the decide method:

| Parameter | Type   | Description                                                              |
| --------- | ------ | ------------------------------------------------------------------------ |
| `flagKey` | String | The key of the feature flag                                              |
| `options` | Array  | Array of [OptimizelyDecideOptions](docId\:IoD8v8YEqQ17iXC7QRUzw)  enums. |

### Returns

The decide method returns an [OptimizelyDecision](docId\:bAl3piZKbSaDKyKI7TlBE) object.

If the method encounters a critical error (SDK not ready, invalid flag key, and so on), then it returns a decision with a `null` `variationKey` field and populates the `Reasons` field with error messages (regardless of the `OptimizelyDecideOption.INCLUDE_REASONS` option).

### Example `decide`

```go
package main

import (
	"fmt"

  optly "github.com/optimizely/go-sdk"      // for v2: "github.com/optimizely/go-sdk/v2"
  "github.com/optimizely/go-sdk/pkg/decide" // for v2: "github.com/optimizely/go-sdk/v2/pkg/decide"
)

func main() {
	optimizely_client, err := optly.Client("SDK_KEY_HERE") // Replace with your SDK key
	if err != nil {
		panic(err)
	}

	user := optimizely_client.CreateUserContext("user123", map[string]interface{}{"logged_in": true})
	decision := user.Decide("product_sort", []decide.OptimizelyDecideOptions{})

	// Did the decision fail with a critical error?
	if decision.VariationKey == "" {
		fmt.Printf("[decide] error: %v", decision.Reasons)
		return
	}

	// Flag enabled state
	enabled := decision.Enabled
	fmt.Println("Decision enabled: ", enabled)

	// String variable value
	var value1 string
	if err := decision.Variables.GetValue("sort_method", &value1); err != nil {
		panic(err)
	}
	// Or
	value2 := decision.Variables.ToMap()["sort_method"].(string)
	fmt.Println("Variable value: ", value2)

	// All variable values
	allVarValues := decision.Variables
	fmt.Println("All variable: ", allVarValues)

	// Variation key
	variationKey := decision.VariationKey
	fmt.Println("Variation Key: ", variationKey)

	// User for which the decision was made
	userContext := decision.UserContext

	// Flag decision reasons
	reasons := decision.Reasons
	fmt.Println("Decision reasons: ", reasons)
}
```

### Side Effect

Invokes the [decision notification listener](docId\:t5MKaa3LIkBM5ovyv7XYn) if this listener is enabled.

## Decide all

Returns decisions for all active (unarchived) flags for a user.

**Minimum SDK version** – v1.6.0+

### Description

Use the decide all method to retrieve decisions for all active flags before rendering content. This is particularly useful when you need to serve the correct cached version of your page or component based on the user's variation. For example when using an [edge worker](../../developer-docs/optimizely-edge-agent/introduction-to-optimizely-edge-agent/index.mdx) or [cloud function](../../developer-docs/optimizely-feature-experimentation-at-the-edge/get-started-edge-functions.mdx).

### Key features

- **Pre-rendering decision** – Lets you know all variation assignments ahead of time.
- **Cache control** – Lets you serve the correct cached content based on the user's pre-determined variations.
- **Delay experiment tracking** – Use `DISABLE_DECISION_EVENT` to prevent the SDK from recording a decision before the user sees the feature. This ensures that participation is only tracked when the experience is delivered.
- **CMAB support** – For CMAB experiments (SDK v5.2.0+), decisions are automatically cached to reduce latency. The cache is invalidated when CMAB attributes change or TTL expires. Use CMAB-specific decide options (`ignoreCmabCache`, `invalidateUserCmabCache`, `resetCmabCache`) to override default caching behavior. See [CMAB cache control](archbee-doc-SXro2YIwdH2k9jGnXKaLr.mdx).

### Parameters

The following table describes parameters for the decide all method:

| Parameter | Type  | Description                                                             |
| --------- | ----- | ----------------------------------------------------------------------- |
| `options` | Array | Array of [OptimizelyDecideOptions](docId\:IoD8v8YEqQ17iXC7QRUzw) enums. |

### Returns

The decide all method returns a map of `OptimizelyDecision` objects. For information, see [OptimizelyDecision](docId\:bAl3piZKbSaDKyKI7TlBE).

If the method fails for all flags (for example, the SDK is not ready or the user context is invalid), then it returns an empty map. If the method detects an error for a specific flag, it returns error messages in the `Reasons` field of the decision for that flag.

### Example `DecideAll`

```go
// Make a decisions for all active (unarchived) flags for the user
decisions := user.DecideAll([]decide.OptimizelyDecideOptions{})
// Or only for enabled flags
decisions = user.DecideAll([]decide.OptimizelyDecideOptions{decide.EnabledFlagsOnly})

flagKeys := []string{}
flagDecisions := []client.OptimizelyDecision{}
for k, v := range decisions {
  flagKeys = append(flagKeys, k)
  flagDecisions = append(flagDecisions, v)
}
decisionForFlag1 := decisions["flag_1"]
```

### Side effect

Invokes the [decision notification listener](docId\:t5MKaa3LIkBM5ovyv7XYn) for each decision, if this listener is enabled.

## Decide for keys

Returns a map of flag decisions for specified flag keys.

**Minimum SDK version** – v1.6.0+

### Description

Returns a map of decisions for the specified flag keys.

### Parameters

The following table describes parameters for the decide for keys method:

| Parameter | Type  | Description                                                             |
| --------- | ----- | ----------------------------------------------------------------------- |
| `keys`    | Array | Array of string flag keys.                                              |
| `options` | Array | Array of [OptimizelyDecideOptions](docId\:IoD8v8YEqQ17iXC7QRUzw) enums. |

### Returns

Returns a map of OptimizelyDecisions. For information, see [OptimizelyDecision](docId\:bAl3piZKbSaDKyKI7TlBE).

If the method fails for all flags (for example, the SDK is not ready or the user context is invalid), then it returns an empty map. If the method detects an error for a specific flag, it returns error messages in the Reasons field of the decision for that flag.

### Example `DecideForKeys`

```go
decisions := user.DecideForKeys([]string{"flag_1", "flag_2"}, []decide.OptimizelyDecideOptions{decide.EnabledFlagsOnly})

decisionForFlag1 := decisions["flag_1"]
decisionForFlag2 := decisions["flag_2"]
```

### Side effect

Invokes the [decision notification listener](docId\:t5MKaa3LIkBM5ovyv7XYn) for each decision if this listener is enabled.

## `OptimizelyDecideOption`

The following table lists the `OptimizelyDecideOption` enum with an explanation what happens if you set them. In addition to setting these options individually for a decide method, you can also set them as global defaults when you instantiate the Optimizely client. See [Initialize Go SDK](docId\:JfYAO2no3jsLSaDL-GIjG).

| `OptimizelyDecideOption` enum                        | If set                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `OptimizelyDecideOption.DISABLE_DECISION_EVENT`      | Prevents the SDK from dispatching an [impression](../../end-user-docs/measure-and-analyze-results/what-are-impressions-and-decisions-in-feature-experimentation.mdx) event when serving a variation. This disables decision tracking on the [Optimizely Experiment Results page](../../end-user-docs/measure-and-analyze-results/optimizely-experiment-results-page.mdx). The [decision notification listener](../../developer-docs/configure/notification-listeners/decision-notification-listener.mdx) is still called, with `decisionEventDispatched` set to `false`. |
| `OptimizelyDecideOption.ENABLED_FLAGS_ONLY`          | Returns decisions only for flags that are currently enabled. Used with the decide all method and decide for keys method.<br />When this option is not set, the SDK returns all decisions regardless of whether the flag is enabled.                                                                                                                                                                                                                                                                                                                                      |
| `OptimizelyDecideOption.IGNORE_USER_PROFILE_SERVICE` | Bypasses the user profile service (both lookup and save) for the decision.<br />When this option is not set, user profile service overrides audience targeting, traffic allocation, and experiment mutual exclusion groups.                                                                                                                                                                                                                                                                                                                                              |
| `OptimizelyDecideOption.INCLUDE_REASONS`             | Adds log messages to the reasons field of the decision. Critical errors are always returned, even if this option is not set.                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `OptimizelyDecideOption.EXCLUDE_VARIABLES`           | Excludes flag variable values from the decision result. Use this option to minimize the returned decision by skipping large JSON variables.                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `OptimizelyDecideOption.IGNORE_CMAB_CACHE`           | Bypasses the CMAB cache and fetches a fresh decision from the CMAB service. Use when you need real-time decisions that reflect the latest context.                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `OptimizelyDecideOption.INVALIDATE_USER_CMAB_CACHE`  | Removes the cached CMAB decision for this user and experiment before making the decision. Use when user context has changed significantly and you want to ensure a fresh decision.                                                                                                                                                                                                                                                                                                                                                                                       |
| `OptimizelyDecideOption.RESET_CMAB_CACHE`            | Clears all entries from the CMAB cache before making the decision. Use sparingly for testing or cache corruption scenarios.                                                                                                                                                                                                                                                                                                                                                                                                                                              |

## Best practices

- **Early and late invocation**
  - Use the decide all method early in your application's rendering process to load the correct cached content. For example, on the [CDN with an Edge SDK](../../developer-docs/optimizely-feature-experimentation-at-the-edge/content-delivery-networks.mdx).
  - Use the decide method at the point of user interaction or when you must ensure Feature Experimentation records the decision in your experiment analytics.
- **Combining methods** – When using the decide and decide all methods, always pair the decide all method with the decide method for each experiment the user encounters. This prevents discrepancies between served content and analytics data.
- **Parameter management** – Ensure you use the `DISABLE_DECISION_EVENT` option with the decide all method to avoid premature bucketing, then use the decide method to handle the decision event when the user experiences the content.

## CMAB cache control

**Minimum Go SDK version** – v2.2.0+

For Contextual Multi-Armed Bandit (CMAB) experiments, the Go SDK automatically caches variation assignments to reduce latency and API calls. The cache stores decisions based on user ID, experiment ID, and CMAB attribute values.

### Automatic cache invalidation

The cache is automatically invalidated when

- The cached entry's TTL expires (default: 30 minutes).
- CMAB attribute values change for a user (detected through attribute hash comparison).

### Manual cache control

Use CMAB-specific decide options to control cache behavior on a per-decision basis, like in the following example:

```go
import (
    optly "github.com/optimizely/go-sdk/v2"
    "github.com/optimizely/go-sdk/v2/pkg/decide"
)

optimizely_client, err := optly.Client("SDK_KEY_HERE")
if err != nil {
    panic(err)
}

// Example 1: Bypass cache for real-time decision
user := optimizely_client.CreateUserContext("user123",
map[string]interface{}{
    "age":      25,
    "location": "US",
})
decision := user.Decide("my-cmab-flag",
[]decide.OptimizelyDecideOptions{
    decide.IgnoreCMABCache, // Always fetch fresh from CMAB service
})

// Example 2: Invalidate cache when user context changes significantly
user.SetAttributes(map[string]interface{}{
    "age":      26,
    "location": "UK", // Context changed
})
decision = user.Decide("my-cmab-flag",
[]decide.OptimizelyDecideOptions{
    decide.InvalidateUserCMABCache, // Clear cached decision for this user
})

// Example 3: Reset entire CMAB cache (use sparingly)
decision = user.Decide("my-cmab-flag",
[]decide.OptimizelyDecideOptions{
    decide.ResetCMABCache, // Clear all CMAB cache entries
})
```

## CMAB decision reasons

When using `INCLUDE_REASONS`, CMAB-related information appears in the decision's `Reasons` field, like in the following example:

```go
decision := user.Decide("my-cmab-flag",
[]decide.OptimizelyDecideOptions{
    decide.IncludeReasons,
})

// Print CMAB-related decision reasons
for _, reason := range decision.Reasons {
    fmt.Println(reason)
    // Examples:
    // "CMAB decision retrieved from cache."
    // "CMAB decision fetched from service."
    // "CMAB cache invalidated due to attribute change."
}
```

:::hint{type="info"}
Configure CMAB cache settings (size, TTL, and timeout) at client initialization time. See [Initialize the Go SDK](docId\:lA6eDbcuVC3C-SQUsCcXV) and [Configure the CMAB cache for the Go SDK](docId\:DO99zUMx-6ddApNEfOqHo) for details.
:::

## Source files

The language and platform source files containing the implementation for Go are available on [GitHub](https://github.com/optimizely/go-sdk/blob/master/pkg/client/client.go).
