# `Electric.Config`
[🔗](https://github.com/electric-sql/electric/tree/%40core/sync-service%401.5.1/packages/sync-service/lib/electric/config.ex#L34)

# `instance_id`

```elixir
@type instance_id() :: String.t()
```

# `default`

# `fetch_env!`

```elixir
@spec fetch_env!(Application.key()) :: Application.value()
```

# `get_env`

```elixir
@spec get_env(Application.key()) :: Application.value()
```

# `get_env_lazy`

# `installation_id!`

```elixir
@spec installation_id!(term()) :: binary() | no_return()
```

# `min_replication_idle_timeout`

```elixir
@spec min_replication_idle_timeout() :: pos_integer()
```

The minimum allowed time before Electric can close database connections due to the
replication stream inactivity.

This is to prevent churn where connection and replication supervisors would restart too frequently.

The scale-to-zero feature of managed providers like Neon takes on the order of minutes before
deciding that an idle database can be scaled down.

# `min_replication_idle_timeout_in_seconds`

# `parse_comma_separated_set!`

Parse a comma-separated string into a MapSet of trimmed values.

## Examples

    iex> parse_comma_separated_set!("foo,bar,baz")
    MapSet.new(["bar", "baz", "foo"])

    iex> parse_comma_separated_set!(" foo , bar , baz ")
    MapSet.new(["bar", "baz", "foo"])

    iex> parse_comma_separated_set!("single")
    MapSet.new(["single"])

    iex> parse_comma_separated_set!(",,,")
    MapSet.new()

    iex> parse_comma_separated_set!("")
    MapSet.new()

# `parse_feature_flags`

# `parse_human_readable_size`

```elixir
@spec parse_human_readable_size(binary()) :: {:ok, pos_integer()} | {:error, binary()}
```

Parse human-readable memory/storage size string into bytes.

## Examples

  iex> parse_human_readable_size("1GiB")
  {:ok, 1073741824}

  iex> parse_human_readable_size("2.23GB")
  {:ok, 2_230_000_000}

  iex> parse_human_readable_size("256MiB")
  {:ok, 268435456}

  iex> parse_human_readable_size("377MB")
  {:ok, 377_000_000}

  iex> parse_human_readable_size("430KiB")
  {:ok, 440320}

  iex> parse_human_readable_size("142888KB")
  {:ok, 142_888_000}

  iex> parse_human_readable_size("123456789")
  {:ok, 123_456_789}

  iex> parse_human_readable_size("")
  {:error, ~S'invalid size unit: "". Must be one of ["KB", "KiB", "MB", "MiB", "GB", "GiB"]'}

  iex> parse_human_readable_size("foo")
  {:error, ~S'invalid size unit: "foo". Must be one of ["KB", "KiB", "MB", "MiB", "GB", "GiB"]'}

# `parse_human_readable_size!`

# `parse_human_readable_time`

```elixir
@spec parse_human_readable_time(binary() | nil) ::
  {:ok, pos_integer()} | {:error, binary()}
```

# `parse_human_readable_time!`

# `parse_legacy_top_process_count`

```elixir
@spec parse_legacy_top_process_count(binary()) ::
  {:ok, {:count, pos_integer()}} | {:error, binary()}
```

Parse the deprecated ELECTRIC_TELEMETRY_TOP_PROCESS_COUNT value (a plain integer)
into a `{:count, N}` tuple.

## Examples

  iex> parse_legacy_top_process_count("10")
  {:ok, {:count, 10}}

  iex> parse_legacy_top_process_count("0")
  {:error, "count value must be a positive integer, got: 0"}

# `parse_legacy_top_process_count!`

# `parse_log_level`

```elixir
@spec parse_log_level(binary()) :: {:ok, Logger.level()} | {:error, binary()}
```

# `parse_log_level!`

# `parse_postgresql_uri`

```elixir
@spec parse_postgresql_uri(binary()) :: {:ok, keyword()} | {:error, binary()}
```

Parse a PostgreSQL URI into a keyword list.

## Examples

    iex> parse_postgresql_uri("postgresql://postgres:password@example.com/app-db") |> deobfuscate()
    {:ok, [
      hostname: "example.com",
      port: 5432,
      database: "app-db",
      username: "postgres",
      password: "password",
    ]}

    iex> parse_postgresql_uri("postgresql://electric@192.168.111.33:81/__shadow")
    {:ok, [
      hostname: "192.168.111.33",
      port: 81,
      database: "__shadow",
      username: "electric"
    ]}

    iex> parse_postgresql_uri("postgresql://pg@[2001:db8::1234]:4321")
    {:ok, [
      hostname: "2001:db8::1234",
      port: 4321,
      database: "pg",
      username: "pg"
    ]}

    iex> parse_postgresql_uri("postgresql://user@localhost:5433/")
    {:ok, [
      hostname: "localhost",
      port: 5433,
      database: "user",
      username: "user"
    ]}

    iex> parse_postgresql_uri("postgresql://user%2Btesting%40gmail.com:weird%2Fpassword@localhost:5433/my%2Bdb%2Bname") |> deobfuscate()
    {:ok, [
      hostname: "localhost",
      port: 5433,
      database: "my+db+name",
      username: "user+testing@gmail.com",
      password: "weird/password"
    ]}

    iex> parse_postgresql_uri("postgres://super_user@localhost:7801/postgres?sslmode=disable")
    {:ok, [
      hostname: "localhost",
      port: 7801,
      database: "postgres",
      username: "super_user",
      sslmode: :disable
    ]}

    iex> parse_postgresql_uri("postgres://super_user@localhost:7801/postgres?sslmode=require")
    {:ok, [
      hostname: "localhost",
      port: 7801,
      database: "postgres",
      username: "super_user",
      sslmode: :require
    ]}

    iex> parse_postgresql_uri("postgres://super_user@localhost:7801/postgres?sslmode=yesplease")
    {:error, "invalid \"sslmode\" value: \"yesplease\""}

    iex> parse_postgresql_uri("postgrex://localhost")
    {:error, "invalid URL scheme: \"postgrex\""}

    iex> parse_postgresql_uri("postgresql://localhost")
    {:error, "invalid or missing username"}

    iex> parse_postgresql_uri("postgresql://:@localhost")
    {:error, "invalid or missing username"}

    iex> parse_postgresql_uri("postgresql://:password@localhost")
    {:error, "invalid or missing username"}

    iex> parse_postgresql_uri("postgresql://user:password")
    {:error, "invalid or missing username"}

    iex> parse_postgresql_uri("postgresql://user:password@")
    {:error, "missing host"}

    iex> parse_postgresql_uri("postgresql://user@localhost:5433/mydb?opts=-c%20synchronous_commit%3Doff&foo=bar")
    {:ok, [
      hostname: "localhost",
      port: 5433,
      database: "mydb",
      username: "user"
    ]}

    iex> parse_postgresql_uri("postgres://user:pass@localhost:5432/db?uselibpqcompat=true") |> deobfuscate()
    {:ok, [
      hostname: "localhost",
      port: 5432,
      database: "db",
      username: "user",
      password: "pass"
    ]}

    iex> parse_postgresql_uri("postgres://user:pass@localhost:5432/db?uselibpqcompat=true&sslmode=require") |> deobfuscate()
    {:ok, [
      hostname: "localhost",
      port: 5432,
      database: "db",
      username: "user",
      password: "pass",
      sslmode: :require
    ]}

    iex> parse_postgresql_uri("postgresql://electric@localhost/db?replication=database")
    {:error, "unsupported \"replication\" query option. Electric opens both a replication connection and regular connections to Postgres as needed"}

    iex> parse_postgresql_uri("postgresql://electric@localhost/db?replication=off")
    {:error, "unsupported \"replication\" query option. Electric opens both a replication connection and regular connections to Postgres as needed"}

# `parse_postgresql_uri!`

# `parse_spawn_opts!`

Parse `spawn_opts` from environment variable to keyword list suitable for passing to `GenServer.start_link/2`

## Examples

    iex> parse_spawn_opts!(~S({"shape_log_collector":{"min_heap_size":234,"min_bin_vheap_size":123,"message_queue_data":"on_heap","priority":"high","fullsweep_after":104}}))
    %{shape_log_collector: [fullsweep_after: 104, message_queue_data: :on_heap, min_bin_vheap_size: 123, min_heap_size: 234, priority: :high]}

    iex> parse_spawn_opts!(~S({"shape_log_collector":{"monkey":123,"message_queue_data":"on_fire","min_bin_vheap_size":-1,"priority":"high"}}))
    %{shape_log_collector: [priority: :high]}

    iex> parse_spawn_opts!("")
    %{}

    iex> parse_spawn_opts!("{}")
    %{}

# `parse_telemetry_url`

```elixir
@spec parse_telemetry_url(binary()) :: {:ok, binary()} | {:error, binary()}
```

# `parse_telemetry_url!`

# `parse_top_process_limit`

```elixir
@spec parse_top_process_limit(binary()) ::
  {:ok, {:count, pos_integer()} | {:mem_percent, 1..100}} | {:error, binary()}
```

Parse a top process limit string into a tagged tuple.

## Examples

  iex> parse_top_process_limit("count:5")
  {:ok, {:count, 5}}

  iex> parse_top_process_limit("mem_percent:80")
  {:ok, {:mem_percent, 80}}

  iex> parse_top_process_limit("mem_percent:0")
  {:error, "mem_percent value must be between 1 and 100, got: 0"}

  iex> parse_top_process_limit("count:0")
  {:error, "count value must be a positive integer, got: 0"}

  iex> parse_top_process_limit("foo")
  {:error, ~S'invalid top process limit: "foo". Expected format: count:<N> or mem_percent:<N>'}

# `parse_top_process_limit!`

# `persist_installation_id`

```elixir
@spec persist_installation_id(term(), binary()) :: instance_id()
```

# `persistent_kv`

# `validate_security_config!`

---

*Consult [api-reference.md](api-reference.md) for complete listing*
