---
title: "Gray ships compiler-hidden PostgreSQL continuations"
description: "Gray handlers can now suspend synchronous-looking PostgreSQL calls on socket readiness, preserving direct code without occupying general task workers."
author: "Grayworth Engineering"
date_published: "2026-07-26T09:40:00Z"
date_modified: "2026-07-26T13:00:00Z"
canonical: "https://grayworth.com/news/gray-postgresql-continuations"
image: "https://grayworth.com/news/media/gray-postgresql-continuations-16x9.png"
section: "Runtime"
word_count: 399
reading_time_minutes: 2
keywords: ["Gray PostgreSQL", "nonblocking database", "compiler continuation", "libpq", "HTTP server"]
---

# Gray ships compiler-hidden PostgreSQL continuations

A 30-second database qualification delivered 7,961.48 requests/s with p99 4.60 ms, 164 simultaneous suspended handlers and zero general task workers.

![Gray source code beside a four-stage flow from HTTP handler suspension through libpq readiness and continuation resume.](https://grayworth.com/news/media/gray-postgresql-continuations-16x9.png)

*Gray keeps database calls in direct source order while the compiler and runtime suspend and resume the HTTP handler around socket readiness.*

**By [Grayworth Engineering](https://grayworth.com/company)**  
Published July 26, 2026 · Updated July 26, 2026 · 2 min read

- **Requested:** 8,000 req/s
- **Achieved:** 7,961.48 req/s
- **Corrected p99:** 4.60 ms
- **General task workers:** 0

## Database waits disappear from handler syntax

Gray HTTP handlers can now call PostgreSQL in direct source order while the compiler and runtime preserve the suspended continuation. The source reads like a synchronous query, but the reactor is released whenever the database socket is not ready.

The application does not maintain a pending-request map, write a polling loop or assign every database wait to a general worker. Gray captures the handler state, associates it with the nonblocking `libpq` operation and resumes the exact continuation when the socket advances.

The result is a server model in which direct code and cooperative I/O are the same product feature rather than competing programming styles.

## Readiness runs through the whole connection lifecycle

Connection creation uses `PQconnectStart` and `PQconnectPoll` rather than blocking the process. Query execution sends work nonblockingly, consumes input only when the database socket is ready and returns the connection to the pool after the complete result is decoded.

When all pool connections are occupied, new work waits in the Gray scheduler instead of failing immediately or consuming task-worker capacity. A cancellation discards the active connection and replaces it safely before another request can inherit uncertain protocol state.

Typed query failures resume through Gray’s normal error path. Live, Static and Adaptive modes preserve the same language behavior.

## The first qualification cleared 8,000 requested

The Static fixture used PostgreSQL 16, a pool of 64 connections, four `wrk2` threads and 256 persistent HTTP connections. At 8,000 requested requests/s, Gray achieved 7,961.48 requests/s, or 99.519% delivery.

Corrected p50 was 1.43 ms, p99 was 4.60 ms and p99.9 was 8.74 ms. The sampler observed as many as 164 simultaneously suspended handlers and no general task workers.

After the run, active tasks and continuations returned to zero. RSS and file-descriptor counts remained within the gate’s declared limits.

## Failure behavior shipped with the fast path

The protocol suite exercises overlapping database handlers in Live and Static modes, typed errors after suspension, independent `HTTP/2` multiplexing, automatic 404 and 500 responses, and Adaptive replacement while an old handler remains in flight.

Cancellation tests verify that unfinished database work cannot leak a connection back into the pool. Sanitizer builds cover the same ownership path, and the optimized suite proves the result through the actual HTTP reactor.

Real service capacity will still depend on query cost, database placement, schema, pool size and topology. What changed in Gray is the architecture: one waiting query no longer owns the HTTP reactor.

## Sources

- [PostgreSQL platform overview](https://grayworth.com/engineering)
- [Gray docs](https://grayworth.com/docs)
- [Commercial preview](https://grayworth.com/pricing)
