Skip to main content
This connector leverages ClickHouse-specific optimizations, such as advanced partitioning and predicate pushdown, to improve query performance and data handling. The connector is based on ClickHouse’s official JDBC connector, and manages its own catalog. Before Spark 3.0, Spark lacked a built-in catalog concept, so users typically relied on external catalog systems such as Hive Metastore or AWS Glue. With these external solutions, users had to register their data source tables manually before accessing them in Spark. However, since Spark 3.0 introduced the catalog concept, Spark can now automatically discover tables by registering catalog plugins. Spark’s default catalog is spark_catalog, and tables are identified by {catalog name}.{database}.{table}. With the new catalog feature, it is now possible to add and work with multiple catalogs in a single Spark application.

Choosing Between Catalog API and TableProvider API

The ClickHouse Spark connector supports two access patterns: the Catalog API and the TableProvider API (format-based access). Understanding the differences helps you choose the right approach for your use case.

Catalog API vs TableProvider API

Requirements

  • Java 8 or 17 (Java 17+ required for Spark 4.0)
  • Scala 2.12 or 2.13 (Spark 4.0 only supports Scala 2.13)
  • Apache Spark 3.3, 3.4, 3.5, or 4.0

Compatibility matrix

Installation & setup

For integrating ClickHouse with Spark, there are multiple installation options to suit different project setups. You can add the ClickHouse Spark connector as a dependency directly in your project’s build file (such as in pom.xml for Maven or build.sbt for SBT). Alternatively, you can put the required JAR files in your $SPARK_HOME/jars/ folder, or pass them directly as a Spark option using the --jars flag in the spark-submit command. Both approaches ensure the ClickHouse connector is available in your Spark environment.

Import as a Dependency

Add the following repository if you want to use SNAPSHOT version.

Download the library

The name pattern of the binary JAR is:
You can find all available released JAR files in the Maven Central Repository and all daily build SNAPSHOT JAR files in the Sonatype OSS Snapshots Repository.
It’s essential to include the clickhouse-jdbc JAR with the “all” classifier, as the connector relies on clickhouse-http and clickhouse-client — both of which are bundled in clickhouse-jdbc:all. Alternatively, you can add clickhouse-client JAR and clickhouse-http individually if you prefer not to use the full JDBC package.In any case, ensure that the package versions are compatible according to the Compatibility Matrix.

Register the catalog (required)

In order to access your ClickHouse tables, you must configure a new Spark catalog with the following configs: These settings could be set via one of the following:
  • Edit/Create spark-defaults.conf.
  • Pass the configuration to your spark-submit command (or to your spark-shell/spark-sql CLI commands).
  • Add the configuration when initiating your context.
When working with a ClickHouse cluster, you need to set a unique catalog name for each instance. For example:
That way, you would be able to access clickhouse1 table <ck_db>.<ck_table> from Spark SQL by clickhouse1.<ck_db>.<ck_table>, and access clickhouse2 table <ck_db>.<ck_table> by clickhouse2.<ck_db>.<ck_table>.

Using the TableProvider API (Format-based Access)

In addition to the catalog-based approach, the ClickHouse Spark connector supports a format-based access pattern via the TableProvider API.

Format-based Read Example

Format-based Write Example

TableProvider Features

The TableProvider API provides several powerful features:

Automatic Table Creation

When writing to a non-existent table, the connector automatically creates the table with an appropriate schema. The connector provides intelligent defaults:
  • Engine: Defaults to MergeTree() if not specified. You can specify a different engine using the engine option (e.g., ReplacingMergeTree(), SummingMergeTree(), etc.)
  • ORDER BY: Required - You must explicitly specify the order_by option when creating a new table. The connector validates that all specified columns exist in the schema.
  • Nullable Key Support: Automatically adds settings.allow_nullable_key=1 if ORDER BY contains nullable columns
ORDER BY Required: The order_by option is required when creating a new table via the TableProvider API. You must explicitly specify which columns to use for the ORDER BY clause. The connector validates that all specified columns exist in the schema and will throw an error if any columns are missing.Engine Selection: The default engine is MergeTree(), but you can specify any ClickHouse table engine using the engine option (e.g., ReplacingMergeTree(), SummingMergeTree(), AggregatingMergeTree(), etc.).

TableProvider Connection Options

When using the format-based API, the following connection options are available:

Connection Options

Table Creation Options

These options are used when the table doesn’t exist and needs to be created: * The order_by option is required when creating a new table. All specified columns must exist in the schema.
** Automatically set to 1 if ORDER BY contains nullable columns and not explicitly provided.
Best Practice: For ClickHouse Cloud, explicitly set settings.allow_nullable_key=1 if your ORDER BY columns might be nullable, as ClickHouse Cloud requires this setting.

Writing Modes

The Spark connector (both TableProvider API and Catalog API) supports the following Spark write modes:
  • append: Add data to existing table
  • overwrite: Replace all data in the table (truncates table)
