---
title: "Stacks-up Sync: Reliable Real-Time Event Streaming Beyond pg_net"
description: "Discover PostgreSQL's pg_net extension's performance pitfalls in Docker vs. bare-metal setups through in-depth benchmarking, uncovering timeouts, port…"
canonical: https://www.stacksync.com/blog/stacks-up-sync-reliable-real-time-event-streaming-beyond-pg-net
last_modified: 2026-03-22
---

# Stacks-up Sync: Reliable Real-Time Event Streaming Beyond pg_net

Discover PostgreSQL's pg_net extension's performance pitfalls in Docker vs. bare-metal setups through in-depth benchmarking, uncovering timeouts, port exhaustion, and reliability fixes.

Author

Ruben Burdin · Founder & CEO

Published

September 6, 2025

Updated

March 22, 2026

Read time

5 min read

DATA ENGINEERING

PostgreSQL's pg_net extension promises asynchronous HTTP capabilities for database-driven webhooks, but extensive performance testing reveals critical limitations that compromise production reliability. This technical analysis examines pg_net's performance characteristics, debugging challenges, and infrastructure dependencies through comprehensive benchmarking methodology.

## Methodology

For testing, we used the official Supabase Postgres Docker image with pg_net installed. The testing environment utilized Postgres 15.6.1 and pg_net 0.10.1 [\[1\]](https://blog.sequinstream.com/benchmarking-pg_net-part-1). This benchmark ran locally with a simple Elixir Phoenix server as the webhook target. The server simulates processing with a controller action returning 200 responses immediately, typically in ~400 µs [\[1\]](https://blog.sequinstream.com/benchmarking-pg_net-part-1).

We used pgbench to perform transactions against the PostgreSQL database:

`pgbench -c 10 -j 2 -t 1000 -P 5 -h localhost -U postgres -f bench.sql postgres`

This configuration runs the `bench.sql` script 1000 times each across 10 connected clients, simulating concurrent operations against target tables.

## Benchmark Scenarios

The evaluation focused on three critical scenarios:

- 01 **Single insert performance** - Individual transaction throughput
- 02 **Batch insert performance** - Bulk operation scalability
- 03 **Batch insert performance with retries** - Error handling under load

For each scenario, we measured two key metrics: throughput (requests per second) and request success rate. Importantly, we determined throughput levels achieving reliable ~100% success rates.

## The Bench

We implemented a trigger function attached to the `spice_harvests` table that initiates API requests via pg_net:

`CREATE OR REPLACE FUNCTION spice_harvests_webhook() RETURNS TRIGGER LANGUAGE plpgsqlAS $$BEGIN PERFORM net.http_post( url := 'http://host.docker.internal:4000/api/spice-harvest', body := NEW::jsonb, headers := '{"Content-Type": "application/json"}'::jsonb ); RETURN NEW;END;$$;`

pgbench typically finished the 1000 transactions in ~1s, then we allowed pg_net time to work through the `net.http_request_queue` table [\[1\]](https://blog.sequinstream.com/benchmarking-pg_net-part-1).

## First Issues

Initial benchmarking with pg_net's default configuration revealed concerning results:

- **Success Rate**: 94.72%
- **Throughput**: 74.31 requests/second
- **Failed Requests**: 528 with NULL status codes

Using the out-of-the-box Supabase Docker image for local development led to significant performance issues, including a high rate of request failures and throughput far below expectations. These issues were compounded by the fact that pg_net is challenging to debug when something goes wrong [\[1\]](https://blog.sequinstream.com/benchmarking-pg_net-part-1).

Error analysis revealed three primary failure modes:

- "Timeout was reached" (80 requests)
- "Couldn't connect to server" (53 requests)
- "Server returned nothing (no headers, no data)" (395 requests)

As a sanity check, we verified our webhook server could handle the expected load. A direct HTTP test achieved 100% success rate at 1,707 requests per second, confirming the failures originated between PostgreSQL and the server.

## Timeout Was Reached

pg_net configuration parameters include pg_net.batch_size (default: 200), pg_net.ttl (default: 6 hours), with the worker performing deletion while processing requests [\[2\]](https://github.com/supabase/pg_net). The timeout errors stem from libCurl, pg_net's underlying HTTP driver, indicating low-level networking bottlenecks.

Lowering batch_size from 200 to 100 improved performance:

- **Success Rate**: 99.15%
- **Throughput**: 50.26 requests/second
- **Failed Requests**: 17 (all timeout errors)

Further reducing batch_size to 50 finally achieved 100% success rate at 97.36 requests/second.

Increasing timeout_milliseconds to 30 seconds with default batch_size achieved ~98% success rate at ~100 req/sec, but significant errors persisted. The most common error became "Server returned nothing (no headers, no data)" - indicating connection closure at the libCurl level.

Two systems, one record, no batch window

See your own stack synced live. Book a demo with the engineers who built it.

[Book a demo](https://www.stacksync.com/book-a-demo)

## Ephemeral Port Exhaustion

Network analysis using `netstat` revealed over 1000+ connections in `TIME_WAIT` state:

`tcp4 0 0 127.0.0.1.59696 127.0.0.1.4000 TIME_WAITtcp4 0 0 127.0.0.1.59656 127.0.0.1.4000 TIME_WAIT`

This indicates **ephemeral port exhaustion** - the operating system running out of available ports to establish new TCP connections. Each TCP connection enters `TIME_WAIT` after closure to ensure packet delivery, consuming the ephemeral port pool.

With high connection rates, `TIME_WAIT` sockets accumulate faster than they're released, causing new connection attempts to fail. We attempted system-level TCP optimizations:

`sudo sysctl -w net.inet.tcp.msl=1000sudo sysctl -w net.inet.ip.portrange.hifirst=32768sudo sysctl -w net.inet.tcp.keepidle=10000`

Unfortunately, this barely helped performance, with success rates remaining at 93.87% and throughput at 42.83 requests/second [\[1\]](https://blog.sequinstream.com/benchmarking-pg_net-part-1).

## Docker?

To address the performance issues, we pulled the Postgres + pg_net setup out of Docker and ran Postgres on bare metal with brew on MacOS. This required building pg_net from source and enabling it in postgresql.conf [\[1\]](https://blog.sequinstream.com/benchmarking-pg_net-part-1).

The pg_net repository provides build instructions, though we encountered initial clang compilation errors requiring Xcode developer tools installation.

Running bare metal Postgres with pg_net achieved the promised ~1k/sec throughput at 100% success rate: Success Rate: 100.00%, Throughput: 937.19 requests/second [\[1\]](https://blog.sequinstream.com/benchmarking-pg_net-part-1).

## Conclusion

This benchmarking exercise demonstrated that pg_net can deliver the high throughput and reliability it promises—but only under the right conditions. When running on bare-metal PostgreSQL installations, we achieved over 900 requests per second with 100% success rate, aligning with advertised performance metrics [\[1\]](https://blog.sequinstream.com/benchmarking-pg_net-part-1).

However, the journey to this point was far from straightforward. Using standard Supabase Docker images led to significant performance issues and high request failure rates. These issues were compounded by challenging debugging capabilities and the necessity to dive deep into system-level networking configurations—such as ephemeral port exhaustion [\[1\]](https://blog.sequinstream.com/benchmarking-pg_net-part-1).

This experience highlights a critical shortcoming: without robust retry mechanisms, you cannot guarantee that webhooks will reach their target HTTP endpoints [\[1\]](https://blog.sequinstream.com/benchmarking-pg_net-part-1). For production systems requiring reliable real-time data synchronization between databases, CRMs, and ERPs, purpose-built platforms like Stacksync eliminate these infrastructure-level challenges while providing guaranteed delivery, comprehensive error handling, and bi-directional sync capabilities that pg_net cannot offer.

The default Supabase Docker image may not be sufficient for reliable development or production use without significant tweaks and deep system-level understanding. Additional benchmark scenarios will be covered in future posts [\[1\]](https://blog.sequinstream.com/benchmarking-pg_net-part-1) where we'll explore batch insert performance and larger payload handling.

Start with one sync and see it hold

Connect two systems, watch a record move both ways, then decide.

[Start syncing](https://app.stacksync.com/)

FAQ

## Frequently asked questions

What does this guide cover?

This guide covers stacks-up sync: reliable real-time event streaming beyond pg_net, including key concepts, implementation strategies, and best practices for enterprises. You will learn how to leverage Stacksync's real-time bidirectional sync platform to solve common data integration challenges and maintain consistency across your business systems.

How does Stacksync help with this?

Stacksync provides a no-code platform for real-time bidirectional data synchronization between 1,000+ connectors including CRMs, ERPs, databases, and SaaS applications. The platform eliminates manual data entry, prevents data drift, and ensures all systems stay aligned with sub-second sync latency and enterprise-grade security.

Is Stacksync secure for enterprise use?

Yes. Stacksync is SOC 2 Type II certified, ISO 27001 certified, and HIPAA compliant. Data is encrypted in transit with TLS 1.2+ and at rest with AES-256. The platform uses zero-persistent-storage architecture, meaning your data is not retained after sync operations. Enterprise security features include SSO, SCIM, IP whitelisting, and full audit logging.

How long does implementation take?

Most Stacksync integrations go live within 3 to 7 business days. The no-code visual interface handles authentication, field mapping, and data transformation without engineering resources. Complex multi-system architectures may take 2 to 3 weeks. Stacksync provides pre-built connectors and templates that accelerate setup compared to custom development.

What pricing model does Stacksync use?

Stacksync uses flat pricing based on active sync connections and monthly record volume, starting at $1,000 per month. There are no per-row fees, no hidden charges for data volume, and no separate costs for bidirectional sync. Volume discounts are available for enterprise deployments. A 14-day free trial is available to evaluate the platform.

About the author

Ruben Burdin

Founder & CEO

Ruben Burdin is the Founder and CEO of Stacksync, the first real-time and two-way sync for enterprise data at scale. Ruben is a Y Combinator alumni with a strong background in software engineering and business.

[All posts by Ruben Burdin](https://www.stacksync.com/blog/author/ruben-burdin)

About Stacksync

Stacksync powers real-time, two-way sync between CRMs, ERPs, and databases. Engineers sync data at scale and automate workflows, not dirty API plumbing.

Stacksync

Keep reading

## Related articles

[All articles](https://www.stacksync.com/blog)

[Data engineering The AI Agent Data Layer: Per-App MCP Servers vs a Synced Postgres Database 15 min read read](https://www.stacksync.com/blog/ai-agent-data-layer-mcp-vs-synced-database)

[Data engineering Demystifying Pricing Models: A Comparative Analysis of Stacksync, Heroku Connect, and Workato 27 min read read](https://www.stacksync.com/blog/demystifying-pricing-models-a-comparative-analysis-of-stacksync-heroku-connect-and-workato)

[Data engineering HubSpot NetSuite Integration: A Two-Way Sync Guide 13 min read read](https://www.stacksync.com/blog/hubspot-netsuite-integration)

## You just read how it should work. See it run on your own data.

[Book a demo](https://www.stacksync.com/book-a-demo) [Get started](https://app.stacksync.com/)
