From 131cfde1f51284d66ae43124846a8d05bb1a0356 Mon Sep 17 00:00:00 2001 From: Steven Sklar Date: Wed, 17 Jun 2026 11:45:03 -0400 Subject: [PATCH 1/5] Rework GCP deployment doc for VM install, align with AWS/Azure Compute Engine no longer supports deploying a container as the VM OS, so the GCP guide now creates a standard Ubuntu VM and installs QuestDB over SSH using the release binary, mirroring the Azure guide. Restructures the page to match the AWS/Azure layout: Quick reference, Infrastructure (sizing/storage/networking), Deployment, Security, Operations, and Enterprise. Folds the GCP-specific storage content (Hyperdisk, Filestore, GCS, NetApp Volumes) into these sections and removes the stale Pulumi example. Removes the orphaned create-vm-docker and instance-available screenshots. Co-Authored-By: Claude Opus 4.8 (1M context) --- documentation/deployment/gcp.md | 550 ++++++++++-------- .../create-vm-docker.webp | Bin 33638 -> 0 bytes .../instance-available.webp | Bin 10066 -> 0 bytes 3 files changed, 303 insertions(+), 247 deletions(-) delete mode 100644 static/images/guides/google-cloud-platform/create-vm-docker.webp delete mode 100644 static/images/guides/google-cloud-platform/instance-available.webp diff --git a/documentation/deployment/gcp.md b/documentation/deployment/gcp.md index be59034a8..beef45492 100644 --- a/documentation/deployment/gcp.md +++ b/documentation/deployment/gcp.md @@ -1,341 +1,397 @@ --- -title: Deploying to Google Cloud Platform (GCP) +title: Deploying QuestDB on GCP sidebar_label: GCP description: - This document explains what to hardware to use, and how to provision QuestDB on Google Cloud Platform (GCP). + Deploy QuestDB on Google Cloud Platform using Compute Engine, with instance sizing, storage, and networking recommendations. --- - +import Screenshot from "@theme/Screenshot" +import InterpolateReleaseData from "../../src/components/InterpolateReleaseData" +import CodeBlock from "@theme/CodeBlock" import FileSystemChoice from "../../src/components/DRY/_questdb_file_system_choice.mdx" import MinimumHardware from "../../src/components/DRY/_questdb_production_hardware-minimums.mdx" -## Hardware recommendations +## Quick reference - +| Component | Recommended | Notes | +|-----------|-------------|-------| +| Instance | `c3-standard-4` or `c3-highmem-8` | 4-8 vCPUs, 16-64 GiB RAM | +| Storage | Hyperdisk Balanced, 100+ GiB | 5000 IOPS / 300 MBps | +| File system | `zfs` with `lz4` | Or `ext4` if compression not needed | +| Ports | 9000, 8812, 9009, 9003 | Restrict to known IPs only | + +--- -### Google Compute Engine with Google Cloud Hyperdisk +## Infrastructure -Google Compute Engine offers a variety of VM instances tuned for different workloads. +Plan your infrastructure before launching. This section covers instance types, +storage, and networking requirements. + -Do **not** use instances containing the letter `A`, such as `C4A`. These are `ARM` architecture instances, -using Axion processors. +### Instance sizing -Either `AMD EPYC` CPUs (`D` letter) or `Intel Xeon` (no letter) are appropriate for `x86_64` deployments. +| Workload | Instance | vCPUs | RAM | Use case | +|----------|----------|-------|-----|----------| +| Development | `c3-standard-4` | 4 | 16 GiB | Testing, small datasets | +| Production (starter) | `c3-highmem-4` | 4 | 32 GiB | Light ingestion, moderate queries | +| Production (standard) | `c3-highmem-8` | 8 | 64 GiB | High ingestion, complex queries | +| Production (heavy) | `c3-highmem-22` | 22 | 176 GiB | Heavy workloads, large datasets | -We recommend starting with `C-Series` instances, and reviewing other instance types if your workload demands it. +**Choosing an instance family:** -You should deploy using an `x86_64` Linux distribution, such as Ubuntu. +Start with `C3` (Intel Xeon) or `C3D` (AMD EPYC) instances. Both perform +similarly for QuestDB. Choose based on availability and pricing in your region. -For storage, we recommend using [Hyperdisk Balanced](https://cloud.google.com/compute/docs/disks/hyperdisks) disks, -and provisioning them at `5000 IOPS/300 MBps` until you have tested your workload. +You can use the `highcpu`, `standard`, and `highmem` variants to adjust the +RAM-to-vCPU ratio between `2:1`, `4:1`, and `8:1`. Higher RAM can improve query +performance dramatically when it lets your working set fit entirely in memory. :::warning -Hyperdisk Balanced is not supported on all machine types. N2 instances do not -support Hyperdisk. Use N4, C3, or C4 series instances with Hyperdisk Balanced. +Do **not** use instances containing the letter `A`, such as `C4A`. These are +ARM architecture instances using Axion processors. QuestDB's JIT compilation and +SIMD optimizations are limited on ARM. Deploy on `x86_64` instances and an +`x86_64` Linux distribution such as Ubuntu. ::: -`Hyperdisk Extreme` generally requires much higher `vCPU` counts - for example, it cannot be used on `C3` machines -smaller than `88 vCPUs`. +### Storage - - - -### Google Filestore - -Google Filestore is a managed NFS service that can be used as a replication -transport layer in QuestDB Enterprise. +Use [Hyperdisk Balanced](https://cloud.google.com/compute/docs/disks/hyperdisks) +volumes, provisioned at `5000 IOPS / 300 MBps` until you have tested your +workload. Separate your OS disk (30 GiB) from your data disk. -Filestore should **not** be used as primary storage for QuestDB. However, it -is well-suited for replication when low latency is required. The `fs::` -transport over NFS provides sub-200ms replication lag with -[aggressive tuning](/docs/high-availability/tuning/), compared to ~1s+ with -object store transport (GCS). +| Workload | Disk | Size | IOPS | Throughput | +|----------|------|------|------|------------| +| Development | Hyperdisk Balanced | 100 GiB | 3000 | 140 MBps | +| Production | Hyperdisk Balanced | 300+ GiB | 5000 | 300 MBps | +| High I/O | Hyperdisk Balanced | 500+ GiB | 5000+ | 300+ MBps | -To use Filestore for replication: - -1. Create a Filestore instance in the same region as your QuestDB VMs -2. Mount the NFS share on both primary and replica nodes -3. Configure the `fs::` transport in `server.conf`: +:::warning +Hyperdisk Balanced is not supported on all machine types. N2 instances do not +support Hyperdisk. Use N4, C3, or C4 series instances with Hyperdisk Balanced. +::: -```ini -replication.object.store=fs::root=/mnt/questdb-repl/final;atomic_write_dir=/mnt/questdb-repl/scratch; -``` +`Hyperdisk Extreme` generally requires much higher vCPU counts. For example, it +cannot be used on `C3` machines smaller than `88 vCPUs`. -Use the [backup](/docs/operations/backup/) feature to manage WAL file retention -on the NFS mount. +**File system:** -On GKE, expose the Filestore share as a `PersistentVolume` with -`ReadWriteMany` access mode using the -[Filestore CSI driver](https://cloud.google.com/kubernetes-engine/docs/how-to/persistent-volumes/filestore-csi-driver), -so both primary and replica pods can mount it simultaneously. + -:::note -Filestore Zonal and Basic SSD tiers may require a -[quota increase](https://cloud.google.com/docs/quotas/view-manage) before use. -Basic HDD is typically available by default. -::: +Use `zfs` with `lz4` compression to reduce storage costs. If you don't need +compression, `ext4` or `xfs` offer slightly better performance. -### Google Cloud Storage +**Unsupported storage:** -QuestDB supports Google Cloud Storage as its replication object store in the -Enterprise edition. GCS is the simplest and cheapest replication transport, but -has higher latency (~1s+) due to object store API overhead. +- **Filestore** - Not supported as primary storage (NFS latency too high). Use + for Enterprise replication only (see [Enterprise on GCP](#enterprise-on-gcp)). +- **Google Cloud Storage** - Not supported as primary storage. Use for + Enterprise replication only. -To get started, create a bucket for the database to use. Then follow the -[Enterprise Quick Start](/docs/getting-started/enterprise-quick-start/) steps to create a connection string and -configure QuestDB. +### Networking -### NetApp Volumes +**Firewall rules:** -[NetApp Volumes](https://cloud.google.com/netapp/volumes/docs/discover/overview) -is a managed NFS service on GCP backed by NetApp ONTAP. Like Filestore, it can -be used as a low-latency replication transport via the `fs::` prefix. The -QuestDB configuration is identical to Filestore. +| Port | Protocol | Source | Purpose | +|------|----------|--------|---------| +| 22 | TCP | Your IP | SSH access | +| 9000 | TCP | Your IP / VPC | Web Console & REST API | +| 8812 | TCP | Your IP / VPC | PostgreSQL wire protocol | +| 9009 | TCP | Application servers | InfluxDB line protocol | +| 9003 | TCP | Monitoring servers | Health check & Prometheus | -:::note -NetApp Volumes requires enabling the `netapp.googleapis.com` API and may -require separate quota allocation. +:::warning +Never expose ports 9000, 8812, or 9009 to `0.0.0.0/0`. Restrict access to known +IP ranges or use an Identity-Aware Proxy (IAP) bastion. ::: -### Minimum specification +**VPC recommendations:** -- **Instance**: `c3-standard-4` or `c3d-standard-4` `(4 vCPUs, 16 GB RAM)` -- **Storage** - - **OS disk**: `Hyperdisk Balanced (30 GiB)` volume provisioned with `3000 IOPS/140 MBps`. - - **Data disk**: `Hyperdisk Balanced (100 GiB)` volume provisioned with `3000 IOPS/140 MBps`. -- **Operating System**: `Linux Ubuntu 24.04 LTS x86_64`. -- **File System**: `ext4` +- Deploy QuestDB in a private subnet +- Use Cloud NAT for outbound access (package updates, etc.) +- Use a network tag (this guide uses `questdb`) so one firewall rule applies to + every QuestDB instance you create +- Use Private Google Access for GCS if using Enterprise replication +--- -### Better specification +## Deployment -- **Instance**: `c3-highmem-8` or `c3d-highmem-8` `(8 vCPUs, 64 GB RAM)` -- **Storage** - - **OS disk**: `Hyperdisk Balanced (30 GiB)` volume provisioned with `5000 IOPS/300 MBps`. - - **Data disk**: `Hyperdisk Balanced (300 GiB)` volume provisioned with `5000 IOPS/300 MBps`. -- **Operating System**: `Linux Ubuntu 24.04 LTS x86_64`. -- **File System**: `zfs` +Deploy QuestDB on a Google Compute Engine virtual machine. :::note - -You can use the `highcpu` and `highmem` variants to adjust the `standard` `4:1` RAM/vCPU -ratio to `2:1` or `8:1` respectively. Higher RAM can improve performance dramatically -if it means your working set data will fit entirely into memory. - +Deploying QuestDB as a container at VM creation (the **Deploy Container** option +on Compute Engine) is no longer supported. Create a standard Linux VM and +install QuestDB over SSH as described below. ::: - -## Launching QuestDB on Google Compute Engine - -This guide describes how to run QuestDB on a new Google Cloud Platform (GCP) -Compute Engine instance. After completing this guide, you will have an instance -with QuestDB running in a container using the official QuestDB Docker image, as -well as a network rule that enables communication over HTTP and PostgreSQL wire -protocol. - ### Prerequisites - A [Google Cloud Platform](https://console.cloud.google.com/getting-started) - (GCP) account and a GCP Project + account and a GCP project - The [Compute Engine API](https://console.cloud.google.com/apis/api/compute.googleapis.com) - must be enabled for the corresponding Google Cloud Platform project + enabled for that project +- An SSH key registered with your project or account -### Create a Compute Engine VM +### Create the VM 1. In the Google Cloud Console, navigate to [Compute Engine](https://console.cloud.google.com/compute/instances) and click **Create Instance** -import Screenshot from "@theme/Screenshot" - -2. Give the instance a name - this example uses `questdb-europe-west3` -3. Choose a **Region** and **Zone** where you want to deploy the instance - this - example uses `europe-west3 (Frankfurt)` and the default zone -4. Choose a machine configuration. The default choice, `ec2-medium`, is a - general-purpose instance with 4GB memory and should be enough to run this - example. - - {" "} - -5. To add a running QuestDB container on instance startup, scroll down and click - the **Deploy Container** button. Then, provide the `latest` QuestDB Docker - image in the **Container image** textbox. - - ```text - questdb/questdb:latest - ``` - - Click the **Select** button at the bottom of the dropdown to complete the - container configuration. - - Your docker configuration should look like this: +2. Give the instance a name. This example uses `questdb-europe-west3` +3. Choose a **Region** and **Zone**. This example uses + `europe-west3 (Frankfurt)` and the default zone +4. Select a machine configuration (see [Instance sizing](#instance-sizing)) +5. Under **Boot disk**, click **Change** and choose **Ubuntu 24.04 LTS + (x86/64)** as the image +6. Set the boot disk type to **Hyperdisk Balanced** and the size to at least + `100 GiB` (see [Storage](#storage)) - {" "} + -Before creating the instance, we need to assign it a **Network tag** so that we -can add a firewall rule that exposes QuestDB-related ports to the internet. This -is required for you to access the database from outside your VPC. To create a -**Network tag**: +Before creating the instance, assign it a **Network tag** so a firewall rule can +expose the QuestDB ports: -1. Expand the **Advanced options** menu below the **firewall** section, and then - expand the **Networking** panel -2. In the **Networking** panel add a **Network tag** to identify the instance. - This example uses `questdb` +1. Expand the **Advanced options** menu, then expand the **Networking** panel +2. Add a **Network tag** to identify the instance. This example uses `questdb` -You can now launch the instance by clicking **Create** at the bottom of the -dialog. +Click **Create** at the bottom of the dialog to launch the instance. ### Create a firewall rule -Now that we've created our instance with a `questdb` network tag, we need to -create a corresponding firewall rule to associate with that tag. This rule will -expose the required ports for accessing QuestDB. With a network tag, we can -easily apply the new firewall rule to our newly created instance as well as any -other QuestDB instances that we create in the future. +The network tag lets a single firewall rule apply to this instance and any +future QuestDB instances you create with the same tag. 1. Navigate to the [Firewall configuration](https://console.cloud.google.com/net-security/firewall-manager/firewall-policies) - page under **Network Security** -> **Firewall policies** -2. Click the **Create firewall rule** button at the top of the page + page under **Network Security** → **Firewall policies** +2. Click **Create firewall rule** 3. Enter `questdb` in the **Name** field -4. Scroll down to the **Targets** dropdown and select "Specified target tags" -5. Enter `questdb` in the **Target tags** textbox. This will apply the firewall - rule to the new instance that was created above -6. Under **Source filter**, enter an IP range that this rule applies to. This - example uses `0.0.0.0/0`, which allows ingress from any IP address. We - recommend that you make this rule more restrictive, and naturally that you - include your current IP address within the chosen range. -7. In the **Protocols and ports** section, select **Specified protocols and - ports**, check the **TCP** option, and type `8812,9000` in the textbox. -8. Scroll down and click the **Create** button +4. Under **Targets**, select **Specified target tags** and enter `questdb` in + **Target tags** +5. Under **Source filter**, enter the IP range this rule applies to. Restrict + this to your own IP range rather than `0.0.0.0/0` (see + [Networking](#networking)) +6. Under **Protocols and ports**, select **Specified protocols and ports**, + check **TCP**, and enter `8812,9000` +7. Click **Create** -All VM instances on Compute Engine in this account which have the **Network -tag** `questdb` will now have this firewall rule applied. +:::warning +Only add port 9009 if you need ILP ingestion, and restrict the source to your +application servers. +::: + +### Install QuestDB -The ports we have opened are: +1. Connect to the instance over SSH. You can use the **SSH** button on the + [VM Instances](https://console.cloud.google.com/compute/instances) page, or + connect with `gcloud`: -- `9000` for the REST API and [Web Console](/docs/getting-started/web-console/overview/) -- `8812` for the PostgreSQL wire protocol +```bash +gcloud compute ssh questdb-europe-west3 --zone europe-west3-a +``` -## Verify the deployment +2. Download and start QuestDB: + + ( + +{`wget https://github.com/questdb/questdb/releases/download/${release.name}/questdb-${release.name}-rt-linux-x86-64.tar.gz +tar xzf questdb-${release.name}-rt-linux-x86-64.tar.gz +cd questdb-${release.name}-rt-linux-x86-64/bin +./questdb.sh start`} + +)} +/> -To verify that the instance is running, navigate to **Compute Engine** -> -[VM Instances](https://console.cloud.google.com/compute/instances). A status -indicator should show the instance as **running**: +3. Access the Web Console at `http://:9000`, using the instance's + **External IP** from the VM Instances page -To verify that the QuestDB deployment is operating as expected: +You can also send a request to the REST API on port 9000: -1. Copy the **External IP** of the instance -2. Navigate to `http://:9000` in a browser +```bash +curl -G \ + --data-urlencode "query=SELECT * FROM telemetry_config" \ + :9000/exec +``` -The [Web Console](/docs/getting-started/web-console/overview/) should now be visible: +For production deployments, use [systemd](/docs/deployment/systemd/) to manage +the QuestDB service. - ( + +{`wget https://github.com/questdb/questdb/releases/download/${release.name}/questdb-${release.name}-rt-linux-x86-64.tar.gz +tar xzf questdb-${release.name}-rt-linux-x86-64.tar.gz`} + +)} /> -Alternatively, a request may be sent to the REST API exposed on port 9000: +4. Start the new version: + ```bash + cd questdb-*/bin + ./questdb.sh start + ``` + +### Monitoring + +**Health check:** ```bash -curl -G \ - --data-urlencode "query=SELECT * FROM telemetry_config" \ - :9000/exec +curl http://localhost:9003/status ``` -### Set up GCP with Pulumi - -If you're using [Pulumi](https://www.pulumi.com/gcp/) to manage your -infrastructure, you can create a QuestDB instance with the following: - -```python -import pulumi -import pulumi_gcp as gcp - -# Create a Google Cloud Network -firewall = gcp.compute.Firewall( - "questdb-firewall", - network="default", - allows=[ - gcp.compute.FirewallAllowArgs( - protocol="tcp", - ports=["9000", "8812"], - ), - ], - target_tags=["questdb"], - source_ranges=["0.0.0.0/0"], -) - -# Create a Compute Engine Instance -instance = gcp.compute.Instance( - "questdb-instance", - machine_type="e2-medium", - zone="us-central1-a", - boot_disk={ - "initialize_params": { - "image": "ubuntu-os-cloud/ubuntu-2004-lts", - }, - }, - network_interfaces=[ - gcp.compute.InstanceNetworkInterfaceArgs( - network="default", - access_configs=[{}], # Ephemeral public IP - ) - ], - metadata_startup_script="""#!/bin/bash - sudo apt-get update - sudo apt-get install -y docker.io - sudo docker run -d -p 9000:9000 -p 8812:8812 \ - --env QDB_HTTP_USER="admin" \ - --env QDB_HTTP_PASSWORD="quest" \ - questdb/questdb - """, - tags=["questdb"], -) - -# Export the instance's name and public IP -pulumi.export("instanceName", instance.name) -pulumi.export("instance_ip", instance.network_interfaces[0].access_configs[0].nat_ip) +**Prometheus metrics:** + +```bash +curl http://localhost:9003/metrics ``` + +**Cloud Monitoring integration:** + +Use the Ops Agent to collect: +- VM metrics (CPU, memory, disk I/O) +- QuestDB logs from the `log/` directory +- Custom metrics from the Prometheus endpoint + +--- + +## Enterprise on GCP + +QuestDB Enterprise adds production features for GCP: + +- **GCS replication** - Continuous backup for durability +- **Cold storage** - Move old partitions to GCS, query on-demand +- **High availability** - Automatic failover across instances + +GCP offers two low-latency NFS services that can act as a replication transport +via the `fs::` prefix, as an alternative to GCS: + +- **Google Filestore** - a managed NFS service. The `fs::` transport over NFS + provides sub-200ms replication lag with + [aggressive tuning](/docs/high-availability/tuning/), compared to ~1s+ with + the GCS object store transport. +- **[NetApp Volumes](https://cloud.google.com/netapp/volumes/docs/discover/overview)** - + a managed NFS service backed by NetApp ONTAP. The QuestDB configuration is + identical to Filestore. + +To use Filestore or NetApp Volumes for replication: + +1. Create the instance in the same region as your QuestDB VMs +2. Mount the NFS share on both primary and replica nodes +3. Configure the `fs::` transport in `server.conf`: + +```ini +replication.object.store=fs::root=/mnt/questdb-repl/final;atomic_write_dir=/mnt/questdb-repl/scratch; +``` + +Use the [backup](/docs/operations/backup/) feature to manage WAL file retention +on the NFS mount. On GKE, expose the share as a `PersistentVolume` with +`ReadWriteMany` access mode using the +[Filestore CSI driver](https://cloud.google.com/kubernetes-engine/docs/how-to/persistent-volumes/filestore-csi-driver) +so both primary and replica pods can mount it simultaneously. + +:::note +Filestore Zonal and Basic SSD tiers may require a +[quota increase](https://cloud.google.com/docs/quotas/view-manage) before use, +and NetApp Volumes requires enabling the `netapp.googleapis.com` API. +::: + +For GCS replication, create a bucket for the database, then follow the +[Enterprise Quick Start](/docs/getting-started/enterprise-quick-start/) to +create a connection string and configure QuestDB. + +See [Enterprise Quick Start](/docs/getting-started/enterprise-quick-start/) for setup. diff --git a/static/images/guides/google-cloud-platform/create-vm-docker.webp b/static/images/guides/google-cloud-platform/create-vm-docker.webp deleted file mode 100644 index c630f2d2a45415fab99d198a2c252a7f2f915305..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33638 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 H00000PtTho diff --git a/static/images/guides/google-cloud-platform/instance-available.webp b/static/images/guides/google-cloud-platform/instance-available.webp deleted file mode 100644 index e5f766784655201d396c34962bd6227025d37ee2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10066 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 J|NAco_CEr!$|?W= From f979dff204780bc4c29d4a2249570622d948345c Mon Sep 17 00:00:00 2001 From: Steven Sklar Date: Wed, 17 Jun 2026 13:13:56 -0400 Subject: [PATCH 2/5] Drop duplicate file system note (covered by FileSystemChoice) Co-Authored-By: Claude Opus 4.8 (1M context) --- documentation/deployment/gcp.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/documentation/deployment/gcp.md b/documentation/deployment/gcp.md index beef45492..8f3970dae 100644 --- a/documentation/deployment/gcp.md +++ b/documentation/deployment/gcp.md @@ -78,9 +78,6 @@ cannot be used on `C3` machines smaller than `88 vCPUs`. -Use `zfs` with `lz4` compression to reduce storage costs. If you don't need -compression, `ext4` or `xfs` offer slightly better performance. - **Unsupported storage:** - **Filestore** - Not supported as primary storage (NFS latency too high). Use From 91917efa60f162142466744aa992270241725a40 Mon Sep 17 00:00:00 2001 From: Steven Sklar Date: Wed, 17 Jun 2026 13:33:11 -0400 Subject: [PATCH 3/5] Clarify GCP VM deployment instructions --- documentation/deployment/gcp.md | 220 ++++++++++++++++++++++++++------ 1 file changed, 183 insertions(+), 37 deletions(-) diff --git a/documentation/deployment/gcp.md b/documentation/deployment/gcp.md index 8f3970dae..0de25cf18 100644 --- a/documentation/deployment/gcp.md +++ b/documentation/deployment/gcp.md @@ -16,9 +16,13 @@ import MinimumHardware from "../../src/components/DRY/_questdb_production_hardwa | Component | Recommended | Notes | |-----------|-------------|-------| | Instance | `c3-standard-4` or `c3-highmem-8` | 4-8 vCPUs, 16-64 GiB RAM | -| Storage | Hyperdisk Balanced, 100+ GiB | 5000 IOPS / 300 MBps | +| Storage | Hyperdisk Balanced data disk, 300+ GiB | 5000 IOPS / 300 MBps for production | | File system | `zfs` with `lz4` | Or `ext4` if compression not needed | | Ports | 9000, 8812, 9009, 9003 | Restrict to known IPs only | +| QuestDB root | `/var/lib/questdb` | Mount the data disk here | + +The screenshots in this guide are visual confirmation only. The numbered steps +and command blocks contain the complete deployment instructions. --- @@ -57,8 +61,9 @@ SIMD optimizations are limited on ARM. Deploy on `x86_64` instances and an ### Storage Use [Hyperdisk Balanced](https://cloud.google.com/compute/docs/disks/hyperdisks) -volumes, provisioned at `5000 IOPS / 300 MBps` until you have tested your -workload. Separate your OS disk (30 GiB) from your data disk. +volumes for QuestDB data, provisioned at `5000 IOPS / 300 MBps` until you have +tested your workload. Keep the OS disk separate from the QuestDB data disk, and +mount the data disk at `/var/lib/questdb`. | Workload | Disk | Size | IOPS | Throughput | |----------|------|------|------|------------| @@ -130,6 +135,26 @@ install QuestDB over SSH as described below. [Compute Engine API](https://console.cloud.google.com/apis/api/compute.googleapis.com) enabled for that project - An SSH key registered with your project or account +- The [Google Cloud CLI](https://cloud.google.com/sdk/docs/install) if you want + to use the `gcloud` commands instead of the console +- A client source CIDR for firewall rules, such as your workstation IP address + with `/32`. Do not use `0.0.0.0/0` for QuestDB ports. + +This guide uses the following example values. Replace them consistently if you +choose different names, regions, zones, or CIDR ranges. + +| Setting | Example value | Used for | +|---------|---------------|----------| +| Instance name | `questdb-europe-west3` | VM name | +| Region | `europe-west3` | GCP region | +| Zone | `europe-west3-a` | VM and disk zone | +| Machine type | `c3-standard-4` | Development or small workloads | +| Network tag | `questdb` | Firewall rule target | +| Data disk name | `questdb-data` | Hyperdisk Balanced data disk | +| Data disk device | `/dev/disk/by-id/google-questdb-data` | Stable Linux device path | +| QuestDB install directory | `/opt/questdb` | Extracted QuestDB release | +| QuestDB root directory | `/var/lib/questdb` | Configuration, logs, and table data | +| Client source range | `YOUR_CLIENT_IP/32` | Firewall source range | ### Create the VM @@ -150,8 +175,15 @@ install QuestDB over SSH as described below. 4. Select a machine configuration (see [Instance sizing](#instance-sizing)) 5. Under **Boot disk**, click **Change** and choose **Ubuntu 24.04 LTS (x86/64)** as the image -6. Set the boot disk type to **Hyperdisk Balanced** and the size to at least - `100 GiB` (see [Storage](#storage)) +6. Set the boot disk type to **Hyperdisk Balanced** and the size to `30 GiB` +7. Add a separate blank **Hyperdisk Balanced** data disk: + - Set **Name** to `questdb-data` + - Set **Size** to `300 GiB` for production, or `100 GiB` for development + - Set **Provisioned IOPS** to `5000` + - Set **Provisioned throughput** to `300 MBps` + - Set **Deletion rule** to **Keep disk** if you want the data disk to survive + instance deletion + - Set the device name to `questdb-data` ( -{`wget https://github.com/questdb/questdb/releases/download/${release.name}/questdb-${release.name}-rt-linux-x86-64.tar.gz -tar xzf questdb-${release.name}-rt-linux-x86-64.tar.gz -cd questdb-${release.name}-rt-linux-x86-64/bin -./questdb.sh start`} +{`export QDB_INSTALL_DIR="/opt/questdb" +export QDB_RELEASE_DIR="/opt/questdb-${release.name}" +export QDB_ROOT="/var/lib/questdb" + +wget "https://github.com/questdb/questdb/releases/download/${release.name}/questdb-${release.name}-rt-linux-x86-64.tar.gz" +sudo mkdir -p "$QDB_RELEASE_DIR" +sudo chown "$USER:$USER" "$QDB_RELEASE_DIR" +tar xzf "questdb-${release.name}-rt-linux-x86-64.tar.gz" -C "$QDB_RELEASE_DIR" --strip-components=1 +sudo ln -sfn "$QDB_RELEASE_DIR" "$QDB_INSTALL_DIR" +"$QDB_INSTALL_DIR/bin/questdb.sh" start -d "$QDB_ROOT" -n +"$QDB_INSTALL_DIR/bin/questdb.sh" status -d "$QDB_ROOT"`} )} /> -3. Access the Web Console at `http://:9000`, using the instance's - **External IP** from the VM Instances page +Access the Web Console at `http://:9000`, using the instance's +**External IP** from the VM Instances page. :9000/exec + "http://:9000/exec" ``` +The deployment is working when: + +- `questdb.sh status -d /var/lib/questdb` reports the service as running +- `curl http://localhost:9003/status` returns `Status: Healthy` from the VM +- `http://:9000` loads the Web Console from an allowed source IP + For production deployments, use [systemd](/docs/deployment/systemd/) to manage the QuestDB service. @@ -258,35 +380,38 @@ the QuestDB service. Update credentials immediately after deployment. -**Web Console and REST API** - edit `conf/server.conf`: +**Web Console and REST API** - edit `/var/lib/questdb/conf/server.conf`: ```ini http.user=your_username http.password=your_secure_password ``` -**PostgreSQL** - edit `conf/server.conf`: +**PostgreSQL** - edit `/var/lib/questdb/conf/server.conf`: ```ini pg.user=your_username pg.password=your_secure_password ``` -**InfluxDB line protocol** - edit `conf/auth.json`. See +**InfluxDB line protocol** - edit `/var/lib/questdb/conf/auth.json`. See [ILP authentication](/docs/ingestion/ilp/overview/#authentication). Restart after changes: ```bash -./questdb.sh stop -./questdb.sh start +export QDB_INSTALL_DIR="/opt/questdb" +export QDB_ROOT="/var/lib/questdb" + +"$QDB_INSTALL_DIR/bin/questdb.sh" stop -d "$QDB_ROOT" +"$QDB_INSTALL_DIR/bin/questdb.sh" start -d "$QDB_ROOT" -n ``` ### Disable unused interfaces Reduce attack surface by disabling protocols you don't use: -```ini title="conf/server.conf" +```ini title="/var/lib/questdb/conf/server.conf" pg.enabled=false # Disable PostgreSQL line.tcp.enabled=false # Disable ILP http.enabled=false # Disable Web Console & REST API @@ -299,29 +424,50 @@ http.security.readonly=true # Or make HTTP read-only ### Upgrading -1. Stop QuestDB: - ```bash - ./questdb.sh stop - ``` +1. On the VM, stop QuestDB: + +```bash +export QDB_INSTALL_DIR="/opt/questdb" +export QDB_ROOT="/var/lib/questdb" + +"$QDB_INSTALL_DIR/bin/questdb.sh" stop -d "$QDB_ROOT" +``` + +2. From Cloud Shell or another shell with `gcloud` configured, create a disk + snapshot before changing binaries: -2. Back up your data directory +```bash +gcloud compute disks snapshot "questdb-data" \ + --zone "europe-west3-a" \ + --snapshot-names "questdb-data-pre-upgrade-$(date +%Y%m%d%H%M%S)" +``` -3. Download and extract the new version: +3. On the VM, download and extract the new version: ( -{`wget https://github.com/questdb/questdb/releases/download/${release.name}/questdb-${release.name}-rt-linux-x86-64.tar.gz -tar xzf questdb-${release.name}-rt-linux-x86-64.tar.gz`} +{`export QDB_INSTALL_DIR="/opt/questdb" +export QDB_RELEASE_DIR="/opt/questdb-${release.name}" + +wget "https://github.com/questdb/questdb/releases/download/${release.name}/questdb-${release.name}-rt-linux-x86-64.tar.gz" +sudo mkdir -p "$QDB_RELEASE_DIR" +sudo chown "$USER:$USER" "$QDB_RELEASE_DIR" +tar xzf "questdb-${release.name}-rt-linux-x86-64.tar.gz" -C "$QDB_RELEASE_DIR" --strip-components=1 +sudo ln -sfn "$QDB_RELEASE_DIR" "$QDB_INSTALL_DIR"`} )} /> -4. Start the new version: - ```bash - cd questdb-*/bin - ./questdb.sh start - ``` +4. Start QuestDB with the same root directory and check status: + +```bash +export QDB_INSTALL_DIR="/opt/questdb" +export QDB_ROOT="/var/lib/questdb" + +"$QDB_INSTALL_DIR/bin/questdb.sh" start -d "$QDB_ROOT" -n +"$QDB_INSTALL_DIR/bin/questdb.sh" status -d "$QDB_ROOT" +``` ### Monitoring @@ -341,7 +487,7 @@ curl http://localhost:9003/metrics Use the Ops Agent to collect: - VM metrics (CPU, memory, disk I/O) -- QuestDB logs from the `log/` directory +- QuestDB logs from `/var/lib/questdb/log/` - Custom metrics from the Prometheus endpoint --- From 7d032bca126151b64e149e14bac783f8cfa992f5 Mon Sep 17 00:00:00 2001 From: Steven Sklar Date: Wed, 17 Jun 2026 13:45:25 -0400 Subject: [PATCH 4/5] Align GCP security and operations sections --- documentation/deployment/gcp.md | 104 +++++++++----------------------- 1 file changed, 27 insertions(+), 77 deletions(-) diff --git a/documentation/deployment/gcp.md b/documentation/deployment/gcp.md index 0de25cf18..faf9baa8a 100644 --- a/documentation/deployment/gcp.md +++ b/documentation/deployment/gcp.md @@ -19,10 +19,6 @@ import MinimumHardware from "../../src/components/DRY/_questdb_production_hardwa | Storage | Hyperdisk Balanced data disk, 300+ GiB | 5000 IOPS / 300 MBps for production | | File system | `zfs` with `lz4` | Or `ext4` if compression not needed | | Ports | 9000, 8812, 9009, 9003 | Restrict to known IPs only | -| QuestDB root | `/var/lib/questdb` | Mount the data disk here | - -The screenshots in this guide are visual confirmation only. The numbered steps -and command blocks contain the complete deployment instructions. --- @@ -140,22 +136,6 @@ install QuestDB over SSH as described below. - A client source CIDR for firewall rules, such as your workstation IP address with `/32`. Do not use `0.0.0.0/0` for QuestDB ports. -This guide uses the following example values. Replace them consistently if you -choose different names, regions, zones, or CIDR ranges. - -| Setting | Example value | Used for | -|---------|---------------|----------| -| Instance name | `questdb-europe-west3` | VM name | -| Region | `europe-west3` | GCP region | -| Zone | `europe-west3-a` | VM and disk zone | -| Machine type | `c3-standard-4` | Development or small workloads | -| Network tag | `questdb` | Firewall rule target | -| Data disk name | `questdb-data` | Hyperdisk Balanced data disk | -| Data disk device | `/dev/disk/by-id/google-questdb-data` | Stable Linux device path | -| QuestDB install directory | `/opt/questdb` | Extracted QuestDB release | -| QuestDB root directory | `/var/lib/questdb` | Configuration, logs, and table data | -| Client source range | `YOUR_CLIENT_IP/32` | Firewall source range | - ### Create the VM 1. In the Google Cloud Console, navigate to @@ -324,23 +304,17 @@ After this step, QuestDB configuration, logs, and table data will live under ### Install QuestDB -Download QuestDB, extract it to a stable install directory, and start it with -`/var/lib/questdb` as the QuestDB root directory: +Download QuestDB and start it with `/var/lib/questdb` as the QuestDB root +directory: ( -{`export QDB_INSTALL_DIR="/opt/questdb" -export QDB_RELEASE_DIR="/opt/questdb-${release.name}" -export QDB_ROOT="/var/lib/questdb" - -wget "https://github.com/questdb/questdb/releases/download/${release.name}/questdb-${release.name}-rt-linux-x86-64.tar.gz" -sudo mkdir -p "$QDB_RELEASE_DIR" -sudo chown "$USER:$USER" "$QDB_RELEASE_DIR" -tar xzf "questdb-${release.name}-rt-linux-x86-64.tar.gz" -C "$QDB_RELEASE_DIR" --strip-components=1 -sudo ln -sfn "$QDB_RELEASE_DIR" "$QDB_INSTALL_DIR" -"$QDB_INSTALL_DIR/bin/questdb.sh" start -d "$QDB_ROOT" -n -"$QDB_INSTALL_DIR/bin/questdb.sh" status -d "$QDB_ROOT"`} +{`wget https://github.com/questdb/questdb/releases/download/${release.name}/questdb-${release.name}-rt-linux-x86-64.tar.gz +tar xzf questdb-${release.name}-rt-linux-x86-64.tar.gz +cd questdb-${release.name}-rt-linux-x86-64/bin +./questdb.sh start -d /var/lib/questdb +./questdb.sh status -d /var/lib/questdb`} )} /> @@ -380,38 +354,35 @@ the QuestDB service. Update credentials immediately after deployment. -**Web Console and REST API** - edit `/var/lib/questdb/conf/server.conf`: +**Web Console and REST API** - edit `conf/server.conf`: ```ini http.user=your_username http.password=your_secure_password ``` -**PostgreSQL** - edit `/var/lib/questdb/conf/server.conf`: +**PostgreSQL** - edit `conf/server.conf`: ```ini pg.user=your_username pg.password=your_secure_password ``` -**InfluxDB line protocol** - edit `/var/lib/questdb/conf/auth.json`. See +**InfluxDB line protocol** - edit `conf/auth.json`. See [ILP authentication](/docs/ingestion/ilp/overview/#authentication). Restart after changes: ```bash -export QDB_INSTALL_DIR="/opt/questdb" -export QDB_ROOT="/var/lib/questdb" - -"$QDB_INSTALL_DIR/bin/questdb.sh" stop -d "$QDB_ROOT" -"$QDB_INSTALL_DIR/bin/questdb.sh" start -d "$QDB_ROOT" -n +./questdb.sh stop -d /var/lib/questdb +./questdb.sh start -d /var/lib/questdb ``` ### Disable unused interfaces Reduce attack surface by disabling protocols you don't use: -```ini title="/var/lib/questdb/conf/server.conf" +```ini title="conf/server.conf" pg.enabled=false # Disable PostgreSQL line.tcp.enabled=false # Disable ILP http.enabled=false # Disable Web Console & REST API @@ -424,50 +395,29 @@ http.security.readonly=true # Or make HTTP read-only ### Upgrading -1. On the VM, stop QuestDB: +1. Stop QuestDB: + ```bash + ./questdb.sh stop -d /var/lib/questdb + ``` -```bash -export QDB_INSTALL_DIR="/opt/questdb" -export QDB_ROOT="/var/lib/questdb" - -"$QDB_INSTALL_DIR/bin/questdb.sh" stop -d "$QDB_ROOT" -``` +2. Back up your data directory -2. From Cloud Shell or another shell with `gcloud` configured, create a disk - snapshot before changing binaries: - -```bash -gcloud compute disks snapshot "questdb-data" \ - --zone "europe-west3-a" \ - --snapshot-names "questdb-data-pre-upgrade-$(date +%Y%m%d%H%M%S)" -``` - -3. On the VM, download and extract the new version: +3. Download and extract the new version: ( -{`export QDB_INSTALL_DIR="/opt/questdb" -export QDB_RELEASE_DIR="/opt/questdb-${release.name}" - -wget "https://github.com/questdb/questdb/releases/download/${release.name}/questdb-${release.name}-rt-linux-x86-64.tar.gz" -sudo mkdir -p "$QDB_RELEASE_DIR" -sudo chown "$USER:$USER" "$QDB_RELEASE_DIR" -tar xzf "questdb-${release.name}-rt-linux-x86-64.tar.gz" -C "$QDB_RELEASE_DIR" --strip-components=1 -sudo ln -sfn "$QDB_RELEASE_DIR" "$QDB_INSTALL_DIR"`} +{`wget https://github.com/questdb/questdb/releases/download/${release.name}/questdb-${release.name}-rt-linux-x86-64.tar.gz +tar xzf questdb-${release.name}-rt-linux-x86-64.tar.gz`} )} /> -4. Start QuestDB with the same root directory and check status: - -```bash -export QDB_INSTALL_DIR="/opt/questdb" -export QDB_ROOT="/var/lib/questdb" - -"$QDB_INSTALL_DIR/bin/questdb.sh" start -d "$QDB_ROOT" -n -"$QDB_INSTALL_DIR/bin/questdb.sh" status -d "$QDB_ROOT" -``` +4. Start the new version: + ```bash + cd questdb-*/bin + ./questdb.sh start -d /var/lib/questdb + ``` ### Monitoring @@ -487,7 +437,7 @@ curl http://localhost:9003/metrics Use the Ops Agent to collect: - VM metrics (CPU, memory, disk I/O) -- QuestDB logs from `/var/lib/questdb/log/` +- QuestDB logs from the `log/` directory - Custom metrics from the Prometheus endpoint --- From 00eaff8fbbdc9a97387e2fd6503d2c55355b740f Mon Sep 17 00:00:00 2001 From: Steven Sklar Date: Wed, 17 Jun 2026 15:38:56 -0400 Subject: [PATCH 5/5] Align GCP filesystem guidance and fix deployment nits - Make the page consistently recommend ext4 as the default file system, with zfs/lz4 noted as the option for on-disk compression. Replace the zfs-leading FileSystemChoice partial with GCP-specific inline text and drop the now-unused import. - Clarify that the firewall rule opens only 9000/8812; 9009 is for ILP and 9003 should be reached over the VPC or SSH. - Normalize gcloud disk sizes to GiB to match the console steps and tables. - Remove a duplicate Enterprise Quick Start link. Co-Authored-By: Claude Opus 4.8 (1M context) --- documentation/deployment/gcp.md | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/documentation/deployment/gcp.md b/documentation/deployment/gcp.md index faf9baa8a..6d1c019a1 100644 --- a/documentation/deployment/gcp.md +++ b/documentation/deployment/gcp.md @@ -8,7 +8,6 @@ description: import Screenshot from "@theme/Screenshot" import InterpolateReleaseData from "../../src/components/InterpolateReleaseData" import CodeBlock from "@theme/CodeBlock" -import FileSystemChoice from "../../src/components/DRY/_questdb_file_system_choice.mdx" import MinimumHardware from "../../src/components/DRY/_questdb_production_hardware-minimums.mdx" ## Quick reference @@ -17,7 +16,7 @@ import MinimumHardware from "../../src/components/DRY/_questdb_production_hardwa |-----------|-------------|-------| | Instance | `c3-standard-4` or `c3-highmem-8` | 4-8 vCPUs, 16-64 GiB RAM | | Storage | Hyperdisk Balanced data disk, 300+ GiB | 5000 IOPS / 300 MBps for production | -| File system | `zfs` with `lz4` | Or `ext4` if compression not needed | +| File system | `ext4` | Or `zfs` with `lz4` for on-disk compression | | Ports | 9000, 8812, 9009, 9003 | Restrict to known IPs only | --- @@ -77,7 +76,9 @@ cannot be used on `C3` machines smaller than `88 vCPUs`. **File system:** - +Format the data disk as `ext4`. If you need on-disk compression, use `zfs` with +`lz4` instead, at a small performance cost. See +[ZFS compression](/docs/deployment/compression-zfs/). **Unsupported storage:** @@ -98,6 +99,10 @@ cannot be used on `C3` machines smaller than `88 vCPUs`. | 9009 | TCP | Application servers | InfluxDB line protocol | | 9003 | TCP | Monitoring servers | Health check & Prometheus | +The firewall rule below opens only 9000 and 8812. Add 9009 only if you ingest +over ILP, and reach 9003 from within the VPC or over SSH rather than exposing +it publicly. + :::warning Never expose ports 9000, 8812, or 9009 to `0.0.0.0/0`. Restrict access to known IP ranges or use an Identity-Aware Proxy (IAP) bastion. @@ -202,13 +207,13 @@ gcloud compute instances create "$QDB_INSTANCE" \ --machine-type "$QDB_MACHINE_TYPE" \ --image-family "ubuntu-2404-lts-amd64" \ --image-project "ubuntu-os-cloud" \ - --boot-disk-size "30GB" \ + --boot-disk-size "30GiB" \ --boot-disk-type "hyperdisk-balanced" \ --tags "$QDB_TAG" gcloud compute disks create "$QDB_DISK" \ --zone "$QDB_ZONE" \ - --size "300GB" \ + --size "300GiB" \ --type "hyperdisk-balanced" \ --provisioned-iops "5000" \ --provisioned-throughput "300" \ @@ -276,7 +281,9 @@ gcloud compute ssh questdb-europe-west3 --zone europe-west3-a ### Prepare the data disk Run these commands on the VM over SSH. They assume the attached data disk uses -the custom device name `questdb-data`. +the custom device name `questdb-data` and format it as `ext4`, which is the +recommended default. If you need on-disk compression, format the data disk as +`zfs` with `lz4` instead. See [ZFS compression](/docs/deployment/compression-zfs/). :::warning The `mkfs.ext4` command erases the target device. Run it only on a new blank @@ -486,5 +493,3 @@ and NetApp Volumes requires enabling the `netapp.googleapis.com` API. For GCS replication, create a bucket for the database, then follow the [Enterprise Quick Start](/docs/getting-started/enterprise-quick-start/) to create a connection string and configure QuestDB. - -See [Enterprise Quick Start](/docs/getting-started/enterprise-quick-start/) for setup.