From 66805d7e77b695f47d272720dbc4ab2f587001ee Mon Sep 17 00:00:00 2001 From: Lev Kokotov Date: Thu, 20 Apr 2023 07:53:55 -0700 Subject: [PATCH] README updates (#409) * Better table * add image * promote auth passthrough to stable * fmt --- README.md | 44 +++++++++++++++++++++++++++++++++++------ images/one_signal.webp | Bin 0 -> 16278 bytes 2 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 images/one_signal.webp diff --git a/README.md b/README.md index 56a8605..4dd7524 100644 --- a/README.md +++ b/README.md @@ -21,21 +21,53 @@ PostgreSQL pooler and proxy (like PgBouncer) with support for sharding, load bal | Client TLS | **Stable** | Clients can connect to the pooler using TLS/SSL. | | Client/Server authentication | **Stable** | Clients can connect using MD5 authentication, supported by `libpq` and all Postgres client drivers. PgCat can connect to Postgres using MD5 and SCRAM-SHA-256. | | Live configuration reloading | **Stable** | Identical to PgBouncer; all settings can be reloaded dynamically (except `host` and `port`). | +| Auth passthrough | **Stable** | MD5 password authentication can be configured to use an `auth_query` so no cleartext passwords are needed in the config file.| | Sharding using extended SQL syntax | **Experimental** | Clients can dynamically configure the pooler to route queries to specific shards. | | Sharding using comments parsing/Regex | **Experimental** | Clients can include shard information (sharding key, shard ID) in the query comments. | | Automatic sharding | **Experimental** | PgCat can parse queries, detect sharding keys automatically, and route queries to the correct shard. | | Mirroring | **Experimental** | Mirror queries between multiple databases in order to test servers with realistic production traffic. | -| Auth passthrough | **Experimental** | MD5 password authentication can be configured to use an `auth_query` so no cleartext passwords are needed in the config file. | ## Status -PgCat is stable and used in production to serve hundreds of thousands of queries per second. Some features remain experimental and are being actively developed. They are optional and can be enabled through configuration. +PgCat is stable and used in production to serve hundreds of thousands of queries per second. -| | | -|-|-| -||| -| [Instacart](https://tech.instacart.com/adopting-pgcat-a-nextgen-postgres-proxy-3cf284e68c2f) | [PostgresML](https://postgresml.org/blog/scaling-postgresml-to-one-million-requests-per-second) | + + + + + + + + + + + +
+ + + + + + + + + + + +
+ + Instacart + + + + PostgresML + + + OneSignal +
+ +Some features remain experimental and are being actively developed. They are optional and can be enabled through configuration. ## Deployment diff --git a/images/one_signal.webp b/images/one_signal.webp new file mode 100644 index 0000000000000000000000000000000000000000..79f3d1293df27aff07988ec9fed98941a10f7c19 GIT binary patch literal 16278 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 literal 0 HcmV?d00001