Data model
The public oso.* marts are the stable, versioned tables most queries should
use. They fall into three families — entities, events, and
metrics — all queryable with read-only Trino SQL via
pyoso, the execute_sql MCP tool, or any
connected notebook.
This page is an orientation to the families and how they fit together. For the exhaustive, field-level reference of every table and column, see the core models reference.
Stability convention: v0 vs. v1
Every mart carries a version suffix that signals how much you can rely on its shape:
v1— stable. The schema will not change without a major version release. Safe to build dashboards and pipelines on.v0— in development. Fields may be added, changed, or removed without warning. Useful, but pin your expectations loosely.
Staging (stg_*) and intermediate (int_*) models sit upstream of the marts.
They change often and are considered internal — query the marts instead.
Entities
Entities are the registries that define what OSO tracks and how the pieces relate. OSO is built around three levels: a collection is a group of projects, a project is a group of artifacts, and an artifact is a concrete work product (a GitHub repo, an npm package, an onchain contract or address). A project can belong to many collections, but an artifact belongs to exactly one project.
Key entity marts:
| Table | Grain | Purpose |
|---|---|---|
projects_v1 | project_id | Project metadata (name, namespace, description) |
collections_v1 | collection_id | Collection metadata (ecosystems, funding rounds) |
artifacts_v1 | artifact_id | All known artifacts, including those not attributed to a project |
artifacts_by_project_v1 | (artifact_id, project_id) | Which artifacts belong to which projects |
projects_by_collection_v1 | (project_id, collection_id) | Which projects belong to which collections |
users_v1 | user_id | Users (e.g. GitHub accounts) linked to events |
IDs (project_id, collection_id, artifact_id, metric_id) are
deterministic hashes of (source, namespace, name) — the same entity always
resolves to the same ID. These OSO IDs are distinct from *_source_id (the
native ID in GitHub, npm, etc.); always join OSO tables on the OSO *_id.
Prefer artifacts_by_project_v1 over artifacts_v1 for most work — the latter
includes artifacts not attributed to any project and is much larger. When a
mart mixes registries, filter by source (e.g. project_source = 'OSS_DIRECTORY')
to avoid duplicate, inflated counts.
SELECT
project_id,
project_name,
display_name,
description
FROM oso.projects_v1
WHERE LOWER(display_name) LIKE '%ethereum%'
Events
Events capture what happened to artifacts over time — code contributions (commits, issues, pull requests), package activity, and onchain transactions — each linked to an artifact and, where applicable, a user. Events are indexed from providers like GH Archive, npm, and blockchain ETL services.
Because event data is the highest-volume layer, most granular event tables live
in the intermediate (int_events*) layer that feeds the metrics rollups, rather
than as v0/v1 marts. For most analysis you should read the pre-aggregated
metrics tables below; drop down to the event tables only when you need
individual events.
SELECT
event_type,
COUNT(*) AS event_count
FROM oso.int_events_daily__github
GROUP BY event_type
ORDER BY event_count DESC
The metrics tables (below) are typically 1–2 orders of magnitude smaller than the events they summarize, so downstream tables are cheaper and faster to scan.
Metrics
Metrics are the KPIs and time series computed on top of events. Many are
factory-generated across sources and time intervals, producing names like
GITHUB_stars_daily or BASE_gas_fees_over_all_time.
| Table | Purpose |
|---|---|
metrics_v0 | Metric catalog — one row per metric, with definition and aggregation metadata |
key_metrics_by_project_v0 / key_metrics_by_artifact_v0 / key_metrics_by_collection_v0 | Latest key-metric snapshots per entity |
timeseries_metrics_by_project_v0 / timeseries_metrics_by_artifact_v0 / timeseries_metrics_by_collection_v0 | Full historical time series per entity |
The timeseries_metrics_by_*_v0 and key_metrics_by_*_v0 tables carry a numeric
amount keyed by metric_id + entity ID + sample_date; join to metrics_v0
to resolve human-readable metric names.
SELECT
tm.sample_date,
m.metric_name,
tm.amount,
tm.unit
FROM oso.timeseries_metrics_by_project_v0 AS tm
JOIN oso.metrics_v0 AS m
ON tm.metric_id = m.metric_id
JOIN oso.projects_v1 AS p
ON tm.project_id = p.project_id
WHERE p.project_name = 'ethereum'
AND m.metric_name IN (
'GITHUB_stars_daily',
'GITHUB_commits_daily'
)
ORDER BY tm.sample_date DESC
LIMIT 10
Next steps
- Core models reference — full field-level documentation for every table.
- Querying OSO — run your first queries with pyoso or MCP.
- pyoso SDK — the Python client API surface.
- Data modeling — build your own models on top of the marts.