Generated banner for Tools And Features Hogql
Generated logo for Tools And Features Hogql

Tools And Features Hogql

PostHogOfficialCreated by PostHog

  • Skill
  • Tool integration
  • Data and AI
  • MIT
  • No issues found

From the author

HogQL queries for PostHog analytics
— the description by PostHog

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

HogQL is PostHog's SQL dialect, designed as a wrapper around ClickHouse SQL to simplify data access and analytics within the PostHog platform. This skill provides the essential reference material for constructing queries, including how to access event and person properties, utilize PostHog-specific functions, and integrate UI-based filters into your SQL insights. It emphasizes performance and efficiency, offering guidelines on aggregation, time-range filtering, and query structure to help users build effective analytics dashboards.

What it does

  • Provides syntax patterns for querying events, persons, and sessions.
  • Explains how to access event and person properties using specific dot notation.
  • Details the use of the {filters} placeholder for dynamic dashboard filtering.
  • Lists supported ClickHouse functions and aggregation methods for data analysis.
  • Offers performance optimization tips like using uniq() over count(distinct).
  • Provides guidance on using cohort and action-based filtering in SQL.

When to use it

  • When you need to create custom SQL insights in PostHog.
  • When you want to perform complex data analysis beyond standard UI-based reports.
  • When you need to optimize existing queries for better performance.
  • When you are building dashboards that require dynamic date ranges or user-defined filters.

Advantages

  • Simplifies complex ClickHouse SQL for common analytics tasks.
  • Enables seamless integration with PostHog's UI-based filtering system.
  • Provides access to specialized PostHog functions like windowFunnel and sequenceMatch.
  • Promotes efficient query patterns to reduce load on the underlying database.

Usage examples

“Write a HogQL query to count pageviews by browser.”
SELECT properties.$browser AS browser, count() FROM events WHERE event = '$pageview' AND {filters} GROUP BY browser
“How do I count unique users in a HogQL query?”
Use the uniq() function instead of count(distinct) for better performance, for example: SELECT uniq(person_id) FROM events WHERE {filters}

Install

  1. Download the skill as a ZIP:

    https://mp-staging.autogineer.com/agent-skills/posthog/tools-and-features-hogql/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip tools-and-features-hogql.zip -d .agents/skills

Documentation by PostHog

HogQL queries for PostHog

This skill helps you write HogQL queries for PostHog analytics. HogQL is PostHog's SQL dialect, a wrapper around ClickHouse SQL with simplified property access and PostHog-specific functions.

Reference files

  • references/expressions.md - Sql expressions - docs

  • references/aggregations.md - Supported aggregations - docs

  • references/clickhouse-functions.md - Supported clickhouse functions - docs

  • references/data-access.md - Accessing data using sql - docs

  • references/variables.md - Sql variables - docs

  • references/useful-functions.md - Useful sql functions - docs

  • references/posthog.md - PostHog table schemas (events, persons, groups, sessions)

  • references/sessions.md - Sessions - docs

Consult the documentation for SQL syntax, available functions, and query patterns.

Key principles

  • Property access: Use properties.$property_name for event properties and person.properties.$property_name for person properties

  • Null handling: HogQL has simplified null handling compared to raw ClickHouse SQL

  • Filters placeholder: Use {filters} in queries to allow UI-based filtering in PostHog dashboards

  • Aggregations: Prefer ClickHouse aggregation functions like count(), uniq(), avg(), sum()

Common patterns

Event queries
SELECT event, count()
FROM events
WHERE {filters}
GROUP BY event
ORDER BY count() DESC
Property breakdowns
SELECT properties.$browser AS browser, count()
FROM events
WHERE event = '$pageview' AND {filters}
GROUP BY browser
Person properties
SELECT person.properties.email, count()
FROM events
WHERE {filters}
GROUP BY person.properties.email

Framework guidelines

  • Use properties.$name syntax for event properties, person.properties.$name for person properties

  • Use bracket notation for special characters like properties['$feature/cool-flag']

  • For cohorts, filter with person_id IN COHORT 'cohort-name'

  • For actions, use matchesAction('action-name') in WHERE clauses

  • Include {filters} placeholder in WHERE clauses to enable UI-based filtering in dashboards

  • Use {variables.name} for reusable SQL variables across dashboards

  • Access dashboard date range with {filters.dateRange.from} and {filters.dateRange.to}

  • ALWAYS include a time range filter - shorter is faster (e.g., timestamp >= now() - INTERVAL 7 DAY)

  • Prefer uniq() over count(distinct) for counting unique values - it's more efficient

  • Don't scan the same table multiple times - use materialized views for reusable subsets

  • Use timestamp-based pagination instead of OFFSET for large datasets

  • Name queries descriptively for easier debugging in query_log

  • Use dateTrunc() for time-based grouping (e.g., dateTrunc('day', timestamp))

  • For funnel queries, use windowFunnel() or sequenceMatch() functions

  • Test queries in the PostHog SQL editor before using them in insights or the API