Partition Overwrite Not Supported: The connector doesn’t currently support partition-level overwrite operations (e.g., overwrite mode with partitionBy). This feature is in progress. See GitHub issue #34 for tracking this feature.

Configuring ClickHouse Options

Both the Catalog API and TableProvider API support configuring ClickHouse-specific options (not connector options). These are passed through to ClickHouse when creating tables or executing queries. ClickHouse options allow you to configure ClickHouse-specific settings like allow_nullable_key, index_granularity, and other table-level or query-level settings. These are different from connector options (like host, database, table) which control how the connector connects to ClickHouse.

Using TableProvider API

With the TableProvider API, use the settings.<key> option format:

Using Catalog API

With the Catalog API, use the spark.sql.catalog.<catalog_name>.option.<key> format in your Spark configuration:
Or set them when creating tables via Spark SQL:

ClickHouse Cloud settings

When connecting to ClickHouse Cloud, make sure to enable SSL and set the appropriate SSL mode. For example:

Read data

Write data

Partition Overwrite Not Supported: The Catalog API doesn’t currently support partition-level overwrite operations (e.g., overwrite mode with partitionBy). This feature is in progress. See GitHub issue #34 for tracking this feature.

DDL operations

You can perform DDL operations on your ClickHouse instance using Spark SQL, with all changes immediately persisted in ClickHouse. Spark SQL allows you to write queries exactly as you would in ClickHouse, so you can directly execute commands such as CREATE TABLE, TRUNCATE, and more - without modification, for instance:
When using Spark SQL, only one statement can be executed at a time.
The above examples demonstrate Spark SQL queries, which you can run within your application using any API—Java, Scala, PySpark, or shell.

Working with VariantType

VariantType support is available in Spark 4.0+ and requires ClickHouse 25.3+ with experimental JSON/Variant types enabled.
The connector supports Spark’s VariantType for working with semi-structured data. VariantType maps to ClickHouse’s JSON and Variant types, allowing you to store and query flexible schema data efficiently.
This section focuses specifically on VariantType mapping and usage. For a complete overview of all supported data types, see the Supported data types section.

ClickHouse Type Mapping

Reading VariantType Data

When reading from ClickHouse, JSON and Variant columns are automatically mapped to Spark’s VariantType:

Writing VariantType Data

You can write VariantType data to ClickHouse using either JSON or Variant column types:

Creating VariantType Tables with Spark SQL

You can create VariantType tables using Spark SQL DDL:

Configuring Variant Types

When creating tables with VariantType columns, you can specify which ClickHouse types to use:

JSON Type (Default)

If no variant_types property is specified, the column defaults to ClickHouse’s JSON type, which only accepts JSON objects:
This creates the following ClickHouse query:

Variant Type with Multiple Types

To support primitives, arrays, and JSON objects, specify the types in the variant_types property:
This creates the following ClickHouse query:

Supported Variant Types

The following ClickHouse types can be used in Variant():
  • Primitives: String, Int8, Int16, Int32, Int64, UInt8, UInt16, UInt32, UInt64, Float32, Float64, Bool
  • Arrays: Array(T) where T is any supported type, including nested arrays
  • JSON: JSON for storing JSON objects

Read Format Configuration

By default, JSON and Variant columns are read as VariantType. You can override this behavior to read them as strings:

Write Format Support

VariantType write support varies by format: Configure the write format:
If you need to write to a ClickHouse Variant type, use JSON format. Arrow format only supports writing to JSON type.

Best Practices

  1. Use JSON type for JSON-only data: If you only store JSON objects, use the default JSON type (no variant_types property)
  2. Specify types explicitly: When using Variant(), explicitly list all types you plan to store
  3. Enable experimental features: Ensure ClickHouse has allow_experimental_json_type = 1 enabled
  4. Use JSON format for writes: JSON format is recommended for VariantType data for better compatibility
  5. Consider query patterns: JSON/Variant types support ClickHouse’s JSON path queries for efficient filtering
  6. Column hints for performance: When using JSON fields in ClickHouse, adding column hints improves query performance. Currently, adding column hints via Spark isn’t supported. See GitHub issue #497 for tracking this feature.

Example: Complete Workflow

Configurations

The following are the adjustable configurations available in the connector.
Using Configurations: These are Spark-level configuration options that apply to both Catalog API and TableProvider API. They can be set in two ways:
  1. Global Spark configuration (applies to all operations):
  2. Per-operation override (TableProvider API only - can override global settings):
Alternatively, set them in spark-defaults.conf or when creating the Spark session.

Supported data types

This section outlines the mapping of data types between Spark and ClickHouse. The tables below provide quick references for converting data types when reading from ClickHouse into Spark and when inserting data from Spark into ClickHouse.

Reading data from ClickHouse into Spark

Inserting data from Spark into ClickHouse

Contributing and support

If you’d like to contribute to the project or report any issues, we welcome your input! Visit our GitHub repository to open an issue, suggest improvements, or submit a pull request. Contributions are welcome! Please check the contribution guidelines in the repository before starting. Thank you for helping improve our ClickHouse Spark connector!
Last modified on June 23, 2026