Skip to content
PricingBlog
✨ Markdown

Sync service configuration

This page documents the config options for self-hosting the Electric sync engine.

Advanced only

You don't need to worry about this if you're using Electric Cloud.

Also, the only required configuration options are DATABASE_URL and ELECTRIC_SECRET.

Configuration

The sync engine is an Elixir application developed at packages/sync-service and published as a Docker image at electricsql/electric.

Configuration options can be provided as environment variables, e.g.:

shell
docker run \
    -e "DATABASE_URL=postgresql://..." \
    -e "ELECTRIC_DB_POOL_SIZE=10" \
    -p 3000:3000 \
    electricsql/electric

These are passed into the application via config/runtime.exs.

Database

DATABASE_URL

VariableDATABASE_URLrequired
Description

Postgres connection string. Used to connect to the Postgres database.

The connection string must be in the libpg Connection URI format of postgresql://[userspec@][hostspec][/dbname][?sslmode=<sslmode>].

The userspec section of the connection string specifies the database user that Electric connects to Postgres as. They must have the REPLICATION role.

For a secure connection, set the sslmode query parameter to require.

ExampleDATABASE_URL=postgresql://user:[email protected]:54321/electric

ELECTRIC_POOLED_DATABASE_URL

VariableELECTRIC_POOLED_DATABASE_URL
DefaultDATABASE_URL
Description

Postgres connection string. Used to connect to the Postgres database for anything but the replication, will default to the same as DATABASE_URL if not provided.

The connection string must be in the libpg Connection URI format of postgresql://[userspec@][hostspec][/dbname][?sslmode=<sslmode>].

The userspec section of the connection string specifies the database user that Electric connects to Postgres as. This can point to a connection pooler and does not need a REPLICATION role as it does not handle the replication.

This should point to the same instance as the main database URL, as Electric relies on transaction information for consistency reasons.

For a secure connection, set the sslmode query parameter to require.

This used to be called ELECTRIC_QUERY_DATABASE_URL, but that name is deprecated and will be removed in a future release.

ExampleELECTRIC_POOLED_DATABASE_URL=postgresql://user:[email protected]:54321/electric

ELECTRIC_DATABASE_USE_IPV6

VariableELECTRIC_DATABASE_USE_IPV6
Defaultfalse
Description

Set to true to prioritise connecting to the database over IPv6. Electric will fall back to an IPv4 DNS lookup if the IPv6 lookup fails.

ExampleELECTRIC_DATABASE_USE_IPV6=true

ELECTRIC_DB_POOL_SIZE

VariableELECTRIC_DB_POOL_SIZE
Default20
Description

How many connections Electric opens as a pool for handling shape queries.

ExampleELECTRIC_DB_POOL_SIZE=10

ELECTRIC_DATABASE_CA_CERTIFICATE_FILE

VariableELECTRIC_DATABASE_CA_CERTIFICATE_FILEoptional
Description

The path on local disk to a file containing trusted certificate(s) that Electric will use to verify the database server identity.

Trusted certificates are those that have been signed by trusted certificate authorities (CA); they are also known as root certificates. Every operating system and most web browsers include a bundle of well-known root certificates (aka CA store). You can instruct Electric to use the default bundle provided by your OS by specifying an absolute path to it. This page from Neon lists the typical locations for different operating systems.

Some managed Postgres providers such as Supabase and DigitalOcean use a self-signed root certificate that won't be found in OS-specific CA stores. If you're using one of those, download the trusted certificate from the provider's website and put it somewhere on your local disk where Electric can access it.

Certificate verification and sslmode

Electric doesn't support sslmode=verify-ca or sslmode=verify-full query params in DATABASE_URL. Those values are specific to psql. When you configure Electric with a trusted certificate file, it will always try to verify the server identity and will refuse to open a database connection if the verification does not succeed.

Note, however, that setting sslmode=disable in DATABASE_URL and enabling certificate verification at the same time will result in a startup error.

ExampleELECTRIC_DATABASE_CA_CERTIFICATE_FILE=/root/.postgresql/root.crt

