diff --git a/src/coio.cc b/src/coio.cc
index e3d92a0d7f7856c64c28a1f692eed6e99e7e712e..b8b5e5edd2f9e6d68109efc266e372eca31a02b7 100644
--- a/src/coio.cc
+++ b/src/coio.cc
@@ -220,7 +220,8 @@ coio_accept(struct ev_io *coio, struct sockaddr *addr,
 		 * available */
 		int fd = sio_accept(coio->fd, addr, &addrlen);
 		if (fd >= 0) {
-			evio_setsockopt_tcp(fd, addr->sa_family);
+			evio_setsockopt_client(fd, addr->sa_family,
+					       SOCK_STREAM);
 			return fd;
 		}
 		/* The socket is not ready, yield */
diff --git a/src/evio.cc b/src/evio.cc
index 75b721161c3f8d30fa18ec00cd17ec46856bde07..7ce4e681b19e447824aa7d212c62f9910b8f3e69 100644
--- a/src/evio.cc
+++ b/src/evio.cc
@@ -38,6 +38,9 @@
 
 #define BIND_RETRY_DELAY 0.1
 
+static void
+evio_setsockopt_server(int fd, int family, int type);
+
 /** Note: this function does not throw. */
 void
 evio_close(ev_loop *loop, struct ev_io *evio)
@@ -60,38 +63,66 @@ evio_socket(struct ev_io *coio, int domain, int type, int protocol)
 	assert(coio->fd == -1);
 	/* Don't leak fd if setsockopt fails. */
 	coio->fd = sio_socket(domain, type, protocol);
-	if (type == SOCK_STREAM) {
-		evio_setsockopt_tcp(coio->fd, domain);
-	} else {
-		sio_setfl(coio->fd, O_NONBLOCK, 1);
-	}
+	evio_setsockopt_client(coio->fd, domain, type);
 }
 
-
-/** Set common tcp socket client options. */
-void
-evio_setsockopt_tcp(int fd, int family)
+static void
+evio_setsockopt_keepalive(int fd)
 {
 	int on = 1;
-	/* In case this throws, the socket is not leaked. */
-	sio_setfl(fd, O_NONBLOCK, on);
-	/* SO_KEEPALIVE to ensure connections don't hang
+	/*
+	 * SO_KEEPALIVE to ensure connections don't hang
 	 * around for too long when a link goes away.
 	 */
 	sio_setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE,
 		       &on, sizeof(on));
+#ifdef __linux__
 	/*
-	 * Lower latency is more important than higher
-	 * bandwidth, and we usually write entire
-	 * request/response in a single syscall.
+	 * On Linux, we are able to fine-tune keepalive
+	 * intervals. Set smaller defaults, since the system-wide
+	 * defaults are in days.
 	 */
-	if (family != AF_UNIX)
-		sio_setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
+	int keepcnt = 5;
+	sio_setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &keepcnt,
+		       sizeof(int));
+	int keepidle = 30;
+
+	sio_setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &keepidle,
+		       sizeof(int));
+
+	int keepintvl = 60;
+	sio_setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &keepintvl,
+		       sizeof(int));
+#endif
 }
 
-/** Set tcp options for server sockets. */
+/** Set common client socket options. */
 void
-evio_setsockopt_tcpserver(int fd)
+evio_setsockopt_client(int fd, int family, int type)
+{
+	int on = 1;
+	/* In case this throws, the socket is not leaked. */
+	sio_setfl(fd, O_NONBLOCK, on);
+	if (type == SOCK_STREAM && family != AF_UNIX) {
+		if (family != AF_UNIX) {
+			/*
+			 * SO_KEEPALIVE to ensure connections don't hang
+			 * around for too long when a link goes away.
+			 */
+			evio_setsockopt_keepalive(fd);
+			/*
+			 * Lower latency is more important than higher
+			 * bandwidth, and we usually write entire
+			 * request/response in a single syscall.
+			 */
+			sio_setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
+		}
+	}
+}
+
+/** Set options for server sockets. */
+static void
+evio_setsockopt_server(int fd, int family, int type)
 {
 	int on = 1;
 	/* In case this throws, the socket is not leaked. */
@@ -99,8 +130,6 @@ evio_setsockopt_tcpserver(int fd)
 	/* Allow reuse local adresses. */
 	sio_setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
 		       &on, sizeof(on));
