Network configuration

EventStoreDB provides two interfaces:

  • HTTP(S) for gRPC communication and REST APIs
  • TCP for cluster replication (internal) and legacy clients (external)

Nodes in the cluster replicate with each other using the TCP protocol, but use gRPC for discovering other cluster nodes.

Server nodes separate internal and external TCP communication explicitly, but use a single HTTP binding. Replication between the cluster nodes is considered internal and all the TCP clients that connect to the database are external. EventStoreDB allows you to separate network configurations for internal and external communication. For example, you can use different network interfaces on the node. All the internal communication can go over the isolated private network but access for external clients can be configured on another interface, which is connected to a more open network. You can set restrictions on those external interfaces to make your deployment more secure.

For gRPC and HTTP, there's no internal vs external separation of traffic.

HTTP configuration

HTTP is the primary protocol for EventStoreDB. It is used in gRPC communication and HTTP APIs (management, gossip and diagnostics).

Unlike for TCP protocol, there is no separation between internal and external communication. The HTTP endpoint always binds to the IP address configured in the ExtIp setting.

Command line--ext-ip
Environment variableEVENTSTORE_EXT_IP

When the ExtIp setting is not provided, EventStoreDB will use the first available non-loopback address. You can also bind HTTP to all available interfaces using as the setting value. If you do that, you'd need to configure the ExtHostAdvertiseAs setting (read mode here), since is not a valid IP address to connect from the outside world.

The default HTTP port is 2113. Depending on the security settings of the node, it either responds over plain HTTP or via HTTPS. There is no HSTS redirect, so if you try reaching a secure node via HTTP, you can an empty response.

You can change the HTTP port using the HttpPort setting:

Command line--http-port
Environment variableEVENTSTORE_HTTP_PORT

Default: 2113

If your network setup requires any kind of IP address, DNS name and port translation for internal or external communication, you can use available address translation settings.

Keep-alive pings

The reliability of the connection between the client application and database is crucial for the stability of the solution. If the network is not stable or has some periodic issues, the client may drop the connection. Stability is essential for the stream subscriptions where a client is listening to database notifications. Having an existing connection open when an app resumes activity allows for the initial gRPC calls to be made quickly, without any delay caused by the reestablished connection.

EventStoreDB supports the built-in gRPC mechanism for keeping the connection alive. If the other side does not acknowledge the ping within a certain period, the connection will be closed. Note that pings are only necessary when there's no activity on the connection.

Keepalive pings are enabled by default, with the default interval set to 10 seconds. The default value is based on the gRPC proposalopen in new window that suggests 10 seconds as the minimum. It's a compromise value to ensure that the connection is open and not making too many redundant network calls.

You can customise the following Keepalive settings:


After a duration of keepAliveInterval (in milliseconds), if the server doesn't see any activity, it pings the client to see if the transport is still alive.

Command line--keep-alive-interval
Environment variableKEEP_ALIVE_INTERVAL

Default: 10000 (ms, 10 sec)


After having pinged for keepalive check, the server waits for a duration of keepAliveTimeout (in milliseconds). If the connection doesn't have any activity even after that, it gets closed.

Command line--keep-alive-timeout
Environment variableKEEP_ALIVE_TIMEOUT

Default: 10000 (ms, 10 sec)

As a general rule, we do not recommend putting EventStoreDB behind a load balancer. However, if you are using it and want to benefit from the Keepalive feature, then you should make sure if the compatible settings are properly set. Some load balancers may also override the Keepalive settings. Most of them require setting the idle timeout larger/longer than the keepAliveTimeout. We suggest checking the load balancer documentation before using Keepalive pings.


The AtomPub application protocol over HTTP is disabled by default since v20. We plan to deprecate the AtomPub support in the future versions, but we aim to provide a replacement before we finally deprecate AtomPub.

In Event Store Cloud, the AtomPub protocol is enabled. For self-hosted instances, use the configuration setting to enable AtomPub.

Command line--enable-atom-pub-over-http
Environment variableENABLE_ATOM_PUB_OVER_HTTP

Default: false (AtomPub is disabled)

Kestrel Settings

