Since version 1.3.0, pg is fully compatible with Ruby 3.0's Fiber.scheduler. All potentially blocking IO operations are automatically routed through the registered Fiber.scheduler for the running thread. This is achieved by pg internally using the asynchronous libpq interface even for synchronous method calls and using Ruby's DNS resolution instead of libpq's built-in functions.
Note on Non-blocking Mode:
Internally, pg always uses libpq's non-blocking connection mode. If you call PG::Connection#setnonblocking(true), the non-blocking state remains enabled, but the automatic handling of blocking states is disabled, requiring your program to handle them manually.
Exceptions to Fiber compatibility:
Some operations will work but will not allow the IO scheduler to switch to another Fiber during waiting states (they will block the thread):
- Large object methods (e.g.,
PG::Connection#lo_create) - Authentication using external libraries (GSSAPI, LDAP)
- LDAP lookup of connection parameters
- Connection strings/hashes using the
service parameter without explicit host and port.
Workarounds for service-based connections:
To maintain Fiber.scheduler compatibility when using service files, use one of these instead:
- Set the service via the
PGSERVICE environment variable. - Provide
host and port explicitly in the connection string or hash. - Set the
hostaddr in the service file.
# Example of a connection that might block the Fiber scheduler if 'service' is used without host/port
conn = PG.connect(service: 'my_service')
# Recommended for Fiber compatibility:
conn = PG.connect(service: 'my_service', host: 'localhost', port: 5432)