-	sio_setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE,
-		       &on, sizeof(on));
 
 	/* Send all buffered messages on socket before take
 	 * control out from close(2) or shutdown(2). */
@@ -108,6 +137,8 @@ evio_setsockopt_tcpserver(int fd)
 
 	sio_setsockopt(fd, SOL_SOCKET, SO_LINGER,
 		       &linger, sizeof(linger));
+	if (type == SOCK_STREAM && family != AF_UNIX)
+		evio_setsockopt_keepalive(fd);
 }
 
 static inline const char *
@@ -136,8 +167,8 @@ evio_service_accept_cb(ev_loop * /* loop */, ev_io *watcher,
 
 		if (fd < 0) /* EAGAIN, EWOULDLOCK, EINTR */
 			return;
-		/* set common tcp options */
-		evio_setsockopt_tcp(fd, service->addr.sa_family);
+		/* set common client socket options */
+		evio_setsockopt_client(fd, service->addr.sa_family, SOCK_STREAM);
 		/*
 		 * Invoke the callback and pass it the accepted
 		 * socket.
@@ -167,7 +198,7 @@ evio_service_bind_addr(struct evio_service *service)
 		SOCK_STREAM, IPPROTO_TCP);
 
 	try {
-		evio_setsockopt_tcpserver(fd);
+		evio_setsockopt_server(fd, service->addr.sa_family, SOCK_STREAM);
 
 		if (sio_bind(fd, &service->addr, service->addr_len) ||
 		    sio_listen(fd)) {
diff --git a/src/evio.h b/src/evio.h
index e05c017556f487fc0a6e979311fda288f495c2a0..906b968ca8c4ca56f1ec7c21d893649d5504e63c 100644
--- a/src/evio.h
+++ b/src/evio.h
@@ -152,9 +152,6 @@ evio_timeout_update(ev_loop *loop, ev_tstamp start, ev_tstamp *delay)
 }
 
 void
-evio_setsockopt_tcp(int fd, int family);
-
-void
-evio_setsockopt_tcpserver(int fd);
+evio_setsockopt_client(int fd, int family, int type);
 
 #endif /* TARANTOOL_EVIO_H_INCLUDED */
diff --git a/src/sio.cc b/src/sio.cc
index 3bafff5629503ea7d62c0d686af27bb1b08e5b7f..dc04c4eaea1b3ca8417caedc96b8363742f34ef1 100644
--- a/src/sio.cc
+++ b/src/sio.cc
@@ -33,6 +33,7 @@
 #include <errno.h>
 #include <stdio.h>
 #include <limits.h>
+#include <netinet/in.h> /* TCP_NODELAY */
 #include <netinet/tcp.h> /* TCP_NODELAY */
 #include <arpa/inet.h> /* inet_ntoa */
 #include <poll.h>
@@ -102,6 +103,10 @@ sio_option_name(int option)
 	CASE_OPTION(SO_ERROR);
 	CASE_OPTION(SO_REUSEADDR);
 	CASE_OPTION(TCP_NODELAY);
+#ifdef __linux__
+	CASE_OPTION(TCP_KEEPCNT);
+	CASE_OPTION(TCP_KEEPINTVL);
+#endif
 	default:
 		return "undefined";
 	}
diff --git a/src/tarantool.cc b/src/tarantool.cc
index 35ea9350497a6cc4c752e664cbeb2ac5cc0d6d20..92174466a75f27124e4032c083d5759df402e310 100644
--- a/src/tarantool.cc
+++ b/src/tarantool.cc
@@ -92,7 +92,7 @@ title(const char *role, const char *fmt, ...)
 	(void) role;
 
 	va_list ap;
-	char buf[128], *bufptr = buf, *bufend = buf + sizeof(buf);
+	char buf[256], *bufptr = buf, *bufend = buf + sizeof(buf);
 	char *statusptr = status, *statusend = status + sizeof(status);
 	statusptr += snprintf(statusptr, statusend - statusptr, "%s", role);
 	bufptr += snprintf(bufptr, bufend - bufptr, "%s%s", role,