Files

references/posthog.md

Linking PostHog as a data warehouse source - Docs

Much of your PostHog data is available in the data warehouse by default. This includes data like events, persons, sessions, groups, and the query log.

Using our SDKs or API to capture events, identify users, create groups, and add properties adds data to these tables, that you can query using the SQL editor.

PostHog data warehouse tables

events

Events are the core unit of data in PostHog, so you'll likely have a lot of them. This also makes the events table one of the most useful.

Some of the columns in the events table are:

ColumnDescription
uuidUnique ID of the event
eventName of the event
propertiesObject containing all properties of the event (stored as a String). You can see the default properties in our data docs.
timestampTime the event was captured (ISO 8601 format)
distinct_idUnique identifier tying together events from the same person
session_idUnique identifier for the session the event belongs to
person_idUnique identifier for the person

event names and properties can be set to any value you want, so you might many potential values for each.

Some products have special event names and properties that can be useful to know. For example:

  • Autocaptured events are named $autocapture and have the elements_chain property.

  • LLM analytics captures events like $ai_generation, $ai_span, $ai_embedding with properties like $ai_model, $ai_input_tokens, and $ai_total_cost_usd.

  • Error tracking captures $exception events with properties like $exception_list and $exception_fingerprint both with a specific expected schema.

persons

The users behind your events are known as persons in PostHog.

Some of the columns in the persons table are:

ColumnDescription
idUUID of the person. Relates to person_id in the events table.
created_atDate and time when the person was first created (ISO 8601 format).
last_seen_atDate and time of the person's most recent event (ISO 8601 format), rounded to the hour. See skipping last_seen_at updates.
propertiesObject containing all properties associated with the person (stored as a String).
is_identifiedIndicates if the person is identified (1) or anonymous (0).

Beyond storing demographic data about your users, the persons table is powerful as it can connect to many other tables. For example, the persons table can be queried through the events using the person field like SELECT person.properties.$initial_browser FROM events. It can also be joined to external sources to create extended person properties.

groups

Groups enable you to aggregate events based on an entity like an organization, project, or team if you have set up group analytics.

Some of the columns in the groups table are:

ColumnDescription
indexNumeric index of the group type. You can view the group types in the People tab. It is zero-based, so the first group type listed there is 0.
keyUnique string identifier for the group. Relates to one of the group keys on the events table, such as $group_0, depending on the index.
created_atDate and time when the group was first created (ISO 8601 format).
updated_atDate and time when the group was last updated (ISO 8601 format).
propertiesObject containing all properties associated with the group (stored as a String).
sessions

If you are using PostHog's snippet or JavaScript Web SDK, PostHog automatically captures session data which you can query using the sessions table.

Unlike the other tables, the sessions table stores all its properties as separate columns. This means there are a lot more of them. Some of them include:

ColumnDescription
session_idUnique identifier for the session. Relates to $session_id on the events table.
distinct_idUnique identifier for the user (person). Relates to $distinct_id on the events table.
$start_timestampTimestamp when the session started
$end_timestampTimestamp when the session ended
$num_uniq_urlsNumber of unique URLs visited in the session
$entry_current_urlURL of the page where the session started
$end_current_urlURL of the page where the session ended
$entry_referring_domainReferring domain for the session's entry
$entry_utm_sourceUTM source for the session's entry
$pageview_countNumber of pageviews in the session
$autocapture_countNumber of autocapture events in the session
$screen_countNumber of screen events in the session
$channel_typeChannel type for the session's entry (e.g., organic, paid)
$session_durationDuration of the session in seconds
$is_bounceIndicates if the session was a bounce (1 = bounce, 0 = not)
$last_external_click_urlLast external click URL in the session
$vitals_lcpLargest Contentful Paint (LCP) web vital for the session
View additional session propertiesSee full list of session properties

The sessions table is heavily used in web analytics. It is also useful for marketing analytics and session-based metrics more broadly.

query_log

The query_log table provides access to query execution metadata and performance metrics. You can learn more about it in the query log data docs.

Like the sessions table, the query_log table stores all its properties as separate columns. Some of them include:

FieldDescription
event_dateDate when the query was executed
event_timeExact timestamp when query started
query_idUnique identifier for the query
endpointAPI endpoint that triggered the query
queryThe actual HogQL/SQL query that was executed
query_start_timeWhen query execution began
query_duration_msQuery execution time in milliseconds
created_byUser ID who initiated the query
read_rowsNumber of rows processed
read_bytesBytes read during execution
result_rowsNumber of rows returned
result_bytesSize of result set in bytes
memory_usagePeak memory usage in bytes
exception_codeException code if the query failed
is_personal_api_key_requestWhether request used personal API key
api_key_maskMasked API key used
cpu_microsecondsCPU time consumed (for computation, excluding waiting)
RealTimeMicrosecondsWall clock time in microseconds
View additional query log fieldsSee full list of query log properties

