@@ -72,6 +72,12 @@ class ClickHouse extends SQL
7272 /** @var bool Whether to enable gzip compression for HTTP requests/responses */
7373 private bool $ enableCompression = false ;
7474
75+ /** @var bool Whether to enable HTTP keep-alive for connection pooling */
76+ private bool $ enableKeepAlive = true ;
77+
78+ /** @var int Number of requests made using this adapter instance */
79+ private int $ requestCount = 0 ;
80+
7581 /**
7682 * @param string $host ClickHouse host
7783 * @param string $username ClickHouse username (default: 'default')
@@ -155,6 +161,34 @@ public function setCompression(bool $enable): self
155161 return $ this ;
156162 }
157163
164+ /**
165+ * Enable or disable HTTP keep-alive for connection pooling.
166+ * When enabled, HTTP connections are reused across multiple requests, reducing latency.
167+ *
168+ * @param bool $enable Whether to enable keep-alive (default: true)
169+ * @return self
170+ */
171+ public function setKeepAlive (bool $ enable ): self
172+ {
173+ $ this ->enableKeepAlive = $ enable ;
174+ return $ this ;
175+ }
176+
177+ /**
178+ * Get connection statistics for monitoring.
179+ *
180+ * @return array{request_count: int, keep_alive_enabled: bool, compression_enabled: bool, query_logging_enabled: bool}
181+ */
182+ public function getConnectionStats (): array
183+ {
184+ return [
185+ 'request_count ' => $ this ->requestCount ,
186+ 'keep_alive_enabled ' => $ this ->enableKeepAlive ,
187+ 'compression_enabled ' => $ this ->enableCompression ,
188+ 'query_logging_enabled ' => $ this ->enableQueryLogging ,
189+ ];
190+ }
191+
158192 /**
159193 * Get the query execution log.
160194 *
@@ -506,11 +540,21 @@ private function query(string $sql, array $params = []): string
506540 // Update the database header for each query (in case setDatabase was called)
507541 $ this ->client ->addHeader ('X-ClickHouse-Database ' , $ this ->database );
508542
543+ // Enable keep-alive for connection pooling
544+ if ($ this ->enableKeepAlive ) {
545+ $ this ->client ->addHeader ('Connection ' , 'keep-alive ' );
546+ } else {
547+ $ this ->client ->addHeader ('Connection ' , 'close ' );
548+ }
549+
509550 // Enable compression if configured
510551 if ($ this ->enableCompression ) {
511552 $ this ->client ->addHeader ('Accept-Encoding ' , 'gzip ' );
512553 }
513554
555+ // Track request count for statistics
556+ $ this ->requestCount ++;
557+
514558 // Build multipart form data body with query and parameters
515559 // The Fetch client will automatically encode arrays as multipart/form-data
516560 $ body = ['query ' => $ sql ];
@@ -575,11 +619,21 @@ private function insert(string $table, array $data): void
575619 $ this ->client ->addHeader ('X-ClickHouse-Database ' , $ this ->database );
576620 $ this ->client ->addHeader ('Content-Type ' , 'application/x-ndjson ' );
577621
622+ // Enable keep-alive for connection pooling
623+ if ($ this ->enableKeepAlive ) {
624+ $ this ->client ->addHeader ('Connection ' , 'keep-alive ' );
625+ } else {
626+ $ this ->client ->addHeader ('Connection ' , 'close ' );
627+ }
628+
578629 // Enable compression if configured
579630 if ($ this ->enableCompression ) {
580631 $ this ->client ->addHeader ('Accept-Encoding ' , 'gzip ' );
581632 }
582633
634+ // Track request count for statistics
635+ $ this ->requestCount ++;
636+
583637 // Join JSON strings with newlines
584638 $ body = implode ("\n" , $ data );
585639
0 commit comments