# Remote config and feature flags
Source: https://sovaria.in/docs/remote-config

Change what your app does without shipping an update: flags and values targeted by platform, version, country, user properties, audiences or a percentage, with versions, rollback and live updates.

Define parameters (a flag, a text, a number or JSON) with a default value and, optionally, values for **conditions**. Your edits are a draft; **publish** makes them a new immutable version that apps fetch. Every version is kept (up to your plan), so a bad change is one rollback away. Apps get only their own evaluated values: targeting rules, which can name users, never leave the server.

JavaScript:
```js
sov.config.setDefaults({ new_checkout: false, banner: 'Welcome' })
sov.config.settings({ storage: indexedDbStorage(), appVersion: '2.4.1', attributes: { plan: 'pro' } })
await sov.config.fetchAndActivate()          // at most every 12 hours unless a publish signal arrives

if (sov.config.getBool('new_checkout')) showNewCheckout()
const off = sov.config.onUpdate((keys) => rerender(keys))   // live, within a second of a publish
```

Swift:
```swift
sovaria.config.setDefaults(["new_checkout": false])
await sovaria.config.fetchAndActivate()
if sovaria.config.bool("new_checkout") { showNewCheckout() }
```

Kotlin:
```kotlin
sovaria.config.setDefaults(mapOf("new_checkout" to false))
sovaria.config.fetchAndActivate()
if (sovaria.config.getBoolean("new_checkout")) showNewCheckout()
```

Dart:
```dart
sovaria.config.setDefaults({'new_checkout': false});
await sovaria.config.fetchAndActivate();
if (sovaria.config.getBool('new_checkout')) showNewCheckout();
```

Python:
```python
client.remote_config.set_defaults({"new_checkout": False})
await client.remote_config.fetch_and_activate(attributes={"plan": "pro"})
client.remote_config.get_bool("new_checkout")
```

## Conditions

A condition is a rule tree. Combine rules with `all`, `any` and `not`. The first matching condition (lowest priority number) gives a parameter its value; with no match, the default applies.

| Rule | Example |
|---|---|
| Platform, country, language | `{"attr": "platform", "op": "in", "value": ["ios", "android"]}` |
| App version (semantic) | `{"attr": "app_version", "op": "semver_gte", "value": "2.3"}` |
| Your attributes (`attributes` in the SDK) | `{"attr": "props.plan", "op": "eq", "value": "pro"}` |
| Signed in / specific users | `{"attr": "signed_in", "op": "eq", "value": true}` · `{"users": ["<user id>"]}` |
| A Messaging audience (SQL on your tables) | `{"audience": "beta"}`: membership is refreshed every 15 minutes, never queried per request. |
| A sticky percentage | `{"percent": 10}`: the same users stay in as you raise it to 20, 50, 100. |

## Publishing safely

1. **Review the change** — Review and publish shows what changes against the live version and **who changes**: how many recently seen users would get a different value.
2. **Publish (or schedule)** — A publish is refused if someone else published since you looked. On paid plans you can pick a time instead.
3. **Apps update** — Apps listening with `onUpdate` refetch within a second (the signal carries only the version number). Others pick it up at their next fetch; an unchanged config costs a 304.
4. **Roll back** — Versions › Roll back publishes an older version again as a new one.

## Keep config in git

CLI:
```bash
sov config pull                      # writes sovaria/config.json (commit it)
sov config push                      # replace the draft from the file (nothing goes live)
sov config diff                      # in the pull request
sov config publish -m "Turn on new checkout" --yes   # on merge
sov config rollback 41 --yes
```

> **Warning:** Values are delivered to every app that asks: never store secrets in remote config. Keys named like secrets are refused; keep secrets in Project › Secrets and read them from a function.

## Plans and limits

|  | Free | Pro | Ultra | Team | Enterprise |
|---|---|---|---|---|---|
| Remote config parameters per project | 20 | 300 | 1,000 | 2,000 | 5,000 |
| Remote config conditions per project | 5 | 100 | 300 | 500 | 1,000 |
| Published remote config versions kept | 5 | 100 | 300 | 300 | 1,000 |
| Realtime remote config updates | — | ✓ | ✓ | ✓ | ✓ |
| Remote config fetches per month | 1,000,000 | 20,000,000 | 100,000,000 | 500,000,000 | 2,000,000,000 |
| Scheduled remote config publishes | — | ✓ | ✓ | ✓ | ✓ |
