Guarding Pattern: Release a Feature
This pattern covers moving a feature from guarded internal testing to a broader audience, and eventually to a full release where the guard is no longer needed.
This picks up where the New Feature pattern leaves off. If you are not yet at the point where internal testing is complete, start there first.
Phase 1: Staged rollout to a broader group
After internal testing succeeds, you may want to expand to a larger set of users before releasing to everyone. The approach is the same as the internal testing rule — you control who sees the feature by adjusting the values in your in rule.
On the guard detail page:
- Open the existing
userId in [...]rule. - Add more user IDs, or replace the existing list with a broader group.
- Click Save.
The change takes effect the next time each SDK instance refreshes its bundle, which happens at the configured refresh interval (default 60 seconds).
There is no redeployment required. The feature expands to the new audience without touching your application code.
You can repeat this as many times as needed — a small pilot, then a beta group, then early adopters — each time expanding the rule's value list. The guard catalog's Evaluated count and Last evaluated time give you a rough signal that the feature is being reached.
Phase 2: Release to everyone
When you are ready to release the feature to all users, the simplest path is to change the default value.
On the guard detail page:
- Remove or disable the
userId in [...]rule. You can disable it rather than delete it if you want to preserve it as a reference. - Set the Default value toggle to on (true).
- Click Save.
The feature is now open for all callers regardless of the properties they pass. No code change, no redeployment.
Per-environment promotion
If you maintain separate environments such as staging and production, promote the release through each one independently.
- Use the Switcher to select
staging. - Set the default value to
trueon the staging configuration and save. - Verify that the feature behaves correctly in staging.
- Use the Switcher to select
production. - Set the default value to
trueon the production configuration and save.
Each environment stores its own configuration, so you can release to staging without affecting production and vice versa.
Phase 3: Remove the guard (optional)
Once the feature has been fully released and has been stable for a reasonable period, the guard check in your code is no longer doing useful work. At that point you have two options:
Option A: Archive the guard, remove the code later. Set the guard's lifecycle state to Archived in the metadata modal (the pencil icon on the guard detail page). This marks it as inactive in the catalog without deleting its history. Remove the isOpen call from your code in a follow-up change.
Option B: Remove the code and let the guard go quiet. Remove the isOpen call from your code and deploy. The guard will stop receiving evaluation signals. You can archive it in Liteguard afterward once you are sure nothing else is calling it.
Either way, the code change is safe: after setting the default value to true, removing the guard call from your code is equivalent to every caller seeing true unconditionally, which is what the guard was already returning.
Rollback at any phase
If something goes wrong after expanding the rollout or releasing fully, you can roll back instantly without a code deployment.
- If you released to everyone by setting the default value to
true, flip it back tofalse. - If you released via an expanded rule list, remove or tighten the rule.
The change propagates to all SDK instances within one refresh cycle (default 60 seconds).
This is the key operational advantage of using a guard: your rollback path does not require a redeployment.
Summary of actions by phase
| Phase | What to change in Liteguard | Code change? |
|---|---|---|
| Internal testing | Add userId in [list] rule with result true | Pass userId property to isOpen |
| Staged rollout | Expand the in rule's value list | No |
| Full release | Remove rule, set default value to true | No |
| Cleanup | Archive the guard | Remove the isOpen call |
| Rollback | Flip default value back to false | No |