Feature Flagging for Monolith Apps

No Microservices Required — Feature Flags Without Re-architecture

Start Free Trial

Why Platforms Assume Microservices

Most enterprise feature flag platforms are designed for distributed systems with hundreds of services. Their documentation, SDKs, and examples assume you have:

  • Multiple services communicating via APIs
  • Separate frontend and backend deployments
  • Service mesh for cross-service communication
  • Different teams owning different services
Reality Check:

Most companies run monoliths. That's not a bad thing — it's often the right architecture. You shouldn't need microservices to use feature flags safely.

Monolith-Specific Workflows

1. Single Deployment Rollout

In a monolith, you deploy everything at once. Use flags to control which features activate after deployment.

// Deploy with flag OFF
if (flags.newCheckoutFlow) {
  return <NewCheckout />;
}
return <LegacyCheckout />;

// Later: flip flag ON in dashboard
// New code activates without redeploy

2. Database Migration Safety

Monoliths often share a single database. Use flags to switch between old and new schemas.

if (flags.useNewUserTable) {
  return db.query('SELECT * FROM users_v2');
}
return db.query('SELECT * FROM users');

3. Feature Isolation in One Codebase

Test risky features in production without affecting the entire app.

// Old code still runs for most users
if (flags.betaAIRecommendations && user.isBetaTester) {
  return getAIRecommendations(user);
}
return getStandardRecommendations(user);

Simple Patterns for Single Codebase

✅ Centralized Flag Loading

// Load once at app startup
const flags = await loadFlags();
app.locals.flags = flags;

Load flags once when your monolith starts. Share across routes via app context.

✅ Middleware Pattern

app.use((req, res, next) => {
  req.flags = app.locals.flags;
  next();
});

Make flags available to all routes without passing them explicitly.

✅ Template Helpers

<!-- In your views -->
{% if flags.showNewNav %}
  <NewNavigation />
{% endif %}

Use flags directly in server-rendered templates for UI changes.

✅ Background Job Flags

if (flags.useNewEmailService) {
  sendViaNewProvider(email);
} else {
  sendViaLegacyProvider(email);
}

Control background processes without separate deployments.

Examples in One Codebase

Rails Monolith

# config/initializers/feature_flags.rb
FLAGS = RemoteEnv.fetch(api_key: ENV['REMOTEENV_KEY'])

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  helper_method :feature_enabled?

  def feature_enabled?(flag)
    FLAGS[flag.to_s] == true
  end
end

# app/views/layouts/application.html.erb
<% if feature_enabled?(:new_dashboard) %>
  <%= render 'dashboard/new_layout' %>
<% else %>
  <%= render 'dashboard/legacy_layout' %>
<% end %>

Django Monolith

# settings.py
import requests
FEATURE_FLAGS = requests.get(
    'https://api.remoteenv.com/v1/flags',
    headers={'Authorization': f'Bearer {REMOTEENV_KEY}'}
).json()

# middleware.py
class FeatureFlagMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        request.flags = settings.FEATURE_FLAGS
        return self.get_response(request)

# views.py
def checkout(request):
    if request.flags.get('new_payment_flow'):
        return render(request, 'checkout/new.html')
    return render(request, 'checkout/legacy.html')

Monoliths Are Not Legacy

The industry has unfairly stigmatized monolithic architectures. The truth:

Monoliths Are Great For:

  • ✓ Small to medium teams (<50 engineers)
  • ✓ Rapid iteration and deployment
  • ✓ Shared data models
  • ✓ Easier debugging and testing
  • ✓ Lower operational complexity

Who Runs Monoliths:

  • • Shopify (Ruby on Rails monolith)
  • • GitHub (Rails monolith for years)
  • • Stack Overflow (ASP.NET monolith)
  • • Basecamp (Rails, proudly monolithic)

If it's good enough for billion-dollar companies, it's good enough for you.

Feature Flags Without Re-architecture

RemoteEnv works perfectly with your monolith. No microservices required.

Try RemoteEnv Free

Related Resources