Laravel Pennant stores and retrieves feature flag values using a flexible storage system that supports two main drivers: an in-memory array driver and a persistent database driver.
Storage Mechanisms:
- Array Driver: This driver stores resolved feature flag values in an in-memory array. It is fast but transient, meaning the stored feature flag values exist only during the current request lifecycle and are lost afterward. This is useful for simple or temporary use cases where persistence is not required.
- Database Driver (Default): Pennant can persist feature flag values in a relational database, specifically in a `features` table created by running Pennant's migrations. This driver stores the resolved feature flag values persistently, allowing the values to be shared across multiple requests and servers. It is ideal for applications running on multiple servers or serverless environments. The database driver also uses an in-memory cache during a single request to avoid repeated database queries for the same feature flag, improving performance[1][2][5].
How Feature Flags Are Defined and Resolved:
- Feature flags are defined using closures that contain the logic to determine whether a feature is active or not. These closures can accept parameters such as the authenticated user, allowing for scoped feature flags (e.g., enabling a feature only for admin users).
- When a feature flag is first checked for a given scope (such as a user), Pennant executes the closure to resolve the feature's value. This resolved value is then stored in the configured storage driver (array or database).
- On subsequent checks for the same feature and scope, Pennant retrieves the stored value from the storage driver instead of recalculating it, which optimizes performance[2][3].
Retrieving Feature Flag Values:
- You can retrieve the value of a single feature flag using methods like `Feature::active('feature-name')` to check if it is enabled (boolean) or `Feature::value('feature-name')` to get its value, which can be boolean or any other data type (rich-value flags).
- Pennant also provides methods to retrieve multiple feature flag values at once, such as `Feature::values(['feature1', 'feature2'])` or `Feature::all()` to get all defined features for a given scope.
- Feature classes can be dynamically discovered and registered to ensure they are included when retrieving all feature flags[1][2].
Summary:
Laravel Pennant resolves feature flag values by running user-defined logic closures and then stores these resolved values either temporarily in an in-memory array or persistently in a database table. This storage mechanism allows Pennant to efficiently retrieve feature flag states on subsequent requests without recalculating, supporting both simple and complex use cases including scoped flags per user. The default and recommended approach is to use the database driver for persistent storage, especially in multi-server or production environments, while the array driver suits transient or testing scenarios[1][2][5].
Citations:
[1] https://laravel.com/docs/11.x/pennant
[2] https://www.honeybadger.io/blog/a-guide-to-feature-flags-in-laravel/
[3] https://www.reddit.com/r/laravel/comments/10yto7q/laravel_pennant_simple_and_lightweight_feature/
[4] https://redberry.international/laravel-pennant-feature-flagging-made-easy/
[5] https://wpwebinfotech.com/blog/laravel-pennant-guide/
[6] https://dev.to/saurabh-dhariwal/how-to-manage-feature-flags-with-laravel-pennant-in-2024-1phb
[7] https://stackoverflow.com/questions/77751003/laravel-pennant-store-against-session-for-a-b-testing
[8] https://laracasts.com/series/whats-new-in-laravel-10/episodes/5