ELECTRIC_REPLICATION_STREAM_ID

VariableELECTRIC_REPLICATION_STREAM_ID
Defaultdefault
Description

Suffix for the logical replication publication and slot name.

ExampleELECTRIC_REPLICATION_STREAM_ID=my-app

CLEANUP_REPLICATION_SLOTS_ON_SHUTDOWN

VariableCLEANUP_REPLICATION_SLOTS_ON_SHUTDOWN
Defaultfalse
Description

When set to true, Electric creates a temporary replication slot that is automatically dropped when the database connection closes. This is useful for ephemeral deployments where each container has its own storage and replication slots don't need to persist across restarts.

Unclean shutdowns cause shape rotations

If Electric crashes or loses its database connection (e.g., during a network partition), the temporary slot is lost. The next instance starts with a fresh slot and clients connected to old shapes will receive 409 (must-refetch) responses, requiring a full resync.

See the Upgrading guide for more context on using temporary slots.

ExampleCLEANUP_REPLICATION_SLOTS_ON_SHUTDOWN=true

ELECTRIC_TEMPORARY_REPLICATION_SLOT_USE_RANDOM_NAME

VariableELECTRIC_TEMPORARY_REPLICATION_SLOT_USE_RANDOM_NAME
Defaultfalse
Description

When used with CLEANUP_REPLICATION_SLOTS_ON_SHUTDOWN=true, generates a random replication slot name instead of the deterministic name based on ELECTRIC_REPLICATION_STREAM_ID. This avoids slot name conflicts when multiple instances run concurrently during rolling deploys.

Has no effect unless CLEANUP_REPLICATION_SLOTS_ON_SHUTDOWN is also set to true.

ExampleELECTRIC_TEMPORARY_REPLICATION_SLOT_USE_RANDOM_NAME=true

ELECTRIC_REPLICATION_IDLE_TIMEOUT

VariableELECTRIC_REPLICATION_IDLE_TIMEOUT
Default0
Description

After seeing no activity on the logical replication stream for this long, Electric will close all of its database connections. This allows the database server to scale-to-zero on supported providers.

While Electric is in the scaled-down mode, an incoming shape request will cause it to reopen database connections and restart the logical replication stream. The request itself will be held until it can be processed as usual to return a proper response.

The default value is 0, meaning the connection scaling down is disabled and Electric will keep its database connections open permanently.

Important note on WAL growth

Avoid setting this timeout if your database sees constant or frequent writes.

When Electric isn't streaming from the database, its replication slot is inactive. Postgres will continue to retain WAL files needed for the slot, since they are required to resume replication later. Over time, this can cause storage growth proportional to the volume of writes on the primary database, regardless of whether those writes target tables for which Electric has active shapes or not.

Once Electric reconnects and replication catches up, Postgres will automatically discard the no-longer-needed WAL segments. However, if the inactivity period is too long, the accumulated WAL may exceed available disk space, potentially interrupting database operations.

ExampleELECTRIC_REPLICATION_IDLE_TIMEOUT=5min

ELECTRIC_MANUAL_TABLE_PUBLISHING

VariableELECTRIC_MANUAL_TABLE_PUBLISHING
Defaultfalse
Description

Set to true to disable automatic addition/removal of database tables from the publication in Postgres.

In order to receive realtime updates as soon as they are committed in Postgres, Electric maintains a publication inside the database and automatically adds tables to it for which shape subscriptions are established. This only works if Electric's database role owns the table or is granted the group role that owns the table.

If your permissions policies prevent Electric from using a role that can alter application tables, set this setting to true and manually add each table to the publication. See the Manual Mode Setup guide for complete setup instructions, or use the following minimal steps:

sql
BEGIN;
ALTER PUBLICATION electric_publication_default ADD TABLE <my table>;
ALTER TABLE <my table> REPLICA IDENTITY FULL;
COMMIT;

before requesting a new shape for that table.

ExampleELECTRIC_MANUAL_TABLE_PUBLISHING=true

Electric

