flippercloud/flipper · error · Flipper::Adapters::ActorLimit::LimitExceeded
Actor limit of #{@limit} exceeded for feature #{feature.key}
Error message
Actor limit of #{@limit} exceeded for feature #{feature.key}. See https://www.flippercloud.io/docs/features/actors#limitations What it means
The ActorLimit adapter wrapper (used by Flipper Cloud) caps how many individual actors may be enabled per feature (default limit 100). Its enable() raises ActorLimit::LimitExceeded when you enable an actor on a feature whose actors_value set already has at least `limit` entries, because per-actor gate rows do not scale and gate reads get slow. The check is skipped for non-actor gates and inside ActorLimit.with_sync_mode, which the sync machinery uses to mirror remote state.
Source
Thrown at lib/flipper/adapters/actor_limit.rb:41
# Executes a block with sync mode enabled. Actor limits will
# not be enforced within the block.
def with_sync_mode
old_value = sync_mode
self.sync_mode = true
yield
ensure
self.sync_mode = old_value
end
end
def initialize(adapter, limit = 100)
super(adapter)
@limit = limit
end
def enable(feature, gate, resource)
if gate.is_a?(Flipper::Gates::Actor) && !self.class.sync_mode && over_limit?(feature)
raise LimitExceeded, "Actor limit of #{@limit} exceeded for feature #{feature.key}. See https://www.flippercloud.io/docs/features/actors#limitations"
else
super
end
end
private
def over_limit?(feature)
feature.actors_value.size >= @limit
end
end
end
end
View on GitHub (pinned to 1f86de3ec9)
Solutions
- Switch to a rollout mechanism that scales: feature.enable_percentage_of_actors(25), enable_group, or enable_expression.
- Prune the list first: disable actors you no longer need (feature.disable_actor(actor)) so the count drops below the limit before enabling more.
- If you are deliberately syncing state (e.g. replicating a remote set), wrap the writes in Flipper::Adapters::ActorLimit.with_sync_mode { ... } to bypass the check.
- If you constructed Flipper::Adapters::ActorLimit yourself with a custom limit, review whether that limit fits the feature's usage before raising it.
Example fix
# before
users.find_each { |user| Flipper[:beta].enable_actor user } # raises at actor #101
# after
Flipper[:beta].enable_percentage_of_actors 25
# or target a stable cohort
Flipper.register(:beta_optins) { |actor| actor.respond_to?(:beta_optin?) && actor.beta_optin? }
Flipper[:beta].enable_group :beta_optins Defensive patterns
Strategy: validation
Validate before calling
def enable_actor_safely(feature, actor, limit = 100)
if feature.actors_value.size >= limit
feature.enable_percentage_of_actors(100) # or another rollout strategy
else
feature.enable_actor(actor)
end
end Try / catch
begin Flipper[:beta].enable_actor(user) rescue Flipper::Adapters::ActorLimit::LimitExceeded Flipper[:beta].enable_percentage_of_actors(25) # fall back to a scalable rollout end
Prevention
- Prefer percentage_of_actors, groups, or expressions over long actor lists.
- Monitor feature.actors_value.size as you enable individual actors.
- Keep bulk actor imports idempotent and resumable so a limit hit mid-run is recoverable.
When it happens
Trigger: feature.enable_actor(user) / Flipper.enable(:beta, user) on a feature that already has >= limit (default 100) enabled actors, outside of sync mode. Typically reached in a loop that enables users one by one.
Common situations: Progressive individual rollouts where a script keeps calling enable_actor past 100 users; backfills/imports that enable lists of actors; teams hitting the Flipper Cloud per-feature actor cap; code migrated from boolean flags to individual actor enables instead of percentage rollouts.
Related errors
- Failed with status: #{response.code}
- Group #{name.inspect} has already been registered
- Your database needs to be migrated to use the latest Flipper
- #{data_type} is not supported by this adapter
- #{gate} is not supported by this adapter yet
AI-assisted analysis of flippercloud/flipper@1f86de3ec9 (2026-08-23).
Data as JSON: /api/errors/83e5fe7cd98703b7.
Report an issue: GitHub.