The query_log table is the only table with data on you and your team's internal usage of PostHog, making it useful for security, governance, and performance optimization.

System tables

PostHog also provides access to system tables that contain metadata about your PostHog project. These tables are accessed using the system. prefix in your queries, like SELECT * FROM system.actions.

system.actions

The system.actions table contains action definitions created in your project.

ColumnDescription
idUnique identifier for the action
team_idTeam ID the action belongs to
nameName of the action
descriptionDescription of the action
deletedWhether the action is deleted (1 = yes, 0 = no)
created_atWhen the action was created
updated_atWhen the action was last updated
steps_jsonJSON containing the action's step definitions
system.activity_logs

The system.activity_logs table tracks user and system actions across PostHog entities, providing an audit trail of changes to feature flags, insights, dashboards, experiments, and more.

ColumnDescription
idUnique identifier for the activity log entry
team_idTeam ID the activity belongs to
activityAction performed (e.g., created, updated, deleted)
item_idID of the entity being logged
scopeEntity type being logged (e.g., FeatureFlag, Insight)
detailJSON containing structured details about the change
created_atWhen the activity occurred

Common scopes include FeatureFlag, Insight, Dashboard, Experiment, Cohort, Survey, Notebook, Action, Person, Replay, and ErrorTrackingIssue.

Note: Only team-scoped activity logs are visible. Organization-level logs (like membership changes) are not included because they are not associated with a specific team.

system.annotations

The system.annotations table contains annotation data from your project. Annotations are timestamped notes used to mark product changes, incidents, or releases on charts.

ColumnDescription
idUnique identifier for the annotation
team_idTeam ID the annotation belongs to
contentText content of the annotation
scopeScope of the annotation: project, organization, dashboard, or dashboard_item
creation_typeHow the annotation was created: USR (user) or GIT (automated)
date_markerTimestamp shown on charts (ISO 8601 format)
deletedWhether the annotation is deleted (1 = yes, 0 = no)
dashboard_item_idLinked insight ID (if scoped to an insight)
dashboard_idLinked dashboard ID (if scoped to a dashboard)
created_by_idUser ID of the annotation creator
created_atWhen the annotation was created
updated_atWhen the annotation was last updated
system.cohort_calculation_history

The system.cohort_calculation_history table tracks cohort calculation runs, useful for monitoring cohort computation status and debugging.

ColumnDescription
idUnique identifier for the calculation run
team_idTeam ID the cohort belongs to
cohort_idID of the cohort that was calculated
countNumber of users in the cohort after calculation
started_atWhen the calculation started
finished_atWhen the calculation finished
error_codeError code if the calculation failed
system.data_warehouse_tables

The system.data_warehouse_tables table contains metadata about data warehouse tables in your project.

ColumnDescription
idUnique identifier for the table
team_idTeam ID the table belongs to
nameName of the data warehouse table
columnsJSON containing column definitions
row_countNumber of rows in the table
external_data_source_idID of the external data source
created_atWhen the table was created
updated_atWhen the table was last updated
deletedWhether the table is deleted (1 = yes, 0 = no)
deleted_atWhen the table was deleted
system.error_tracking_issues

The system.error_tracking_issues table contains error tracking issues from your project.

ColumnDescription
idUnique identifier for the issue
team_idTeam ID the issue belongs to
created_atWhen the issue was first created
statusCurrent status of the issue
nameName of the issue
descriptionDescription of the issue
system.hog_flows

The system.hog_flows table contains workflow definitions from your project.

ColumnDescription
idUnique identifier for the workflow
team_idTeam ID the workflow belongs to
nameName of the workflow
descriptionDescription of the workflow
statusCurrent status of the workflow
versionVersion number of the workflow
exit_conditionExit condition for the workflow
triggerJSON containing trigger configuration
edgesJSON containing workflow edges
actionsJSON containing workflow actions
created_atWhen the workflow was created
updated_atWhen the workflow was last updated
system.notebooks

The system.notebooks table contains notebook metadata from your project.

ColumnDescription
idUnique identifier for the notebook
short_idShort identifier for the notebook
team_idTeam ID the notebook belongs to
titleTitle of the notebook
contentJSON containing the notebook's content
text_contentPlain text content of the notebook
deletedWhether the notebook is deleted (1 = yes, 0 = no)
visibilityVisibility setting for the notebook
versionVersion number of the notebook
created_atWhen the notebook was created
last_modified_atWhen the notebook was last modified
Community questions

Ask a question

Was this page useful?

HelpfulCould be better

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Security

No issues found by our static scan· No issues found

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Created by
PostHog
Publisher
PostHog (Official)
Source
PostHog/skills · skills/posthog/tools-and-features/skills/hogql · commit a5d30e7
Licence
MIT License (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced
Also distributed in
PostHog/skills

AutoGineer is not affiliated with or endorsed by PostHog.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download tools-and-features-hogql.zip