ELECTRIC_SECRET

VariableELECTRIC_SECRETrequired
Description

Secret for shape requests to the HTTP API. This is required unless ELECTRIC_INSECURE is set to true. By default, the Electric API is public and authorises all shape requests against this secret. More details are available in the security guide.

ExampleELECTRIC_SECRET=1U6ItbhoQb4kGUU5wXBLbxvNf

ELECTRIC_INSECURE

VariableELECTRIC_INSECURE
Defaultfalse
Description

When set to true, runs Electric in insecure mode and does not require an ELECTRIC_SECRET. Use with caution. API requests are unprotected and may risk exposing your database. Good for development environments. If used in production, make sure to lock down access to Electric.

ExampleELECTRIC_INSECURE=true

ELECTRIC_INSTANCE_ID

VariableELECTRIC_INSTANCE_ID
DefaultElectric.Utils.uuid4()
Description

A unique identifier for the Electric instance. Defaults to a randomly generated UUID.

ExampleELECTRIC_INSTANCE_ID=some-unique-instance-identifier

ELECTRIC_SERVICE_NAME

VariableELECTRIC_SERVICE_NAME
Defaultelectric
Description

Name of the electric service. Used as a resource name in OTEL traces and metrics.

ExampleELECTRIC_SERVICE_NAME=my-electric-service

ELECTRIC_LISTEN_ON_IPV6

VariableELECTRIC_LISTEN_ON_IPV6
Defaultfalse
Description

By default, Electric binds to IPv4. Enable this to listen on IPv6 addresses as well.

ExampleELECTRIC_LISTEN_ON_IPV6=true

ELECTRIC_TCP_SEND_TIMEOUT

VariableELECTRIC_TCP_SEND_TIMEOUT
Default30s
Description Timeout for sending a response chunk back to the client. Defaults to 30 seconds.

Slow response processing on the client or bandwidth restristrictions can cause TCP backpressure leading to the error message:

Error while streaming response: :timeout

This environment variable increases this timeout.

ExampleELECTRIC_TCP_SEND_TIMEOUT=60s

ELECTRIC_SHAPE_CHUNK_BYTES_THRESHOLD

VariableELECTRIC_SHAPE_CHUNK_BYTES_THRESHOLD
Default10485760
Description

Limit the maximum size of a shape log response, to ensure they are cached by upstream caches. Defaults to 10MB (10 _ 1024 _ 1024).

See #1581 for context.

ExampleELECTRIC_SHAPE_CHUNK_BYTES_THRESHOLD=20971520

ELECTRIC_PORT

VariableELECTRIC_PORT
Default3000
Description

Port that the HTTP API is exposed on.

ExampleELECTRIC_PORT=8080

ELECTRIC_SHAPE_SUSPEND_CONSUMER

VariableELECTRIC_SHAPE_SUSPEND_CONSUMER
Defaultfalse
Description

Whether to terminate idle shape consumer processes after ELECTRIC_SHAPE_HIBERNATE_AFTER seconds. This saves on memory at the cost of slightly higher CPU usage. When receiving a transaction that contains changes matching a given shape, a consumer process is started to handle the update. If more transactions matching the shape appear within the time defined by ELECTRIC_SHAPE_HIBERNATE_AFTER then the consumer will remain active, if not it will be terminated.

If set to false the consumer processes will hibernate instead of terminating, meaning they still occupy some memory but are inactive until passed transaction operations to process.

If you enable this feature then you should configure ELECTRIC_SHAPE_HIBERNATE_AFTER to match the usage patterns of your application to avoid unnecessary process churn.

ExampleELECTRIC_SHAPE_SUSPEND_CONSUMER=true

ELECTRIC_SHAPE_HIBERNATE_AFTER

VariableELECTRIC_SHAPE_HIBERNATE_AFTER
Default30s
Description

The amount of time a consumer process remains active without receiving transaction operations before either hibernating or terminating (if ELECTRIC_SHAPE_SUSPEND_CONSUMER is true).

ExampleELECTRIC_SHAPE_HIBERNATE_AFTER=5000ms

