Decoupling the deployment of a new feature from its release is basic hygiene for any modern engineering team. When you're a Banking-as-a-Service provider like Solaris, it's non-negotiable. We must be able to disable a new feature immediately if it doesn't perform as intended.
Our in-house feature flag solution was okay enough for basic features, but it couldn't keep up as we scaled. I recently led an initiative to find a proper replacement, and this post breaks down how we made our choice.
A quick primer on feature flags
Before feature flags, a bad bug meant rolling back your entire deploy—and if you were dealing with a massive monolith, that rollback could take hours. Feature flags are essentially kill switches for your code. They let you turn functionality on or off in production instantly, without new deployments.
Beyond simple toggles
When we started, a simple database-backed toggle system worked fine. But as Solaris grew, the binary approach became a massive bottleneck. We needed to turn features on for a single partner or our testers.
We also wanted to run A/B tests to measure the impact of a change before a complete roll-out.
How we chose a replacement
There's many solutions out there, more or less sophisticated. I boiled our requirements down to four hard rules to review the following solutions: LaunchDarkly, Optimizely, Split.io, Flagsmith, Unleash, GrowthBook, and Flipt.
1. Security and data residency
We're a German FinTech. Data residency isn't a suggestion; it's the law. We have to guarantee that user data and configuration context stay within Germany or the EU. This instantly killed off most SaaS-only providers. Letting sensitive evaluation data leave our infrastructure simply wasn't an option for our compliance team.
2. Budget
Let's be real: I had a zero-budget mandate for new external tooling. That immediately ruled out the "premium enterprise" tiers of tools like LaunchDarkly, Split, and Optimizely. They're great products, we used Optimizely at HelloFresh, and Split at Personio, but they were completely out of reach.
3. GitOps first
We didn't want our flags to continue living in a database. By treating configuration as code, our flags get the same pull request reviews, version history, and audit trails as the rest of our banking logic.
4. No vendor lock-in (OpenFeature)
I had to evaluate several feature flag systems in a short amount of time. I looked for compatibility with OpenFeature to be able to switch the underlying provider with minimal effort.
The Winner: GO Feature Flag
Here is how the contenders stacked up against our constraints:
| Solution | Strength | Why it didn't fit (at the time) |
|---|---|---|
| LaunchDarkly, Split, Optimizely | Feature-rich, best UI | Too expensive, and SaaS-only doesn't work for our data residency rules. |
| Unleash, Flagsmith | Robust, Open Source | Required managing extra databases and infrastructure we didn't want to maintain. |
| GrowthBook | Excellent for Analytics | Too focused on A/B testing; we wanted a GitOps-first workflow. |
| Flipt | High performance | GitOps support wasn't quite there yet compared to our winner. |
After walking the Principal Engineering group through these trade-offs, we decided to go with GO Feature Flag. It hit the sweet spot between power and simplicity
-
GitOps Native: No database required. Flags are just YAML files stored in GitHub and deployed to S3. This means they go through the exact same PR reviews and deployment pipelines as the rest of our code.
-
Granular targeting: We can write complex rules to target features by user ID, region, or any custom attribute we need.
-
Easy integrations: It supports custom "retrievers" (for pulling config from S3/GitHub) and "exporters" (for pushing metrics to Prometheus). Because of this, it slotted right into our existing observability stack on day one.
-
Lightweight and open source: It's a Go binary wrapped in a Docker container. We run it on AWS Fargate, and it consumes barely any resources.
Friction and Contributions
Taking an open-source tool through a POC usually means hitting some rough edges. And in this case, I ended up fixing a few of them myself.
The documentation hadn't quite caught up to the code yet. I found an incorrect volume mapping in the Docker setup, a broken Ruby SDK example using import instead of require, and a JavaScript SDK example that failed silently because the provider wasn't awaited before flag evaluation.
I also opened a couple of issues: a targetingKey mapping issue in the JavaScript SDK that caused targeting rules to silently fail, and a configuration bug that made it impossible to configure the app using environment variables alone—which is a must-have for our Fargate setup.
The real headache for us, though, was our WAF. It blocks any request that doesn't have a User-Agent header. Since this feature was missing, I added CustomHeaders support for Go, JavaScript, and Swift.
The maintainers were awesome throughout this. They reviewed things fast and merged quickly. When you're betting production infrastructure on an open-source project, an active maintainer team isn't a luxury. It's a requirement. The whole thing was actually pretty fun, and getting an envelope full of stickers in the mail was a nice bonus.

Driving Adoption at Solaris
Of course, none of this matters if people don't know how to use the new tool. To make the transition painless, I wrote reference implementations for every language in our stack. Go, Ruby, Java, Kotlin, Swift, and JavaScript.
I didn't just throw docs at people, either. I ran deep dives with the Principal Engineering group and team leads. After that, I was available for one-on-one and pair-programming.
Conclusion
At the end of the day, we didn't just swap out a toggle system. By insisting on OpenFeature and GitOps from the start, we built a workflow that actually matches how we ship code at Solaris. We can target features exactly where we need them now. The banking platform stays stable, and our devs don't slow down.
If you're looking at feature flags, my advice is simple: ignore the dashboard for a minute. Figure out how the tool actually fits your deployment pipeline. Check your compliance rules. And make sure it's not going to lock you into a vendor later on.
I wasn't around long enough to see company-wide adoption, but the initial rollout validated the architecture. By the time I left Solaris a couple of months later, three services had already adopted the new platform—a promising start for broader adoption across the organization.