It's generally not expected that you'll need to update the Kestrel configuration that EventStoreDB has set by default, but it's good to know that you can update the following settings if needed.

Kestrel uses the kestrelsettings.json configuration file. This file should be located in the default configuration directory.


Sets the maximum number of open connections. See the docs hereopen in new window.

This is configured with Kestrel.Limits.MaxConcurrentConnections in the settings file.


Sets the maximum number of open, upgraded connections. An upgraded connection is one that has been switched from HTTP to another protocol, such as WebSockets. See the docs hereopen in new window.

This is configured with Kestrel.Limits.MaxConcurrentUpgradedConnections in the settings file.

Http2 InitialConnectionWindowSize

Sets how much request body data the server is willing to receive and buffer at a time aggregated across all requests (streams) per connection. Note requests are also limited by KestrelInitialStreamWindowSize

The value must be greater than or equal to 65,535 and less than 2^31. See the docs hereopen in new window.

This is configured with Kestrel.Limits.Http2.InitialConnectionWindowSize in the settings file.

Http2 InitialStreamWindowSize

Sets how much request body data the server is willing to receive and buffer at a time per stream. Note connections are also limited by KestrelInitialConnectionWindowSize

Value must be greater than or equal to 65,535 and less than 2^31. See the docs hereopen in new window.

This is configured with Kestrel.Limits.Http2.InitialStreamWindowSize in the settings file.

TCP configuration

The TCP protocol is used internally for cluster nodes to replicate with each other. It happens over the internal TCP communication. In addition, you can enable external TCP if you use the TCP client library in your applications.


Internal TCP binds to the IP address specified in the IntIp setting. It must be configured if you run a multi-node cluster.