ELECTRIC_SHAPE_DB_EXCLUSIVE_MODE

VariableELECTRIC_SHAPE_DB_EXCLUSIVE_MODE
Defaultfalse
Description

Run the SQLite database holding active shape data over a single read-write connection, rather than a single writer and multiple reader connections. This avoids corruption issues when holding shape data on an NFS share (such as AWS EFS). Set this to true and ELECTRIC_SHAPE_DB_STORAGE_DIR=:memory: to use an in-memory database.

ExampleELECTRIC_SHAPE_DB_EXCLUSIVE_MODE=true

ELECTRIC_SHAPE_DB_STORAGE_DIR

VariableELECTRIC_SHAPE_DB_STORAGE_DIR
Default$ELECTRIC_STORAGE_DIR
Description

The base path for the shapes SQLite database. Set this to a local, non-networked drive, for consistency and performance reasons when hosting shape data on a network volume, such as AWS EFS. This is an alternative to ELECTRIC_SHAPE_DB_EXCLUSIVE_MODE when a single read-write connection does not provide enough performance. Note that if the ELECTRIC_SHAPE_DB_STORAGE_DIR is ephemeral, e.g. instance specific, then on a re-deployment the shape log data in $ELECTRIC_STORAGE_DIR (hosted on EFS) will be ignored by the system, which will start empty.

Enable ELECTRIC_SHAPE_DB_EXCLUSIVE_MODE and set ELECTRIC_SHAPE_DB_EXCLUSIVE_MODE=:memory: to use an ephemeral in-memory shape database.

ExampleELECTRIC_SHAPE_DB_STORAGE_DIR=/var/db/electric

ELECTRIC_SHAPE_DB_SYNCHRONOUS

VariableELECTRIC_SHAPE_DB_SYNCHRONOUS
DefaultOFF
Description

The value of the synchronous PRAGMA set on every connection to the shape db.

ExampleELECTRIC_SHAPE_DB_SYNCHRONOUS=NORMAL

ELECTRIC_SHAPE_DB_CACHE_SIZE

VariableELECTRIC_SHAPE_DB_CACHE_SIZE
Default4096KiB
Description

The value of the cache_size PRAGMA set on every connection to the shape db. Higher values will result in more memory usage but improved performance. Accepts values in bytes, or with a suffix such as "1024KB", "500KiB", "5MB", "8MiB", etc.

ExampleELECTRIC_SHAPE_DB_CACHE_SIZE=8MiB

ELECTRIC_SHAPE_DB_ENABLE_STATS

VariableELECTRIC_SHAPE_DB_ENABLE_STATS
Defaultfalse
Description

Set ELECTRIC_SHAPE_DB_ENABLE_STATS=true to enable collection of statistics for the SQLite shape db system.

ExampleELECTRIC_SHAPE_DB_ENABLE_STATS=true

ELECTRIC_SHAPE_DB_ENABLE_MEMORY_STATS

VariableELECTRIC_SHAPE_DB_ENABLE_MEMORY_STATS
Defaultfalse
Description

Set ELECTRIC_SHAPE_DB_ENABLE_STATS=true and ELECTRIC_SHAPE_DB_ENABLE_MEMORY_STATS=true to enable collection of memory usage statistics for the SQLite shape db system. Requires the loading of a pre-compiled extension so may cause issues on some architectures and is disabled by default for stability reasons.

ExampleELECTRIC_SHAPE_DB_ENABLE_MEMORY_STATS=true

ELECTRIC_MAX_CONCURRENT_REQUESTS

VariableELECTRIC_MAX_CONCURRENT_REQUESTS
Default{"initial": 300, "existing": 10000}
Description

Maximum number of concurrent HTTP requests Electric will serve, as a JSON object with two keys:

  • initial — limit for initial sync requests (requests with offset=-1). Default: 300.
  • existing — limit for ongoing requests (live long-polls and catch-up requests). Default: 10000.

When the limit is exceeded, Electric responds with 503 and a Retry-After header. See the troubleshooting guide for details.

