
September 10, 2026
11 min read
By Kokil Thapa | Last reviewed: September 2026
Shipping a big release on Friday still breaks production for too many teams. Feature flags and progressive delivery separate deployment from release so you merge code early, keep it dormant, and turn it on for a small slice of users first. On production Laravel applications I maintain, flags have saved hours that would otherwise go to hotfix deploys. This guide covers the patterns, Laravel Pennant on PHP 8.3+, rollout steps, and the mistakes that cause flag debt.
What are feature flags and how do they enable progressive delivery?
A feature flag is a runtime switch that decides whether a code path runs. Progressive delivery uses those switches to expose new behaviour in controlled steps. You ship the code to production behind a flag. You then widen the audience while watching errors, latency, and business metrics.
Think of three separate events:
- Deploy — new code reaches servers (Git push, CI, symlink swap).
- Release — users can actually use the new capability.
- Rollout — the release expands from internal staff to beta users to everyone.
Without flags, deploy and release happen at the same moment. One bad assumption affects every visitor. With flags, deploy becomes boring and release becomes a deliberate product decision.
Common flag types map cleanly to delivery goals:
| Flag type | Purpose | Typical lifetime | Progressive delivery role |
|---|---|---|---|
| Release flag | Hide incomplete features | Days to weeks | Canary and percentage rollout |
| Ops flag | Kill switch, maintenance mode | Permanent | Instant rollback without redeploy |
| Experiment flag | A/B test variants | Weeks | Measure conversion before full release |
| Permission flag | Entitlements, plan tiers | Long-lived | Gradual access by customer segment |
For deeper Laravel-specific setup, see the dedicated Laravel Pennant feature flags implementation walkthrough. Small teams should also read feature flag rollout for small teams before buying enterprise tooling.
How do you implement feature flags in Laravel 13?
Laravel Pennant ships with Laravel 12 and remains the first choice for PHP teams on Laravel 13. It stores flag state in the database or Redis. You define features in a service provider and evaluate them in controllers, Blade, or middleware.
Install and define a feature
On Laravel 12+, Pennant is included. Publish the migration and define your first feature:
php artisan vendor:publish --provider="Laravel\Pennant\PennantServiceProvider"
php artisan migrate <?php
/* app/Providers/AppServiceProvider.php */
use App\Models\User;
use Laravel\Pennant\Feature;
public function boot(): void
{
Feature::define('new-checkout-flow', function (User $user) {
if (app()->environment('local', 'staging')) {
return true;
}
return $user->isInternalTester();
});
} Evaluate in application code
Never branch only in Blade. Always enforce business rules on the server.
<?php
/* app/Http/Controllers/CheckoutController.php */
use Laravel\Pennant\Feature;
public function show(Request $request)
{
if (Feature::active('new-checkout-flow')) {
return view('checkout.v2', [
'cart' => $request->user()->cart,
]);
}
return view('checkout.legacy', [
'cart' => $request->user()->cart,
]);
} In Blade, Pennant directives keep templates readable:
@feature('new-checkout-flow')
@include('checkout.partials.v2-summary')
@else
@include('checkout.partials.legacy-summary')
@endfeature Percentage rollout with Pennant
For progressive delivery, combine Pennant with a stable hash so the same user always gets the same variant:
Feature::define('new-checkout-flow', function (User $user) {
if (Feature::value('new-checkout-flow') === 'force-on') {
return true;
}
if (Feature::value('new-checkout-flow') === 'force-off') {
return false;
}
$bucket = crc32($user->id . 'new-checkout-flow') % 100;
return $bucket < (int) Feature::value('new-checkout-flow-percentage');
}); Activate for 5% from Artisan or a small admin panel:
php artisan pennant:activate new-checkout-flow --value=5 Official reference: Laravel Pennant documentation. Pair flag checks with Laravel feature testing best practices so both paths stay covered in CI.
What is the difference between feature flags and blue-green deployments?
Blue-green and canary deployments change which version of the entire application runs. Feature flags change behaviour inside a single running version. They solve different problems and work best together.
Blue-green swaps traffic between two full environments. Rollback means routing back to the old stack. That still takes minutes and may require database compatibility between versions.
Feature flags flip one behaviour inside the current deployment. Rollback is a config change. On a booking portal I shipped with Livewire, a payment-step flag let us disable a new Khalti flow in seconds when a gateway callback format changed.
Kubernetes teams often combine both. Progressive delivery with Argo Rollouts handles pod-level traffic splitting. Pennant handles user-level logic inside PHP. The feature branch deployment workflow article covers how Git strategy fits this model.
How do you roll out a feature safely with progressive delivery?
A repeatable rollout beats ad-hoc toggling. Use this sequence on every non-trivial feature.
- Define success metrics before coding. Pick error rate, p95 latency, conversion, or support tickets. Without a baseline, you cannot judge the rollout.
- Ship dark. Merge behind a default-off release flag. Run automated tests for both paths. Validate in staging with the flag forced on.
- Enable for internal users. Staff accounts or a allow-list email domain see the feature first. Fix obvious bugs before external exposure.
- Canary by percentage. Move 1%, then 5%, then 25%, then 50%, then 100%. Wait at each step until metrics stay stable.
- Watch payment and auth paths closely. These flows fail quietly until revenue drops. Add structured logging with the flag name in every branch.
- Remove the flag. After full rollout and a soak period, delete the old path. Flag debt is real technical debt.
On eCommerce work like Quick And Easy Nepalese Grocery, delivery-zone logic rolled out city by city using segment flags tied to postal codes. That limited support load when edge cases appeared.
Ops flags for instant rollback
Keep at least one ops flag per risky integration. Payment gateways, SMS providers, and third-party OCR APIs deserve a kill switch. When Khalti or eSewa changes a callback field, you disable the new handler without reverting Git.
Feature::define('khalti-v2-webhook', fn () => false); /* force off in emergency */
/* In webhook controller */
if (! Feature::active('khalti-v2-webhook')) {
return $this->handleLegacyKhalti($payload);
} Document every ops flag in your runbook. Future you will not remember why khalti-v2-webhook exists at 2 a.m.
Observability requirements
Progressive delivery without metrics is guesswork. Minimum viable observability:
- Log lines include
feature_flagandflag_valuefields. - APM traces tag active flags on the root span.
- Dashboards split error rate by flag state.
- Alerts fire when the flagged path error rate exceeds baseline by a set margin.
For JSON log payloads during debugging, the JSON formatter tool helps validate structure before you ship to production log aggregators.
Which feature flag tools fit PHP and Laravel teams in 2026?
Tool choice depends on team size, budget, and hosting model. Most Laravel shops I work with start with Pennant and only add SaaS when product or growth teams need a UI.
| Tool | Best for | Storage | Approx. cost |
|---|---|---|---|
| Laravel Pennant | Laravel 12/13 apps, small to mid teams | Database, Redis | Free (built-in) |
| LaunchDarkly | Multi-stack orgs, PM-owned rollouts | Managed SaaS | From ~USD 10/seat/month |
| Unleash (self-hosted) | Teams needing UI + on-prem control | PostgreSQL | Free OSS + hosting (~Rs 3,000/month, ~USD 22) |
| Flagsmith | API-first products, mobile + web | Managed or self-hosted | Free tier available |
| Custom Redis keys | Legacy PHP, quick kill switches | Redis | Free, high maintenance |
Pennant wins when your app is Laravel and your team already runs testing and optimization in CI. LaunchDarkly or Unleash make sense when marketing runs experiments without opening pull requests.
The Martin Fowler feature toggles article remains the best conceptual foundation. For vendor-neutral APIs, review the OpenFeature specification before committing to a proprietary SDK.
WordPress and WooCommerce projects rarely need Pennant. Use a plugin-level flag or a simple option in wp_options. For custom PHP outside Laravel, a Redis hash with TTL and an admin toggle page is enough for ops flags. Do not over-engineer.
What mistakes cause feature flag debt on production apps?
Flags help until they accumulate. I've cleaned up flag sprawl on long-running client codebases. These patterns cause the most pain.
Nesting flags inside flags
Three levels of nested if (Feature::active(...)) create combinatorial test paths. One release flag per feature. Compose at the route or controller level instead.
Long-lived release flags
A flag older than two sprints without a cleanup ticket is a forked codebase. Schedule flag removal in the same sprint as full rollout. Your future support and maintenance contract will cost less.
Client-side-only gating
JavaScript that hides a button does not protect the API. Always enforce flags server-side. Public APIs need the same check as Blade templates. See API rate limiting and abuse prevention for related hardening patterns.
No naming convention
Use release-checkout-v2, ops-khalti-webhook, experiment-hero-cta. Prefix by type. Random names like new-thing-2 survive for years and confuse every new developer.
Database migrations tied to flag state
Deploy migrations before enabling the flag, never after. The new code must run against the new schema while the flag is off. On legal-tech portals like Mijar Law Associates, document upload flags followed this order to avoid breaking existing client downloads.
For greenfield work, custom software development projects should include a flag lifecycle section in the technical spec from day one. Retrofitting flags into a monolith without tests is painful.
Key Takeaways
- Separate deploy from release: ship code with flags off, then turn behaviour on deliberately.
- Use Laravel Pennant on Laravel 12/13 with PHP 8.3+ for database- or Redis-backed flags without extra SaaS cost.
- Roll out by percentage with stable user hashing and metric gates at 1%, 5%, 25%, and 100%.
- Keep ops kill switches for payments, webhooks, and third-party APIs; document them in runbooks.
- Test both flag paths in CI and delete flags within two weeks of full rollout to avoid permanent forks.
- Combine infrastructure canaries (Argo, blue-green) with application-level flags for the safest progressive delivery stack.
People Also Ask
Are feature flags the same as A/B testing?
They overlap but serve different goals. A/B testing compares variants to pick a winner using experiment flags. Progressive delivery uses release flags to reduce rollout risk. You can run an A/B test as part of a progressive delivery plan, but not every flag is an experiment.
Do feature flags slow down Laravel applications?
Pennant caches resolved values in Redis or in-memory for the request. A single flag check adds microseconds. Problems appear when you evaluate dozens of flags per request or hit the database on every check without cache. Define flags once per request scope and cache aggressively.
Can you use feature flags without Kubernetes?
Yes. Most Laravel apps I deploy run on Ubuntu with Apache, PHP-FPM 8.3/8.4, and Deployer 7—not Kubernetes. Pennant works on any PHP host. Kubernetes adds pod-level traffic splitting; it is optional, not required for progressive delivery.
When should you remove a feature flag?
Remove release flags within one to two weeks after 100% rollout and stable metrics. Keep ops and permission flags as long as the business rule exists. If removing the flag feels risky, your test coverage for the new path is probably insufficient.
Ship safer releases starting with your next feature
Feature flags and progressive delivery turn release day from a gamble into a controlled process. Start with one release flag on your next Laravel feature, add percentage rollout, and wire basic error-rate monitoring before you widen the audience. The tooling is already in Laravel 13; the discipline is what separates teams that sleep on deploy night from those that do not.
Need help designing flag strategy, Pennant setup, or CI gates for a production app? Review the Adventure Third Pole Trek booking platform in the portfolio, or read Laravel 12 new features for framework context. For hands-on implementation on your stack, contact us about web development or API development—we integrate flags into deploy pipelines, not as an afterthought.
Frequently Asked Questions
0 Comments
Leave a comment
Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

