> ## Documentation Index
> Fetch the complete documentation index at: https://docs.firebolt.io/llms.txt
> Use this file to discover all available pages before exploring further.

<AgentInstructions>

## Submitting Feedback

If you encounter incorrect, outdated, or confusing documentation on this page, submit feedback:

POST https://docs.firebolt.io/feedback

```json
{
  "path": "/firebolt-core/firebolt-core-operation/firebolt-core-deployment-k8s",
  "feedback": "Description of the issue"
}
```

Only submit feedback when you have something specific and actionable to report.

</AgentInstructions>

# Deployment on Kubernetes

Firebolt Core can be deployed to a Kubernetes cluster (version 1.19 or newer) using the [provided Helm chart](https://github.com/firebolt-db/firebolt-core/tree/main/helm). This section provides a step-by-step guide to get a working deployment up and running.

## Prerequisites

Before you begin, ensure that you have the following installed and configured:

* A [Kubernetes](https://kubernetes.io/) cluster (v1.19+)
* `kubectl` command-line tool configured to access your cluster
* `helm` (v3+) installed on your local machine

Additionally, you will need one of these configurations:

1. Kubernetes nodes with a memlock limit of at least 8GB (you can check with `cat /proc/self/limits | grep -F 'Max locked memory'`)
2. possibility to run Core with the helper root container (`memlockSetup=true` in Helm values)

The memlock setup helper root container is enabled by default, if you are using configuration (1) the container will be idle and do nothing, you can disable it using `memlockSetup=false` so that there are no root containers in your deployments.

## 1: Create a Dedicated Namespace

To isolate Firebolt Core resources from other workloads in your cluster, create a dedicated Kubernetes namespace:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
kubectl create namespace firebolt-core
```

This will create a logical grouping for all resources related to Firebolt Core, making it easier to manage and clean up later.

## 2: Customize Helm Chart Values

The deployment is configured via Helm chart values. You can modify these by editing a `values.yaml` file or by setting them directly via the `--set` flag.

For example, to deploy a 3-node cluster, ensure the `nodesCount` value is set to `3`; the memory allocation and storage allocation should also be increased for any serious workload you are planning to run.
It is advised to not use the default `preview-rc` value for the `image.tag` and instead pick a released pinned version from the [GHCR repository](https://github.com/firebolt-db/firebolt-core/pkgs/container/firebolt-core).

Refer to the [Helm Chart README](https://github.com/firebolt-db/firebolt-core/blob/main/helm/README.md) for the complete list of configurable parameters, including resource limits, storage options, and networking settings.

One of the most important values is `useStatefulSet`: when explicitly set to `false` it will cause the Helm chart to use 1 Kubernetes deployment per node, which facilitates operations like image updates and [scaling up/down](#scaling-up/down).

When `useStatefulSet=true` (the default), the Helm chart creates a headless service alongside the StatefulSet. This gives each pod a stable, fully-qualified domain name (FQDN) resolved via [CoreDNS](https://coredns.io/) — the same service discovery pattern used by most databases on Kubernetes (PostgreSQL, Cassandra, Kafka, and others). When `useStatefulSet=false`, each node runs as a separate Deployment and is addressed through its own ClusterIP service.

## 3: Install the Helm Chart

Once your values are configured, install the chart into the `firebolt-core` namespace:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
helm install core-demo helm/ -n firebolt-core --set nodesCount=3
```

Instead of `core-demo` you can use any name you prefer, it will be used as a prefix for the generated Kubernetes resources; the `--generate-name` flag can also be specified and it will let Helm automatically generate a release name.

## 4: Verify the Deployment

After installation, verify that the Firebolt Core pods are up and running:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
kubectl get pods -n firebolt-core
```

You should see output similar to the following, depending on your `nodesCount` value:

```
NAME                        READY   STATUS    RESTARTS   AGE
core-demo-firebolt-core-0   2/2     Running   0          50s
core-demo-firebolt-core-1   2/2     Running   0          50s
core-demo-firebolt-core-2   2/2     Running   0          50s
```

If the pods are **not** in the `Running` state, check their logs and events for troubleshooting:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
kubectl describe pod <pod-name> -n firebolt-core
kubectl logs <pod-name> -n firebolt-core
```

## 5: Querying locally

You can interact with Firebolt Core locally by port-forwarding the HTTP interface port (default: `3473`) from one of the pods to your local machine. This enables you to send SQL queries directly via `curl` without exposing the service externally. To do this, run:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
kubectl port-forward pod/core-demo-firebolt-core-0 3473:3473 -n firebolt-core
```

Replace `core-demo-firebolt-core-0` with the name of one of the running Firebolt Core pods.

Once forwarded, you can issue SQL queries using `curl`, for example:

```
curl -s "http://localhost:3473" --data-binary "select 42";
```

This approach is particularly useful for local testing and debugging.

## 6. Operations

Monitor IOPS usage on storage volumes to avoid slowdowns and latencies. For a full discussion of failure modes and recovery behavior, see [Fault tolerance](/firebolt-core/firebolt-core-operation/firebolt-core-fault-tolerance).

### Volume backup

No built-in backup mechanism is provided. The **node 0 persistent volume** is the only volume that always requires backup: it holds the SQLite metadata store containing the entire database catalog (schemas, table definitions, indexes).

When object storage is configured, data volumes on non-zero nodes hold only a local cache of tablet data — the authoritative copy is in object storage, so those volumes do not need to be backed up separately.

When object storage is **not** configured, data volumes on non-zero nodes are the only copy of their tablets. In this case, back up all node volumes, or ensure data can be fully re-ingested from the original source if a volume is lost.

It is strongly recommended to configure regular snapshots or backups of the node 0 persistent volume using your storage infrastructure or Kubernetes-native tooling.

<Note>
  A future version of Firebolt Core will manage metadata through PostgreSQL, which has its own backup and recovery ecosystem. At that point, dedicated volume-level backups for metadata will no longer be necessary.
</Note>

### Scaling up/down

When object storage is configured, scaling does not risk data loss — all table data remains in the object store. Update `nodesCount` in your Helm values and run `helm upgrade` (requires `useStatefulSet=false`); nodes restart and rehydrate from object storage.

When object storage is **not** configured, changing the number of nodes is only safe for clusters that are not using locally managed tables. For any other case it will be necessary to erase data volumes during the scaling operation, otherwise data inconsistency will occur.

### Changing resources

You can run `helm upgrade` to apply changes to your cluster after changing resources like memory or CPU allocation.

Note that it is not possible to resize storage volumes this way.

### Updating Firebolt Core version

After changing the `image.tag` value to a more recent pinned version you can run a `helm upgrade` to automatically roll out the change to your Firebolt Core cluster:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
helm upgrade core-demo helm -n firebolt-core
```

Afterwards, if you are using the default `useStatefulSet=true`, it will be necessary to delete all pods:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
kubectl delete pods -n firebolt-core -l app.kubernetes.io/name=core-demo-firebolt-core
```

⚠️ Make sure you are using a label which deletes pods only of the Core cluster you intend to update, if you have multiple Core clusters in the same namespace they will all be affected when using `app.kubernetes.io/name=firebolt-core` in the example above.

### Removing the deployment

You can use:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
helm uninstall core-demo -n firebolt-core
```

If you are using the default `useStatefulSet=true` the created PVCs (which contain data/metadata) will be left behind; you can list them using:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
kubectl get pvc -n firebolt-core
NAME                                                        STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
core-demo-firebolt-core-data-nr-core-demo-firebolt-core-0   Bound    pvc-5b2ff164-c34b-4b0f-a2f1-5244a68fec1f   1Gi        RWO            standard       <unset>                 1m
core-demo-firebolt-core-data-nr-core-demo-firebolt-core-1   Bound    pvc-5c8f9cac-929e-42c1-85ee-bef4ba84c645   1Gi        RWO            standard       <unset>                 1m
core-demo-firebolt-core-data-nr-core-demo-firebolt-core-2   Bound    pvc-972dfadc-9684-44c6-8a6a-705611173f45   1Gi        RWO            standard       <unset>                 1m
```

Remove them using `kubectl delete` and make sure you are deleting only those whose name prefix matches your Helm deployment.

**NOTE:** this is a non-reversible operation, you must not delete the PVCs if you need the data/metadata of your Core cluster.

### Additional Resources

* Kubernetes [Namespaces documentation](https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/)
* Helm [Quickstart Guide](https://helm.sh/docs/intro/quickstart/)