Each live=true long-poll request holds the connection open for up to 20 seconds, so the effective limit is determined by the number of concurrent shape subscriptions across all connected clients. Putting a CDN with request collapsing in front of Electric is the recommended way to handle high connection counts.

ExampleELECTRIC_MAX_CONCURRENT_REQUESTS={"initial": 500, "existing": 30000}

ELECTRIC_MAX_SHAPES

VariableELECTRIC_MAX_SHAPESoptional
Description

Maximum number of shapes that Electric will serve concurrently. When unset (the default), there is no limit on the number of shapes.

When set, Electric periodically evicts the least recently used shapes to stay within the limit.

Clients subscribed to an expired shape will receive a 409 Conflict response, prompting them to create a new shape subscription with a fresh initial sync.

This replaces the previous ELECTRIC_EXPERIMENTAL_MAX_SHAPES environment variable, which is deprecated and will be removed in a future release.

ExampleELECTRIC_MAX_SHAPES=10000

ELECTRIC_CONSUMER_PARTITIONS

VariableELECTRIC_CONSUMER_PARTITIONSoptional
Description

Consumer processes are partitioned across some number of supervisors to improve launch and shutdown time. If ELECTRIC_MAX_SHAPES is set the number of partitions will scale to fit this maximum but if not, it defaults to the number of CPU cores. If you want to improve shutdown performance without setting an upper limit on the number of shapes, then set this to roughly your expected number of shapes / 4000.

ExampleELECTRIC_CONSUMER_PARTITIONS=128

Feature Flags

Feature flags enable advanced features and staged rollouts for capabilities that are not yet enabled by default in production.

ELECTRIC_FEATURE_FLAGS

VariableELECTRIC_FEATURE_FLAGS
Description

Available flags:

  • allow_subqueries - Enables preview subquery support in shape WHERE clauses
  • tagged_subqueries - Enables preview incremental subquery move handling, including compound boolean expressions with compatible clients
ExampleELECTRIC_FEATURE_FLAGS=allow_subqueries,tagged_subqueries

Client compatibility

Electric 1.6's incremental handling for compound subquery expressions changes the client protocol. Upgrade clients before enabling the server rollout. TanStack DB clients need @tanstack/db >= 0.6.2 and @tanstack/electric-db-collection >= 0.3.0.

allow_subqueries

Enables support for subqueries in the WHERE clause of shape definitions. When enabled, you can use queries in the form:

sql
WHERE id IN (SELECT user_id FROM memberships WHERE org_id = 'org_123')

This allows creating shapes that filter based on related data in other tables, enabling more complex data synchronization patterns.

Status: Preview. Disabled by default in production until enabled with ELECTRIC_FEATURE_FLAGS.

tagged_subqueries

Subqueries create dependency trees between shapes. This flag enables incremental move handling when dependency rows change, including compound WHERE expressions that combine subqueries with AND, OR, and NOT.

Before Electric 1.6, complex boolean combinations around subqueries could still invalidate the shape and return a 409 on a move. With this flag enabled and compatible clients, those changes are reconciled in-stream instead.

See discussion #2931 for more details about this feature.

Status: Preview rollout flag for subquery move handling. Disabled by default in production. Requires allow_subqueries to be enabled.

Caching

ELECTRIC_CACHE_MAX_AGE

VariableELECTRIC_CACHE_MAX_AGE
Default60
Description

Default max-age for the cache headers of the HTTP API.

ExampleELECTRIC_CACHE_MAX_AGE=5

ELECTRIC_CACHE_STALE_AGE

VariableELECTRIC_CACHE_STALE_AGE
Default300
Description

Default stale-age for the cache headers of the HTTP API.

ExampleELECTRIC_CACHE_STALE_AGE=5

Storage

ELECTRIC_PERSISTENT_STATE

VariableELECTRIC_PERSISTENT_STATE
DefaultFILE
Description

Where to store shape metadata. Defaults to storing on the filesystem. If provided must be one of MEMORY or FILE.

