factcat
An open-source alternative to Amplitude and Mixpanel that runs in your own data warehouse. Factcat generates SQL and runs it in your BigQuery (or Snowflake, experimental) — no SDK, no ingestion, nothing hosted.
Point it at an events table you already have — one row per event, properties as real columns. Python 3.10+ and credentials for your warehouse.
pip install "factcat[bigquery]"
cd /path/to/your/warehouse # your mapping is saved here
factcat
That gives you a factcat command. Open http://127.0.0.1:8000. Setup asks which
table, which column identifies the thing you are counting, and which column is
the event timestamp. Then you have a chart.
Product analytics tools make your modelling decisions for you: entity = a user,
period = a calendar bucket, retained = did an event. Real definitions violate
all three, so Factcat makes all three yours:
from factcat import RetentionSpec, retention_sql
spec = RetentionSpec(
table="analytics.fct_subscription_payments",
entity="subscription_id", # not the user
entity_time="sub_start",
event_time="paid_at",
period_days=35, # a billing cycle plus dunning, not a calendar bucket
n_periods=12,
retained="status = 'collected' AND within_period_offset <= 5",
)
print(retention_sql(spec, dialect="snowflake"))
retained is arbitrary SQL over any column in your table, plus the derived columns
offset_days, period_index and within_period_offset.
Status. Factcat is 0.x. The SQL-generation API — RetentionSpec, FunnelSpec,
EventsSpec and the *_sql functions — is the surface that stays stable. A minor
release may change those dataclasses or the shape of .factcat.json, and says so at
the top of its release notes; a patch release never does. Pin with factcat~=0.5.0.
Warehouses. pip install factcat is SQL generation plus the local chart and
includes no warehouse SDK; factcat[bigquery] and factcat[snowflake] add the
official driver, factcat[all] adds every shipped one. BigQuery ships today;
Snowflake is experimental — its SQL is generated and compiled in CI against
Snowflake's grammar, but no live Snowflake account has ever executed it, so treat a
first run as a test. SQL generation alone also targets DuckDB, Postgres, Databricks,
Spark, Trino, Presto, ClickHouse and Redshift.
Managed tables. Factcat may create fc_ tables in a write dataset you choose,
to make repeated breakdowns cheap; they hold entity ids and column values copied
from your events table, and they live in your warehouse. See the setup guide.
Long documentation: https://factcat.dev · Releases: https://github.com/gordonkjlee/factcat/releases · Bugs and feedback: https://github.com/gordonkjlee/factcat/issues
Metadata
Release files for factcat 0.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| factcat-0.6.0.tar.gz | 1.0 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| factcat-0.6.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 2.0 MB
Release files / factcat-0.6.0.tar.gz
| Download URL | factcat-0.6.0.tar.gz |
|---|---|
| Size | 1.0 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
571bc800dc9b647eb57ab6409a4104870bd2afc23837d457df14fb1057733ab6
|
|
BLAKE2b-256 checksum How to use checksums |
3c0f4a307140f588e1047f39bbc28059d2435ba9ea94091ee19b0891f43a3339
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 12, 2026.
Transparency logRelease files / factcat-0.6.0-py3-none-any.whl
| Download URL | factcat-0.6.0-py3-none-any.whl |
|---|---|
| Size | 939.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
dcb9e11d7eb2c1b7b2d510fd68baf1d1443076af1bbfadcdfc1539dbc53921ac
|
|
BLAKE2b-256 checksum How to use checksums |
89ab053c146aa3b4e79cf6c2fa26c4d24031331fddaec6cac221cf2a874f3219
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 12, 2026.
Transparency log