# Unix domain socket

A Unix domain socket (also called a Unix socket or local socket) is an endpoint for interprocess communication between programs running on the same machine, addressed either by a filesystem pathname or, on Linux, by a name in an abstract namespace. It uses the normal socket API with the address family AF_UNIX (also known as AF_LOCAL), and it is a standard feature of UNIX certified systems.<sup>[1](https://man7.org/linux/man-pages/man7/unix.7.html)</sup><sup> • </sup><sup>[2](https://www.unix.org/overview.html)</sup>

| Key fact | Detail |
|---|---|
| Address family | AF_UNIX / AF_LOCAL, for communication between processes on the same machine<sup>[1](https://man7.org/linux/man-pages/man7/unix.7.html)</sup> |
| Socket types | SOCK_STREAM, SOCK_DGRAM (preserves boundaries; reliable and not reordered on most UNIX implementations), and SOCK_SEQPACKET (since Linux 2.6.4)<sup>[1](https://man7.org/linux/man-pages/man7/unix.7.html)</sup> |
| Address size | Linux sun_path is 108 bytes; FreeBSD allows pathnames of at most 104 characters<sup>[1](https://man7.org/linux/man-pages/man7/unix.7.html)</sup><sup> • </sup><sup>[3](https://man.freebsd.org/cgi/man.cgi?apropos=0&manpath=FreeBSD+10.2-RELEASE&query=unix&sektion=4)</sup> |
| Distinctive capability | Passing file descriptors and process credentials between processes via ancillary data (SCM_RIGHTS, SCM_CREDENTIALS)<sup>[1](https://man7.org/linux/man-pages/man7/unix.7.html)</sup><sup> • </sup><sup>[3](https://man.freebsd.org/cgi/man.cgi?apropos=0&manpath=FreeBSD+10.2-RELEASE&query=unix&sektion=4)</sup> |
| Origin | Experimental facility in 4.2BSD, which introduced the UNIX domain for socket IPC<sup>[4](https://docs-archive.freebsd.org/44doc/psd/20.ipctut/paper.pdf)</sup> |
| Performance (one Linux benchmark) | 81 µs median round trip and 546 MB/s throughput, versus 109 µs and 448 MB/s for TCP loopback<sup>[5](https://github.com/aviNaftalis/ipc-shootout)</sup> |
| Common use | Default local control interface of the Docker daemon and the Podman API<sup>[6](https://docs.docker.com/engine/daemon/remote-access/)</sup><sup> • </sup><sup>[7](https://docs.podman.io/en/v5.0.3/markdown/podman-system-service.1.html)</sup> |

## How it works

A Unix domain socket is created with the ordinary socket(2) call, specifying AF_UNIX and a socket type. Three types are valid in the Unix domain: SOCK_STREAM for a byte-stream connection, SOCK_DGRAM for datagrams that preserve message boundaries, and SOCK_SEQPACKET for a connection-oriented, sequenced-packet service. On most UNIX implementations, Unix domain datagram sockets are reliable and do not reorder datagrams, unlike UDP on a network.<sup>[1](https://man7.org/linux/man-pages/man7/unix.7.html)</sup>

**Addressing.** Traditionally a socket is either unnamed or bound to a null-terminated filesystem pathname using bind(2). Binding a name creates a socket file in the filesystem, and other processes refer to the socket by that pathname; on FreeBSD the file is not removed when the socket is closed, so unlink(2) must be called to remove it.<sup>[1](https://man7.org/linux/man-pages/man7/unix.7.html)</sup><sup> • </sup><sup>[3](https://man.freebsd.org/cgi/man.cgi?apropos=0&manpath=FreeBSD+10.2-RELEASE&query=unix&sektion=4)</sup> The address structure sockaddr_un holds the family (always AF_UNIX) and a pathname field, 108 bytes on Linux and 104 characters on FreeBSD.<sup>[1](https://man7.org/linux/man-pages/man7/unix.7.html)</sup><sup> • </sup><sup>[3](https://man.freebsd.org/cgi/man.cgi?apropos=0&manpath=FreeBSD+10.2-RELEASE&query=unix&sektion=4)</sup> Linux additionally supports an abstract namespace, a name independent of the filesystem; when an abstract socket is closed its name disappears with it, and no filesystem cleanup is needed.<sup>[1](https://man7.org/linux/man-pages/man7/unix.7.html)</sup>

Because pathname sockets live in the filesystem, normal file access-control mechanisms apply: connecting to or sending to a pathname socket requires write permission on that path, and the Unix domain supports neither broadcast addressing nor wildcard matching of addresses.<sup>[3](https://man.freebsd.org/cgi/man.cgi?apropos=0&manpath=FreeBSD+10.2-RELEASE&query=unix&sektion=4)</sup>

## File descriptor and credential passing

The capability that most clearly separates Unix domain sockets from pipes and network sockets is ancillary data. A process can send an open file descriptor to another process over a socket using sendmsg(2) with a control message of type SCM_RIGHTS; the data portion is an array of integers naming the descriptors to pass. The descriptor the receiver obtains is a duplicate of the sender's, as if created by dup(fd), and descriptors awaiting delivery are closed automatically by the system if the destination socket is closed before they are received.<sup>[3](https://man.freebsd.org/cgi/man.cgi?apropos=0&manpath=FreeBSD+10.2-RELEASE&query=unix&sektion=4)</sup> This mechanism lets one process, for example a service broker or a container runtime, hand another process access to a file or device it could not open itself.

Credentials travel the same way. On Linux, enabling SO_PASSCRED causes receipt of the sending process's credentials in an SCM_CREDENTIALS ancillary message; FreeBSD offers the LOCAL_CREDS socket option, which delivers a sockcred structure containing the real and effective user and group IDs and supplemental groups.<sup>[1](https://man7.org/linux/man-pages/man7/unix.7.html)</sup><sup> • </sup><sup>[3](https://man.freebsd.org/cgi/man.cgi?apropos=0&manpath=FreeBSD+10.2-RELEASE&query=unix&sektion=4)</sup> Linux also supports SO_PASSSEC, which delivers the peer's SELinux security label in an SCM_SECURITY message; it has been supported for datagram sockets since Linux 2.6.18 and for stream sockets since Linux 4.2.<sup>[1](https://man7.org/linux/man-pages/man7/unix.7.html)</sup> A server that receives clients over a Unix socket can therefore authenticate them by kernel-verified identity rather than by an application-level protocol.

## Performance compared with TCP loopback and other IPC

For local communication a Unix socket avoids the full network stack that TCP loopback pays. In a cross-platform C++23 benchmark of IPC mechanisms, the Unix socket on Linux recorded a median round-trip time of 81 µs and 546 MB/s throughput, against 109 µs and 448 MB/s for TCP loopback and 86 µs and 497 MB/s for named pipes; shared memory was far faster (0.3 µs, 3500 MB/s) but cost about two cores of busy-wait spinning versus roughly one core for the kernel-mediated transports.<sup>[5](https://github.com/aviNaftalis/ipc-shootout)</sup> The ranking is platform dependent: on Windows the named pipe was the fastest kernel-mediated transport at 27 µs median, ahead of the Unix socket at 31 µs, while on Linux the Unix socket edged out the pipe.<sup>[5](https://github.com/aviNaftalis/ipc-shootout)</sup> Under a single-CPU constraint the picture changes again: blocking transports speed up because the handoff becomes a same-core context switch, with the Unix socket measured at 10 µs per round trip.<sup>[5](https://github.com/aviNaftalis/ipc-shootout)</sup>

## API limitations on Linux

The Linux Unix domain implementation omits some features of the general sockets API. It does not support out-of-band data (the MSG_OOB flag of send(2) and recv(2)) or the MSG_MORE flag of send(2), and before Linux 3.4 it did not support MSG_TRUNC in recv(2).<sup>[1](https://man7.org/linux/man-pages/man7/unix.7.html)</sup> Buffer options behave asymmetrically: SO_SNDBUF has an effect, and for datagram sockets it caps the size of outgoing datagrams at the doubled option value minus 32 bytes of overhead, while SO_RCVBUF has no effect.<sup>[1](https://man7.org/linux/man-pages/man7/unix.7.html)</sup>

## History and standardization

The Unix domain appeared as an experimental facility in 4.2BSD, the Berkeley release that introduced the sockets API, where a socket in the UNIX domain is given a pathname in the filesystem so that any two processes working in the same filesystem can communicate without a common ancestor to set up a pipe.<sup>[4](https://docs-archive.freebsd.org/44doc/psd/20.ipctut/paper.pdf)</sup> The Single UNIX Specification requires UNIX certified systems to support Unix domain sockets for process-to-process communication within a single system, alongside IPv4 network sockets, with IPv6 and raw sockets optional; its XSH Section 2.10 covers socket types, addressing, protocols, and socket options for both domains.<sup>[2](https://www.unix.org/overview.html)</sup>

## Typical uses

Local service APIs are the most visible applications. The Docker daemon by default listens for connections on a Unix socket, traditionally /var/run/docker.sock, to accept requests from local clients, and remote access is an explicit configuration change with security consequences.<sup>[6](https://docs.docker.com/engine/daemon/remote-access/)</sup> Podman's API service follows the same pattern: its security model is built on Unix socket access restricted by standard file permissions, the rootful service listens on /run/podman/podman.sock and the rootless service on $XDG_RUNTIME_DIR/podman/podman.sock, and setting DOCKER_HOST to that socket lets Docker API tools such as docker-compose drive [Podman](https://www.edgepedia.org/podman).<sup>[7](https://docs.podman.io/en/v5.0.3/markdown/podman-system-service.1.html)</sup> Podman also supports systemd socket activation, in which the service starts only when a client connects to the socket.<sup>[7](https://docs.podman.io/en/v5.0.3/markdown/podman-system-service.1.html)</sup>

The credential-passing and descriptor-passing features make Unix sockets the standard channel for privilege separation: an unprivileged front-end process can authenticate the peer, hand opened resources to a privileged helper, or receive them from one, with the kernel guaranteeing the identity claims.<sup>[1](https://man7.org/linux/man-pages/man7/unix.7.html)</sup><sup> • </sup><sup>[3](https://man.freebsd.org/cgi/man.cgi?apropos=0&manpath=FreeBSD+10.2-RELEASE&query=unix&sektion=4)</sup>

## References

1. [unix(7) - Linux manual page, man-pages project](https://man7.org/linux/man-pages/man7/unix.7.html)
2. [The Single UNIX Specification V5 (2024) - Introduction, The Open Group](https://www.unix.org/overview.html)
3. [unix(4) - FreeBSD 10.2-RELEASE Manual Pages](https://man.freebsd.org/cgi/man.cgi?apropos=0&manpath=FreeBSD+10.2-RELEASE&query=unix&sektion=4)
4. [Introductory 4.4BSD Interprocess Communication Tutorial, FreeBSD Documentation Archive](https://docs-archive.freebsd.org/44doc/psd/20.ipctut/paper.pdf)
5. [ipc-shootout: cross-platform C++23 benchmark of IPC mechanisms, GitHub](https://github.com/aviNaftalis/ipc-shootout)
6. [Configure remote access for Docker daemon, Docker Docs](https://docs.docker.com/engine/daemon/remote-access/)
7. [podman-system-service, Podman documentation](https://docs.podman.io/en/v5.0.3/markdown/podman-system-service.1.html)

---
*Topic: Encyclopedia › Technology and the built world › Computing and digital systems › Networks and security › Networking fundamentals and architecture › Internet protocol suite*

*Initially written Sep 17, 2026 · Reviewed: Oct 15, 2026 · Edited: Oct 15, 2026 · Last review: Oct 15, 2026*

*Copyright 2026 EdgeChat AI, a subsidiary of Biostate AI.*

License: Edgepedia Community License 1.0, https://www.edgepedia.org/edgepedia/license