By default, EventStoreDB binds its internal networking on the loopback interface only ( You can change this behaviour and tell EventStoreDB to listen on a specific internal IP address. To do that set the IntIp to or the IP address of the network interface.

Command line--int-ip
Environment variableEVENTSTORE_Int_IP

Default: (loopback).

If you keep this setting to its default value, cluster nodes won't be able to talk to each other.

By default, EventStoreDB uses port 1112 for internal TCP. You can change this by specifying the IntTcpPort setting.

Command line--int-tcp-port
Environment variableEVENTSTORE_INT_TCP_PORT

Default: 1112


By default, TCP protocol is not exposed externally. If you use a TCP client library in your applications, you need to enable external TCP explicitly using the setting below.

Command line--enable-external-tcp

Default: false, TCP is disabled externally.

When enabled, the external TCP will be exposed on the ExtIp address (described here) using port 1113. You can change the external TCP port using the ExtTcpPort setting.

Command line--ext-tcp-port
Environment variableEVENTSTORE_EXT_TCP_PORT

Default: 1113


When the node is secured (by default), all the TCP traffic will use TLS. You can disable TLS for TCP internally and externally using the settings described below.

Command line--disable-internal-tcp-tls

Default: false

Command line--disable-external-tcp-tls

Default: false

If your network setup requires any kind of IP address, DNS name and port translation for internal or external communication, you can use available address translation settings.

Network address translation

Due to NAT (network address translation), or other reasons a node may not be bound to the address it is reachable from other nodes. For example, the machine has an IP address of, but the node is visible to other nodes as

Options described below allow you to tell the node that even though it is bound to a given address it should not gossip that address. When returning links over HTTP, EventStoreDB will also use the specified addresses instead of physical addresses, so the clients that use HTTP can follow those links.

Another case when you might want to specify the advertised address although there's no address translation involved. When you configure EventStoreDB to bind to, it will use the first non-loopback address for gossip. It might or might not be the address you want it to use. Whilst the best way to avoid such a situation is to configure the binding properly using the ExtIp and IntIp settings, you can also use address translation setting with the correct IP address or DNS name.

Also, even if you specified the ExtIp and IntIp settings in the configuration, you might still want to override the advertised address if you want to use hostnames and not IP addresses. That might be needed when running a secure cluster with certificates that only contain DNS names of the nodes.

The only place where these settings make any effect is the gossip endpoint response.

HTTP translations

By default, a cluster node will advertise itself using ExtIp and HttpPort. You can override the advertised HTTP port using the HttpPortAdvertiseAs setting.

Command line--http-port-advertise-as

If you want the node to advertise itself using the hostname rather than its IP address, use the ExtHostAdvertiseAs setting.

Command line--ext-host-advertise-as

TCP translations

Both internal and external TCP ports can be advertised using custom values:

Command line--int-tcp-port-advertise-as
Command line--ext-tcp-port-advertise-as

If you want to change how the node TCP address is advertised internally, use the IntHostAdvertiseAs setting. You can use an IP address or a hostname.

Command line--int-host-advertise-as

Externally, TCP is advertised using the address specified in the ExtIp or ExtHostAdvertiseAs (as for HTTP).

In some cases, the cluster needs to advertise itself to clients using a completely different set of addresses and ports. Usually, you need to do it because addresses and ports configured for the HTTP protocol are not available as-is to the outside world. One of the examples is running a cluster in Docker Compose. In such environment, HTTP uses internal hostnames in the Docker network, which isn't accessible on the host. So, in order to connect to the cluster from the host machine, you need to use localhost and translated HTTP ports to reach the cluster nodes.

To configure how the cluster nodes advertise to clients, use the Advertise<*>ToClient settings listed below.

Specify the advertised hostname or IP address:

Command line--advertise-host-to-client-as

Specify the advertised HTTP(S) port:

Command line--advertise-http-port-to-client-as

Specify the advertised TCP port (only if external TCP is enabled):

Command line--advertise-tcp-port-to-client-as

Heartbeat timeouts

EventStoreDB uses heartbeats over all TCP connections to discover dead clients and nodes. Heartbeat timeouts should not be too short, as short timeouts will produce false positives. At the same time, setting too long timeouts will prevent discovering dead nodes and clients in time.

Each heartbeat has two points of configuration. The first is the interval, this represents how often the system should consider a heartbeat. EventStoreDB doesn't send a heartbeat for every interval, but only if it has not heard from a node within the configured interval. On a busy cluster, you may never see any heartbeats.

The second point of configuration is the timeout. This determines how long EventStoreDB server waits for a client or node to respond to a heartbeat request.

Different environments need different values for these settings. The defaults are likely fine on a LAN. If you experience frequent elections in your environment, you can try to increase both interval and timeout, for example:

  • An interval of 5000ms.
  • A timeout of 1000ms.


If in doubt, choose higher numbers. This adds a small period of time to discover a dead client or node and is better than the alternative, which is false positives.

Internal TCP heartbeat (between cluster nodes):

Command line--int-tcp-heartbeat-interval

Default: 700 (ms)

Command line--int-tcp-heartbeat-timeout

Default: 700 (ms)

External TCP heartbeat (between client and server):

Command line--ext-tcp-heartbeat-interval

Default: 2000 (ms)

Command line--ext-tcp-heartbeat-timeout

Default: 1000 (ms)

gRPC heartbeats

For the gRPC heartbeats, EventStoreDB and its gRPC clients use the protocol feature called Keepalive ping. Read more about it on the HTTP configuration page.

Exposing endpoints

If you need to disable some HTTP endpoints on the external HTTP interface, you can change some settings below. It is possible to disable the Admin UI, stats and gossip port to be exposed externally.

You can disable the Admin UI on external HTTP by setting AdminOnExt setting to false.

Command line--admin-on-ext
Environment variableEVENTSTORE_ADMIN_ON_EXT

Default: true, Admin UI is enabled on the external HTTP.

Exposing the stats endpoint externally is required for the Admin UI and can also be useful if you collect stats for an external monitoring tool.

Command line--stats-on-ext
Environment variableEVENTSTORE_STATS_ON_EXT

Default: true, stats endpoint is enabled on the external HTTP.

You can also disable the gossip protocol in the external HTTP interface. If you do that, ensure that the internal interface is properly configured. Also, if you use gossip with DNS, ensure that the gossip port is set to the internal HTTP port.

Command line--gossip-on-ext
Environment variableEVENTSTORE_GOSSIP_ON_EXT

Default: true, gossip is enabled on the external HTTP.