ClickHouse for Laravel: Introduction
ClickHouse for Laravel: Introduction
ClickHouse for Laravel: Introduction
Tip: ClickHouse is for Analytics, Not Transactions
Don't use ClickHouse as your primary database. Use it alongside PostgreSQL/MySQL for analytics.
Gotcha: No Updates or Deletes (Easily)
ClickHouse is optimized for inserts and reads. Updates and deletes are expensive. Design for append-only.
Tip: Installation
composer require smi2/phpclickhouse
Gotcha: HTTP Interface, Not TCP
ClickHouse uses port 8123 (HTTP), not 9000 (TCP). The PHP client uses HTTP.
Tip: Configuration
'clickhouse' => [
'driver' => 'clickhouse',
'host' => env('CLICKHOUSE_HOST', 'localhost'),
'port' => env('CLICKHOUSE_PORT', 8123),
'database' => env('CLICKHOUSE_DATABASE', 'default'),
],
Gotcha: No Foreign Keys
ClickHouse doesn't enforce foreign keys. Data integrity is your responsibility.
Tip: Creating Tables
DB::connection('clickhouse')->statement("
CREATE TABLE page_views (
id UInt64,
url String,
user_id UInt64,
created_at DateTime
) ENGINE = MergeTree()
ORDER BY (created_at, url)
");
Gotcha: Primary Key = Sorting Key
In ClickHouse, the ORDER BY clause defines both the primary key and the sort order. Choose wisely.
Tip: Order of Columns in ORDER BY Matters Massively
ClickHouse's primary key is defined by ORDER BY. Put high-cardinality columns first for better data skipping. ORDER BY (timestamp, user_id) is very different from ORDER BY (user_id, timestamp) in query performance.
Tip: Use LowCardinality for Enum-Like Strings
Strings like status, country, browser benefit from LowCardinality(String) — it's stored as a dictionary internally, reducing storage 10x and speeding up scans.
Gotcha: Mutations Are Heavy
ALTER TABLE ... UPDATE and DELETE in ClickHouse create new parts instead of modifying in place. A single mutation on a large table can take hours and block merges. Design for append-only from day one.
Senior Insight
Introducing ClickHouse into a Laravel stack is a significant architectural decision. ClickHouse is not a transactional database — it's an analytical column-store. I've seen teams try to use ClickHouse as a drop-in MySQL replacement and fail spectacularly. The right approach: keep PostgreSQL/MySQL for transactional data, and use ClickHouse as a dedicated analytics layer. I set up a nightly ETL pipeline that exports aggregated data from the OLTP database to ClickHouse for reporting.
Source: ClickHouse Blog (https://clickhouse.com/blog), Altinity Blog (https://altinity.com/blog), Altinity Knowledge Base (https://kb.altinity.com/)