ExampleELECTRIC_PERSISTENT_STATE=MEMORY

ELECTRIC_STORAGE

VariableELECTRIC_STORAGE
DefaultFAST_FILE
Description

Where to store shape logs. Defaults to storing on the filesystem. If provided must be one of MEMORY or FAST_FILE.

ExampleELECTRIC_STORAGE=MEMORY

ELECTRIC_STORAGE_DIR

VariableELECTRIC_STORAGE_DIR
Default./persistent
Description

Path to root folder for storing data on the filesystem.

ExampleELECTRIC_STORAGE_DIR=/var/example

Telemetry

These environment variables allow configuration of metric and trace export for visibility into performance of the Electric instance.

ELECTRIC_OTLP_ENDPOINT

VariableELECTRIC_OTLP_ENDPOINToptional
Description

Set an OpenTelemetry endpoint URL to enable telemetry.

ExampleELECTRIC_OTLP_ENDPOINT=https://example.com

ELECTRIC_OTEL_DEBUG

VariableELECTRIC_OTEL_DEBUG
Defaultfalse
Description

Debug tracing by printing spans to stdout, without batching.

ExampleELECTRIC_OTEL_DEBUG=true

ELECTRIC_HNY_API_KEY

VariableELECTRIC_HNY_API_KEYoptional
Description

Honeycomb.io api key. Specify along with HNY_DATASET to export traces directly to Honeycomb, without the need to run an OpenTelemetry Collector.

ExampleELECTRIC_HNY_API_KEY=your-api-key

ELECTRIC_HNY_DATASET

VariableELECTRIC_HNY_DATASEToptional
Description

Name of your Honeycomb Dataset.

ExampleELECTRIC_HNY_DATASET=your-dataset-name

ELECTRIC_PROMETHEUS_PORT

VariableELECTRIC_PROMETHEUS_PORToptional
Description

Expose a prometheus reporter for telemetry data on the specified port.

ExampleELECTRIC_PROMETHEUS_PORT=9090

ELECTRIC_STATSD_HOST

VariableELECTRIC_STATSD_HOSToptional
Description

Enable sending telemetry data to a StatsD reporting endpoint.

ExampleELECTRIC_STATSD_HOST=https://example.com

SENTRY_DSN

VariableSENTRY_DSNoptional
Description

Set a Sentry DSN to enable error tracking via the Sentry Elixir SDK. When configured, Electric will automatically capture errors and report them to your Sentry project.

This requires Electric to be built with telemetry enabled (which is the case for the official Docker images).

ExampleSENTRY_DSN=https://[email protected]/0

Logging

ELECTRIC_LOG_LEVEL

VariableELECTRIC_LOG_LEVELoptional
Description

Verbosity of Electric's log output.

Available levels, in the order of increasing verbosity:

  • error
  • warning
  • info
  • debug
ExampleELECTRIC_LOG_LEVEL=debug

ELECTRIC_LOG_COLORS

VariableELECTRIC_LOG_COLORSoptional
Description

Enable or disable ANSI coloring of Electric's log output.

By default, coloring is enabled when Electric's stdout is connected to a terminal. This may be undesirable in certain runtime environments, such as AWS which displays ANSI color codes using escape sequences and may incorrectly split log entries into multiple lines.

ExampleELECTRIC_LOG_COLORS=false

ELECTRIC_LOG_OTP_REPORTS

VariableELECTRIC_LOG_OTP_REPORTS
Defaultfalse
Description

Enable OTP SASL reporting at runtime.

ExampleELECTRIC_LOG_OTP_REPORTS=true

Usage reporting

ELECTRIC_USAGE_REPORTING

These environment variables allow configuration of anonymous usage data reporting back to https://electric-sql.com

VariableELECTRIC_USAGE_REPORTING
Defaulttrue
Description

Configure anonymous usage data about the instance being sent to a central checkpoint service. Collected information is anonymised and doesn't contain any information from the replicated data. You can read more about it in our telemetry docs.

ExampleELECTRIC_USAGE_REPORTING=true