EV::Pg

Asynchronous PostgreSQL client for Perl using libpq and the EV event loop.

Features

Synopsis

use v5.10;
use EV;
use EV::Pg;

my $pg = EV::Pg->new(
    conninfo   => 'dbname=mydb',
    on_error   => sub { die "PG error: $_[0]\n" },
);
$pg->on_connect(sub {
    $pg->query("select 1, 'hello'", sub {
        my ($rows, $err) = @_;
        die $err if $err;
        say $rows->[0][1];  # hello
        EV::break;
    });
});
EV::run;

Parameterized queries

$pg->query_params(
    'select $1::int + $2::int',
    [10, 20],
    sub {
        my ($rows, $err) = @_;
        say $rows->[0][0];  # 30
    },
);

Prepared statements

$pg->prepare('stmt', 'select $1::int', sub {
    $pg->query_prepared('stmt', [42], sub {
        my ($rows, $err) = @_;
        say $rows->[0][0];  # 42
    });
});

Pipeline mode

use EV::Pg qw(:pipeline);

$pg->enter_pipeline;
for my $i (0 .. 999) {
    $pg->query_params('select $1::int', [$i], sub { ... });
}
$pg->pipeline_sync(sub {
    $pg->exit_pipeline;
});
$pg->send_flush_request;

Callback convention

All query callbacks receive ($result) on success, (undef, $error) on error:

Installation

Requires Alien::libpq and EV. Alien::libpq will use the system libpq if available, or build it from source.

cpanm EV::Pg

Or manually:

perl Makefile.PL
make
make test
make install

Benchmark

500k queries over Unix socket, PostgreSQL 18, libpq 18:

| Workload | EV::Pg sequential | EV::Pg pipeline | DBD::Pg sync | DBD::Pg async+EV | |----------|------------------:|----------------:|-------------:|-----------------:| | SELECT | 73,109 q/s | 124,092 q/s | 56,496 q/s | 48,744 q/s | | INSERT | 58,534 q/s | 84,467 q/s | 39,068 q/s | 41,559 q/s | | UPSERT | 26,342 q/s | 34,223 q/s | 28,134 q/s | 27,155 q/s |

EV::Pg sequential uses prepared statements (parse once, bind+execute per call). Pipeline mode batches queries with pipeline_sync every 1000 queries.

License

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.