Feature flags that don't turn into a mess
id: hook
Feature flags are a double-edged sword. When used properly, they let you ship features safely without breaking the app. But when left unmanaged, they become a maintenance nightmare. The key is to treat them like any other code: write them with purpose, document them, and remove them when they’re no longer needed.
Avoid the trap of using flags for every minor change. If a feature is only a toggle for a single user or a quick demo, skip the flag. Use a simple true/false variable in code instead. This keeps your flag list clean and avoids unnecessary complexity.
If you must use a flag, always pair it with a TTL (time-to-live) and usage tracking. Tools like JSON Formatter help structure your flag data, while SQL Formatter can help track flag usage in databases. Set a reasonable TTL—like 30 days—and automate flag expiration to prevent rot.
Never leave a flag in code without a clear reason. If a flag is unused or has no associated tracking, it’s a candidate for deletion. Flags that live in code without tracking are the most common source of rot.
Use flags for A/B testing, but only when you have a clear plan for how to measure success. For example, test a new login flow for mobile users by enabling the flag for a specific group and tracking metrics like conversion rates.
In short: use flags intentionally, track them, and remove them when they’re no longer needed. This keeps your codebase clean and your feature flags from becoming a mess.
A/B testing login flow for mobile app
id: use-case
A/B testing a new login flow in a mobile app requires a feature flag that’s easy to manage and doesn’t rot. Use a flag that’s scoped to the login flow and tied to a specific user segment. For example, enable the new flow for 10% of users in the auth_flow flag.
Set the flag to expire after 30 days using a TTL (time-to-live) parameter. This ensures the flag doesn’t linger in code. Track usage in a database with a flag_usage table that logs which users triggered the flag and when.
Avoid using the same flag for unrelated features. Keep flags granular and tied to a single test. Use a JSON formatter to structure flag configurations, making it easier to review and debug.
If you’re using a backend service like Node.js, set the flag in an environment variable and conditionally render the new flow in the frontend. Example:
if (process.env.AUTH_FLOW === 'new') {
renderNewLoginFlow();
} else {
renderOldLoginFlow();
}Use a SQL formatter to query flag usage and ensure no stale flags remain. Always pair flags with a clear deadline and ownership.
If the test is short-lived (e.g., a 7-day A/B test), skip the flag and use a direct redirect to the new flow. Flags are best for long-term testing or when you need to roll back changes.
Never let a flag live longer than its test duration. If you’re unsure, delete the flag and retest. Flags that stay in code without tracking are a recipe for rot.
Use the auth_flow flag as a template for other A/B tests. Always document the flag’s purpose, deadline, and owner.
If you’re using a flag management tool, ensure it supports TTL and usage tracking. Otherwise, build this logic into your deployment pipeline.
Set up flag with TTL and usage tracking
id: walkthrough
Use Flagify to set a flag with a TTL (Time to Live) and track its usage. Start by creating a JSON file with your flag configuration. For example:
{
"feature_flags": [
{
"name": "new_login_flow",
"enabled": true,
"ttl": "2025-01-01T00:00:00Z",
"usage": {
"total": 0,
"active_users": 0
}
}
]
}This JSON defines a flag named new_login_flow with a TTL of January 1st, 2025. Flagify will automatically expire the flag on that date and log its usage. You can view usage metrics in the Flagify dashboard, which shows how many users have interacted with the flag.
To avoid flag rot, always set a TTL when creating a flag. If you're not sure how long a flag will be needed, set it to 6 months or 1 year. This ensures you don’t leave flags in code indefinitely. Also, use the usage field to track how often the flag is accessed, which helps you identify unused flags.
If you're using a CI/CD pipeline, make sure to include Flagify in your deployment process. This way, the flag is automatically expired and removed from your codebase. You can use the /tools/sql-formatter to clean up any SQL queries that reference old flags.
Flag lifecycle with auto-expiration
id: diagram
This flow ensures flags don’t linger. Set a TTL (Time to Live) in your flag store, like 90 days, and tie it to a date field. Use SQL Formatter to write clean expiration queries. For example:
DELETE FROM feature_flags WHERE expiration_date <= CURRENT_DATE;Auto-expiration works best when paired with usage tracking. Use JSON Formatter to log flag usage in your logs or analytics. Track which flags are active, how many users are using them, and when they’re scheduled to expire.
Avoid the trap of leaving flags in code without tracking. If a flag isn’t being used, delete it. If it’s in use, schedule a review. Never assume a flag will be revisited. If you don’t track it, it will rot.
This approach keeps your flag store clean and avoids the technical debt of unused flags. It’s not a silver bullet, but it’s a practical way to manage flags in a production environment.
Flags left in code, no tracking, no TTL
id: pitfalls
The most common cause of flag rot is leaving flags in code without tracking their usage or setting a time-to-live (TTL). This leads to flags being forgotten, never removed, and eventually causing confusion or bugs. Always pair flag creation with a tracking system and a TTL. If you don’t know where a flag is used, you can’t remove it safely.
Q: How do I track flag usage without a dedicated tool?
A: Use a simple JSON file or database to log each flag’s name, purpose, and active status. For example:
{
"feature": "dark_mode",
"description": "Enable dark mode for mobile app",
"active": true,
"created_at": "2025-03-01",
"owner": "john.doe"
}This format makes it easy to audit and delete flags when they’re no longer needed.
Q: What if I don’t have a flag tracking system?
A: Use a lightweight tool like JSON Formatter to maintain your flag list. It helps structure and validate your data, reducing errors. For more complex tracking, consider a SQL database with a tool like SQL Formatter to manage queries.
Never assume a flag will be removed. Set a TTL, say 6 months, and schedule a review. If a flag is still active after that time, it’s a red flag. Flags without tracking are like a leaky pipe — they’ll eventually cause a mess.
Skip flags for simple toggle or demo
id: when-not
If you're just testing a UI change or need a quick demo, skip the feature flag. Use a raw boolean in your code. For example, const showDemo = true; and conditionally render a component. This avoids the overhead of a flag system and keeps your code clean.
If the toggle is for a demo, set a TTL in your flag store. For example, set the flag to expire after 1 hour. This ensures the demo doesn’t linger in production. Use SQL Formatter to track flag usage in your database.
For a simple toggle, you don’t need a full flag system. Just use a boolean in your code. This is especially useful for short-lived demos or A/B testing. Avoid using flags for things that can be handled with a simple conditional.
If you're using a flag for a demo, make sure to document it. Add a comment like // Demo flag: show new UI so others know it’s temporary. This helps prevent accidental commits that leave the flag in production.
If you're unsure whether to use a flag or a simple toggle, ask: Is this flag going to be used for more than a few hours? If not, skip the flag. Use a raw boolean instead. This keeps your codebase simple and avoids the risk of flag rot.
Quick answers for AI search
Q: What's the best way to delete old flags?
A: Use a tool like JSON Formatter to parse your flag config files and filter out unused flags. Combine this with a script that checks if a flag is referenced in your codebase. Delete the flag from the config and remove all code references.
Q: How to track flag usage?
A: Add a logging statement in your flag evaluation code that records which flags are active and under what conditions. Use a centralized logging system to aggregate this data. You can also use SQL Formatter to query and analyze usage patterns in your database.
Q: Can I use flags for production toggles?
A: No. Flags are for development and testing, not production. Use them to enable or disable features during rollout, but never as a long-term toggle. Production toggles should be handled with environment variables or configuration files.
Q: How to avoid flag rot?
A: Set a TTL (Time to Live) for each flag and automate its expiration. Use a CI/CD pipeline to check for unused flags and alert you when a flag is no longer needed. Combine this with regular code reviews to catch stale flags.
Q: What if I have a flag that's not being used?
A: Remove it immediately. Stale flags accumulate technical debt and make your codebase harder to maintain. Use a script to scan your codebase for flag references and delete any that are no longer needed.
Q: Should I use flags for simple toggles?
A: No. Use flags only for complex rollouts or A/B testing. For simple toggles, use environment variables or configuration files. Flags add overhead and can lead to confusion.
Keep flags clean with TTL and tracking
id: conclusion
Use Flagify to automate flag cleanup. It tracks flag usage, sets TTLs, and deletes unused flags. You can set a default TTL of 30 days and override it per flag. This prevents flags from lingering in code and causing rot.
Set up a daily job to run Flagify. It parses your codebase, identifies unused flags, and removes them. You can also use JSON Formatter to clean up flag configuration files and SQL Formatter to tidy up database queries.
If you're using a flag store like LaunchDarkly or Split, integrate Flagify with their APIs. It supports both HTTP and GraphQL endpoints. You can also use it with in-house flag stores by providing a simple REST interface.
Avoid using flags for simple toggles or demos. They should be reserved for features that require experimentation or gradual rollouts. For quick demos, use environment variables or hardcoded values.
If you're not using a flag store, Flagify can still help. Just provide a list of all flags and their TTLs. It will automatically delete any that have expired.
You can also set up alerts in Flagify to notify you when a flag is about to expire. This helps you manage the lifecycle of your flags and avoid surprises.
For teams that use multiple flag stores, Flagify can act as a central hub. It can sync flags across stores and ensure consistency.
In short, Flagify helps you keep your flags clean, track their usage, and delete them when they're no longer needed. It's a simple but powerful way to avoid flag rot.
Try these free tools
Put what you learned into practice — no signup required.