Environment
@socket.io/postgres-adapter: 0.4.0
socket.io: 4.8.x
pg: 8.16.x
- Node.js: 22
- PostgreSQL: 14.x
Problem description
When using serverSideEmit(..., callback), the callback is invoked with:
(err, responses) => {
console.log(err); // null
console.log(responses); // [] ← empty
}
The event is never delivered to any other server, and the handler (io.on(...)) is never triggered on them.
However, if each individual server sends at least one serverSideEmit() (even a dummy one), things start working — the events are delivered and acknowledged as expected.
Note: If serverSideEmit() is used without a callback, the event is delivered to other servers even before they have sent any emits themselves. The issue only affects the ACK-based communication (serverSideEmit(..., callback)).
Root cause
The Postgres adapter does not deliver serverSideEmit(..., callback) events to other servers unless those servers have already started sending their own heartbeats.
Until a server sends a serverSideEmit():
- It is connected and listening on the correct
LISTEN channel
- It can receive broadcast events without callback
- But it will not be discoverable by other servers for ACK-based communication (
serverSideEmit(..., callback))
As a result:
- The initiating server sends a request and waits for ACKs
- But other servers ignore the request because they don't recognize the source as active
- The callback returns with
responses = []
Minimal reproduction
// on all servers:
io.on("test-ack", (data, callback) => {
console.log("received:", data);
callback("ack from " + process.pid);
});
// on emitter server:
setTimeout(() => {
io.serverSideEmit("test-ack", "hello", (err, responses) => {
console.log("err:", err); // null
console.log("responses:", responses); // [] if heartbeat not yet started on other servers
});
}, 1000);
Workaround
Ensure that every server sends a dummy serverSideEmit() after startup to trigger the heartbeat:
io.serverSideEmit("__init__", "poke");
This ensures each server becomes discoverable by others and can participate in ACK-based messaging.
Environment
@socket.io/postgres-adapter: 0.4.0socket.io: 4.8.xpg: 8.16.xProblem description
When using
serverSideEmit(..., callback), the callback is invoked with:The event is never delivered to any other server, and the handler (
io.on(...)) is never triggered on them.However, if each individual server sends at least one
serverSideEmit()(even a dummy one), things start working — the events are delivered and acknowledged as expected.Root cause
The Postgres adapter does not deliver serverSideEmit(..., callback) events to other servers unless those servers have already started sending their own heartbeats.
Until a server sends a
serverSideEmit():LISTENchannelserverSideEmit(..., callback))As a result:
responses = []Minimal reproduction
Workaround
Ensure that every server sends a dummy
serverSideEmit()after startup to trigger the heartbeat:This ensures each server becomes discoverable by others and can participate in ACK-based messaging.