diff --git a/Cargo.lock b/Cargo.lock
index 2e3ea2842d..9721d487c8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -851,6 +851,7 @@ dependencies = [
"futures",
"hyper",
"notify",
+ "num_cpus",
"opentelemetry",
"postgres",
"regex",
diff --git a/Cargo.toml b/Cargo.toml
index bbd4975603..e27a50a1cb 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -64,6 +64,7 @@ md5 = "0.7.0"
memoffset = "0.8"
nix = "0.26"
notify = "5.0.0"
+num_cpus = "1.15"
num-traits = "0.2.15"
once_cell = "1.13"
opentelemetry = "0.18.0"
diff --git a/Dockerfile.compute-node b/Dockerfile.compute-node
index fc65448323..ef861b15be 100644
--- a/Dockerfile.compute-node
+++ b/Dockerfile.compute-node
@@ -409,6 +409,10 @@ COPY pgxn/ pgxn/
RUN make -j $(getconf _NPROCESSORS_ONLN) \
PG_CONFIG=/usr/local/pgsql/bin/pg_config \
-C pgxn/neon \
+ -s install && \
+ make -j $(getconf _NPROCESSORS_ONLN) \
+ PG_CONFIG=/usr/local/pgsql/bin/pg_config \
+ -C pgxn/neon_utils \
-s install
#########################################################################################
diff --git a/Makefile b/Makefile
index e04a82c7c9..9d78c5d0fc 100644
--- a/Makefile
+++ b/Makefile
@@ -133,6 +133,11 @@ neon-pg-ext-%: postgres-%
$(MAKE) PG_CONFIG=$(POSTGRES_INSTALL_DIR)/$*/bin/pg_config CFLAGS='$(PG_CFLAGS) $(COPT)' \
-C $(POSTGRES_INSTALL_DIR)/build/neon-test-utils-$* \
-f $(ROOT_PROJECT_DIR)/pgxn/neon_test_utils/Makefile install
+ +@echo "Compiling neon_utils $*"
+ mkdir -p $(POSTGRES_INSTALL_DIR)/build/neon-utils-$*
+ $(MAKE) PG_CONFIG=$(POSTGRES_INSTALL_DIR)/$*/bin/pg_config CFLAGS='$(PG_CFLAGS) $(COPT)' \
+ -C $(POSTGRES_INSTALL_DIR)/build/neon-utils-$* \
+ -f $(ROOT_PROJECT_DIR)/pgxn/neon_utils/Makefile install
.PHONY: neon-pg-ext-clean-%
neon-pg-ext-clean-%:
@@ -145,6 +150,9 @@ neon-pg-ext-clean-%:
$(MAKE) PG_CONFIG=$(POSTGRES_INSTALL_DIR)/$*/bin/pg_config \
-C $(POSTGRES_INSTALL_DIR)/build/neon-test-utils-$* \
-f $(ROOT_PROJECT_DIR)/pgxn/neon_test_utils/Makefile clean
+ $(MAKE) PG_CONFIG=$(POSTGRES_INSTALL_DIR)/$*/bin/pg_config \
+ -C $(POSTGRES_INSTALL_DIR)/build/neon-utils-$* \
+ -f $(ROOT_PROJECT_DIR)/pgxn/neon_utils/Makefile clean
.PHONY: neon-pg-ext
neon-pg-ext: \
diff --git a/compute_tools/Cargo.toml b/compute_tools/Cargo.toml
index 46b0e80896..59433535f1 100644
--- a/compute_tools/Cargo.toml
+++ b/compute_tools/Cargo.toml
@@ -11,6 +11,7 @@ clap.workspace = true
futures.workspace = true
hyper = { workspace = true, features = ["full"] }
notify.workspace = true
+num_cpus.workspace = true
opentelemetry.workspace = true
postgres.workspace = true
regex.workspace = true
diff --git a/compute_tools/src/http/api.rs b/compute_tools/src/http/api.rs
index 2392863303..199e0f3bd0 100644
--- a/compute_tools/src/http/api.rs
+++ b/compute_tools/src/http/api.rs
@@ -7,6 +7,7 @@ use crate::compute::ComputeNode;
use anyhow::Result;
use hyper::service::{make_service_fn, service_fn};
use hyper::{Body, Method, Request, Response, Server, StatusCode};
+use num_cpus;
use serde_json;
use tracing::{error, info};
use tracing_utils::http::OtelName;
@@ -49,6 +50,17 @@ async fn routes(req: Request
, compute: &Arc) -> Response {
+ let num_cpus = num_cpus::get_physical();
+ info!("serving /info GET request. num_cpus: {}", num_cpus);
+ Response::new(Body::from(
+ serde_json::json!({
+ "num_cpus": num_cpus,
+ })
+ .to_string(),
+ ))
+ }
+
// Return the `404 Not Found` for any other routes.
_ => {
let mut not_found = Response::new(Body::from("404 Not Found"));
diff --git a/compute_tools/src/http/openapi_spec.yaml b/compute_tools/src/http/openapi_spec.yaml
index 3a8e9fc1dc..5c74dfd2d2 100644
--- a/compute_tools/src/http/openapi_spec.yaml
+++ b/compute_tools/src/http/openapi_spec.yaml
@@ -53,6 +53,21 @@ paths:
schema:
$ref: "#/components/schemas/ComputeInsights"
+ /info:
+ get:
+ tags:
+ - "info"
+ summary: Get info about the compute Pod/VM
+ description: ""
+ operationId: getInfo
+ responses:
+ "200":
+ description: Info
+ content:
+ application/json:
+ schema:
+ $ref: "#/components/schemas/Info"
+
/check_writability:
post:
tags:
@@ -96,6 +111,15 @@ components:
total_startup_ms:
type: integer
+ Info:
+ type: object
+ description: Information about VM/Pod
+ required:
+ - num_cpus
+ properties:
+ num_cpus:
+ type: integer
+
ComputeState:
type: object
required:
diff --git a/pgxn/neon_utils/Makefile b/pgxn/neon_utils/Makefile
new file mode 100644
index 0000000000..852a437713
--- /dev/null
+++ b/pgxn/neon_utils/Makefile
@@ -0,0 +1,15 @@
+# pgxs/neon_utils/Makefile
+
+
+MODULE_big = neon_utils
+OBJS = \
+ $(WIN32RES) \
+ neon_utils.o
+
+EXTENSION = neon_utils
+DATA = neon_utils--1.0.sql
+PGFILEDESC = "neon_utils - small useful functions"
+
+PG_CONFIG = pg_config
+PGXS := $(shell $(PG_CONFIG) --pgxs)
+include $(PGXS)
diff --git a/pgxn/neon_utils/neon_utils--1.0.sql b/pgxn/neon_utils/neon_utils--1.0.sql
new file mode 100644
index 0000000000..d4652e91ad
--- /dev/null
+++ b/pgxn/neon_utils/neon_utils--1.0.sql
@@ -0,0 +1,6 @@
+CREATE FUNCTION num_cpus()
+RETURNS int
+AS 'MODULE_PATHNAME', 'num_cpus'
+LANGUAGE C STRICT
+PARALLEL UNSAFE
+VOLATILE;
diff --git a/pgxn/neon_utils/neon_utils.c b/pgxn/neon_utils/neon_utils.c
new file mode 100644
index 0000000000..8b9dfa24f4
--- /dev/null
+++ b/pgxn/neon_utils/neon_utils.c
@@ -0,0 +1,35 @@
+/*-------------------------------------------------------------------------
+ *
+ * neon_utils.c
+ * neon_utils - small useful functions
+ *
+ * IDENTIFICATION
+ * contrib/neon_utils/neon_utils.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifdef _WIN32
+#include
+#else
+#include
+#endif
+
+#include "postgres.h"
+#include "fmgr.h"
+
+PG_MODULE_MAGIC;
+
+PG_FUNCTION_INFO_V1(num_cpus);
+
+Datum
+num_cpus(PG_FUNCTION_ARGS)
+{
+#ifdef _WIN32
+ SYSTEM_INFO sysinfo;
+ GetSystemInfo(&sysinfo);
+ uint32 num_cpus = (uint32) sysinfo.dwNumberOfProcessors;
+#else
+ uint32 num_cpus = (uint32) sysconf(_SC_NPROCESSORS_ONLN);
+#endif
+ PG_RETURN_UINT32(num_cpus);
+}
diff --git a/pgxn/neon_utils/neon_utils.control b/pgxn/neon_utils/neon_utils.control
new file mode 100644
index 0000000000..ff402efb31
--- /dev/null
+++ b/pgxn/neon_utils/neon_utils.control
@@ -0,0 +1,6 @@
+# neon_utils extension
+comment = 'neon_utils - small useful functions'
+default_version = '1.0'
+module_pathname = '$libdir/neon_utils'
+relocatable = true
+trusted = true