EPICS has two network protocols. Both are current, both are supported, and an EPICS 7 IOC serves both simultaneously from the same records.
References: Channel Access Reference Manual · PV Access protocol specification · Normative Types
| Channel Access (CA) | PV Access (PVA) | |
|---|---|---|
| Since | ~1990 | EPICS 7 (2017); designed as EPICS v4 |
| Data model | Scalars, arrays, and fixed compound “DBR” types (value + timestamp + limits + …) | Arbitrary nested structures, introspected at runtime |
| Standard structures | — | Normative Types: NTScalar, NTNDArray, NTTable, NTEnum, … |
| Partial access | No — you get the whole channel | Yes — request a sub-field of a structure |
| RPC | No | Yes (pvcall) — services with typed arguments and returns |
| Discovery | UDP broadcast/unicast, port 5064 | UDP broadcast/unicast, port 5076 |
| Data transport | TCP, port 5064 | TCP, port 5075 |
| Beacons | UDP 5065 | UDP 5076 (multicast-capable) |
| C library | libca in Base |
PVXS (modern) or pvAccessCPP (older) |
| CLI tools | caget, caput, camonitor, cainfo, cainfo |
pvget, pvput, pvmonitor, pvinfo, pvcall, pvlist |
| Base server | Every IOC; softIoc |
Every Base 7 IOC with pvAccess; softIocPVA |
| Share of production traffic | Overwhelming majority | Growing; dominant in new services and imaging |
The original protocol, in production since the early 1990s, and still carrying the overwhelming majority of EPICS traffic worldwide.
A channel is a single named value — a scalar, an array, or an enum — offered in several request types that bundle progressively more metadata alongside the value (see DBR types below). Discovery is by UDP broadcast on port 5064; data flows over TCP on the same port. The client library, libca, ships in Base, and every other CA implementation is either a binding to it or a reimplementation of its wire protocol.
Its limitations are the ones you’d expect of a design from 1990: no structured data, no partial reads, a 40-character limit on string values, no RPC, and no authentication or encryption. Its strengths are that it is small, fast, extremely well tested, and understood by every tool in the ecosystem.
Introduced with EPICS 7, having been developed as EPICS v4. It transports self-describing structures rather than bare values, which is the whole point: a value, its timestamp, its alarm state and its display metadata arrive as one atomic object, and a client can request just the fields it wants.
The standard structure definitions are the Normative Types — NTScalar, NTNDArray, NTTable, NTEnum and others — which is what makes structured data interoperable between tools that know nothing about each other. PVA also supports RPC, so a service can expose typed calls rather than a set of magic PVs.
Discovery is UDP on port 5076 (multicast-capable), data over TCP on 5075. Implementations: PVXS for modern C++, p4p for Python, and the pvAccess stack bundled in Base 7.
Learn with CA. Its tooling, examples, and mailing-list history are vastly larger, and it is what your facility’s existing screens use.
Reach for PVA when you need: a structure (value plus metadata as one atomic unit), a table, an image with its dimensions and attributes attached (NTNDArray), an RPC-style service call, partial reads of a large structure, or a service that only speaks PVA.
This is not an either/or migration. Facilities run both, indefinitely.
Understanding this sequence explains most connectivity failures.
sequenceDiagram
participant C as Client (caget)
participant N as Network (broadcast domain)
participant I as IOC serving the PV
C->>N: UDP search "SR-C05-PS-QF-01:Current-RB"<br/>(to EPICS_CA_ADDR_LIST, or broadcast)
Note over C,N: Retried with exponential backoff:<br/>~30 ms, 60 ms, 120 ms … capped at 30 s
N->>I: search arrives
I->>C: UDP reply "I have it, TCP me on port 5064"
C->>I: TCP connect
C->>I: create channel, negotiate version
I->>C: channel created: native type, element count, access rights
C->>I: get / put / monitor-subscribe
I-->>C: value + timestamp + alarm status
Note over I,C: IOC also emits periodic UDP beacons on 5065<br/>so clients detect a restarted server quickly
Failure modes that map directly onto this diagram:
| Symptom | Where it broke |
|---|---|
| “Channel connect timed out” | The search never reached an IOC, or the reply never came back. Address list, routing, or firewall. |
| Connects then immediately disconnects | TCP reachable but something (NAT, asymmetric routing, MTU) breaks the data connection. |
| Works from host A, not host B | Different broadcast domain or different EPICS_CA_ADDR_LIST. |
| Slow to reconnect after an IOC restart | Beacons blocked (UDP 5065), so the client waits for its own retry backoff instead of being told. |
| Two clients see different values for one name | Duplicate PV name on two IOCs. See naming. |
A monitor is a subscription: “tell me when this changes”. It is the mechanism behind every live screen and the archiver.
What “changes” means is set by the record, not the client:
MDEL on the record — the monitor deadband. Change smaller than this posts nothing.!!! warning “Monitors are not a complete history” Monitors deliver the current value at delivery time. If a client is slow, or its queue fills, or values change faster than the network drains, intermediate values are dropped by design. Base logs “client last message” / queue-overflow warnings when this happens.
If you need every sample: buffer it in the IOC (`compress` record, circular buffer in the driver, waveform per acquisition), or use a mechanism designed for it. Do not build a data pipeline that assumes monitors are lossless — this mistake is usually discovered months later, in analysis.
Cost model. Network and CPU load ≈ (number of monitored channels) × (update rate) × (number of subscribed clients). Four hundred workstations each monitoring 5 000 PVs at 10 Hz is 20 million updates per second demanded of your IOCs. This is what gateways exist to collapse: the gateway holds one monitor per PV and fans out to its clients, so an IOC serves one connection instead of four hundred.
CA offers each channel in several request types, layered:
DBR_DOUBLE value only
DBR_STS_DOUBLE + status, severity
DBR_TIME_DOUBLE + timestamp ← what monitors normally use
DBR_GR_DOUBLE + display limits, units, precision
DBR_CTRL_DOUBLE + control limits
Plus DBR_ENUM for enumerated values (with up to sixteen 26-character state strings) and DBR_STRING, which is 40 characters, hard limit. Longer text needs a char waveform (the -S option in caget) or the lsi/lso long-string record types.
caget gives you value only; caget -a adds timestamp and alarm; caget -d DBR_CTRL_DOUBLE gives you everything. When a display shows units and limits without you configuring them, that’s DBR_CTRL at work.
PVA transports self-describing structures. An NTScalar is:
structure NTScalar
double value
alarm_t alarm
int severity
int status
string message
time_t timeStamp
long secondsPastEpoch
int nanoseconds
int userTag
display_t display
double limitLow
double limitHigh
string description
string units
int precision
control_t control
...
Two properties this buys you:
pvget -r 'value,timeStamp' BIG:PV transfers only those fields — significant when the structure is a megapixel image or a 10 000-row table.NTNDArray is why detector work has moved to PVA: an image, its dimensions, its compression codec, its unique ID and its per-frame attributes are one coherent object, which is exactly what a downstream analysis pipeline needs.
| Port | Protocol | Direction | Purpose |
|---|---|---|---|
| 5064/udp | CA | client → server (broadcast or unicast) | Name search |
| 5064/tcp | CA | client → server | Channel data |
| 5065/udp | CA | server → clients (broadcast) | Beacons |
| 5075/tcp | PVA | client → server | Channel data |
| 5076/udp | PVA | both | Search and beacons (multicast capable) |
Firewall rules must permit inbound UDP on 5064/5076 to IOCs, inbound TCP on 5064/5075 to IOCs, and the beacon path back to clients. A common misconfiguration allows TCP but not UDP, which produces “the PV doesn’t exist” with no other symptom.
Repeaters: CA uses a local caRepeater process that fans beacons out to multiple client processes on one host. It starts automatically, listens on UDP 5065, and its absence causes slow reconnection. If you see complaints about caRepeater in a log, that’s what it is.
Full list in environment variables. The ones with real consequences:
| Variable | Default | Why you’d change it |
|---|---|---|
EPICS_CA_ADDR_LIST |
(empty) | The list of addresses to send searches to. Set this explicitly on any routed network. Broadcast addresses of remote subnets, or IOC/gateway unicast addresses. |
EPICS_CA_AUTO_ADDR_LIST |
YES |
NO to stop also broadcasting on every local interface — required when your list is deliberate. |
EPICS_CA_MAX_ARRAY_BYTES |
16384 (Base < 3.14.12 era default; modern Base auto-sizes) | Historic source of “array truncated” grief. Modern Base grows buffers dynamically, but old clients and old IOCs still need it raised on both ends. |
EPICS_CA_CONN_TMO |
30 s | How long before a quiet connection is declared dead. |
EPICS_CA_BEACON_PERIOD |
15 s | Server beacon interval. |
EPICS_CA_SERVER_PORT / EPICS_CA_REPEATER_PORT |
5064 / 5065 | Run two isolated EPICS “universes” on one network by changing the port. A legitimate trick for a test system beside a production one — and a way to make PVs mysteriously invisible if you forget you did it. |
EPICS_PVA_ADDR_LIST, EPICS_PVA_AUTO_ADDR_LIST, EPICS_PVA_SERVER_PORT, EPICS_PVA_BROADCAST_PORT |
— | PVA equivalents. |
EPICS_CAS_INTF_ADDR_LIST / EPICS_CAS_BEACON_ADDR_LIST |
— | Server-side: which interfaces to serve on and where to send beacons. Essential on multi-homed IOC hosts, where the default behaviour is often wrong. |
!!! tip “Array sizes are still a real trap”
Large waveforms (camera images, orbit arrays) fail in ways that look like corruption rather than a limit. If a 2 048-element waveform reads back with 1 024 elements, or caget reports a size mismatch, suspect buffer limits on the client, the server, and any gateway in between — all three have to agree.
Channel Access has no authentication and no encryption. The “user name” a client sends is whatever it chooses to send. Access security rules based on it are a guard against accident, not against an adversary. Anyone with IP reachability to an IOC can, in general, write to any PV that isn’t protected by an ASG, and even ASGs trust a self-declared identity.
The architectural answer is network segmentation — controls networks are physically or logically separated, and everything else reaches them through a read-only gateway. See Networking and the example facility’s network design.
Work on authenticated, TLS-protected PVA (often discussed as “secure PVA”) has been ongoing in the community; check the current Base and PVXS release notes rather than any statement on this page for where it stands.
→ Naming Conventions — because the PV name is the entire API.