Benchmarking PLJS vs PLV8

June 25, 2025 ยท View on GitHub

PLV8 uses Google's V8 JavaScript engine, whereas PLJS uses the QuickJS engine. QuickJS's performance relative to V8 is well-documented here.

Since Postgres stored procedures are typically short-lived, which primarily serve data transformations, we focus instead on specific metrics such as type conversions between PostgreSQL and JavaScript, and startup times.

Benchmarks

The benchmarks are currently separated into two sections: type conversion, and general performance; type conversions are general PostgreSQL to JavaScript and back type conversions.

Conversion

Benchmarking conversions involves executing an SPI SELECT of the value, which converts from JavaScript to Postgres, and back.

TestCountDescription
JSON Conversion Small10000Small JSON conversion
JSON Conversion Medium10000Medium JSON conversion
JSONB Conversion Small10000Small JSONB conversion
JSONB Conversion Medium10000Medium JSONB conversion
INT Conversion100000Integer conversion
FLOAT Conversion100000Float conversion
TEXT Conversion100000String conversion
TIMESTAMP Conversion100000Date conversion

Performance

Performance depends on two specific benchmarks: engine startup and a simple array search test. The array search test provides insight into variable performance, and startup is critical for initializing the extension and executing stored procedures quickly.

It should be noted that once a context is created, it is active until the Postgres process is disconnected.

TestCountDescription
Array Creation and Search10000Create an array and search it
Context Creation1000Create a new JavaScript context and execute

Tested Platforms

Tested platforms were against ARM64/AARCH64 running both MacOS and Linux, and x86_64 running Linux. This was meant to show the differences both on an operating system level as well as a CPU level.

CPUOperating SystemPlatform
M1 MaxMacOSAarch64
AMD64Linuxx86_64
Rockchip RK3588SLinuxArm64

Results

The results show variation based on operating system and CPU.

AARCH64 - MacOS

BenchmarkPLJSPLV8
JSON conversion small (10000)219.416ms165.447ms
JSON conversion medium (10000)4038.368ms553.211ms
JSONB conversion small (10000)219.808ms137.069ms
JSONB conversion medium (10000)2740.983ms1726.405ms
INT conversion (100000)1217.895ms1083.894ms
FLOAT conversion (100000)1010.408ms966.111ms
TEXT conversion (100000)1059.067ms1070.629ms
TIMESTAMP conversion (100000)1256.939ms1067.198ms
Array creation and search (10000)6628.59ms4409.779ms
Context creation (1000)9401.116ms2376.421ms

Arm64 - Linux

BenchmarkPLJSPLV8
JSON conversion small (10000)319.792ms403.188ms
JSON conversion medium (10000)2770.112ms1197.231ms
JSONB conversion small (10000)217.58ms290.721ms
JSONB conversion medium (10000)1960.291ms2817.583ms
INT conversion (100000)2029.335ms2682.387ms
FLOAT conversion (100000)1781.802ms2049.39ms
TEXT conversion (100000)1690.534ms2229.296ms
TIMESTAMP conversion (100000)1774.391ms2226.814ms
Array creation and search (10000)17608.051ms9060.09ms
Context creation (1000)27881.981ms4864.181ms

x64_64 - Linux

BenchmarkPLJSPLV8
JSON conversion small (10000)380.352ms563.658ms
JSON conversion medium (10000)2551.5ms1215.062ms
JSONB conversion small (10000)249.23ms415.243ms
JSONB conversion medium (10000)1920.07ms3193.685ms
INT conversion (100000)3489.673ms3412.874ms
FLOAT conversion (100000)2292.054ms2819.443ms
TEXT conversion (100000)1919.394ms3059.18ms
TIMESTAMP conversion (100000)1926.551ms3376.927ms
Array creation and search (10000)13970.188ms6276.774ms
Context creation (1000)23741.54ms5037.147ms