What's the best way to explore a local Parquet file visually?
If you want to drag fields around a Parquet or CSV file you already have on disk, with no server and no repo, use xmetric: it opens the file in a browser tab and runs the queries there. Pick Evidence or Observable Framework when the result should be a versioned report in Git, and Superset when a team needs a shared portal on a warehouse.
Updated
Our pick
xmetric
It opens the file in a browser tab with nothing to install or host, the data stays on your machine, and you pivot on shelves with Tableau-style formulas instead of rewriting a GROUP BY for every question.
Pick something else if
The output is a report that lives in Git and deploys on CI (Evidence or Observable Framework), or a team needs a shared, permissioned portal on Postgres, Snowflake or Trino (Superset or Preset).
xmetric makes this page. Every vendor fact below links to the vendor’s own page and the date we checked it.
Cost to startxmetricFree in your browser. No account needed to open a file.Saving a workbook online and sharing a link need a free account.Source · checked October 20EvidenceEvidence Core framework, MIT licence, free to self-host, no account needed.You build and host the static site yourself; docs do not state a $0 price explicitly. Hosted plan has only a 30-day trial.Source · checked October 17Observable FrameworkObservable Framework, free static site generator (ISC licence), free to self-host.Code-first (JavaScript plus Markdown); you build and host the static site yourself.Source · checked October 17Apache Superset / PresetApache Superset is free to self-host under the Apache License (Docker Compose, Kubernetes, PyPI)Source · checked October 17
What you runxmetricAny modern browser on Mac, Windows or Linux. Nothing to install.Source · checked October 17EvidenceCore builds a static site you host anywhere (Vercel, Netlify, Docker, own servers); hosted option is Evidence Studio/Cloud.Source · checked October 17Observable FrameworkBuilds a static site hosted on any static hosting service or your own server; docs walk through GitHub Pages.Source · checked October 17Apache Superset / PresetPreset Cloud (fully managed SaaS); Enterprise adds Managed Private Cloud; also certified Superset for any infrastructureSource · checked October 17
Where the data is processedxmetricIn your browser. Files are not uploaded.Source · checked October 17EvidenceHosted: extracted data cached in Evidence's query engine in a chosen region; direct connectors query the user's warehouse per request.Source · checked October 17Observable FrameworkData loaders run at build time where the build runs (project directory); the browser gets static data snapshots.Source · checked October 17Apache Superset / PresetQueries run against the customer's own database, connected to Preset's hosted cloudSource · checked October 17
Try it: the first look at a new events table
Here is a month of events from a habit app's pipeline. Count rows per user and Android users log 19.7 habits each against 14.3 on iOS, a 38% lead. Then compare rows with distinct event ids: 307 of Android's 995 rows are repeats of an event already stored, from a client that retries uploads. Count distinct events and Android lands at 13.7, just behind iOS. Nothing about engagement changed; the table had duplicates.
SELECT platform,
COUNT(DISTINCT user_id) AS users,
ROUND(COUNT(*) FILTER (WHERE event_type ='habit_logged') *1.0/COUNT(DISTINCT user_id), 1) AS habits_per_user
FROM input
GROUPBY platform
ORDERBY habits_per_user DESC
Rows
Platform
Users
Habits per user
android
26
19.7
ios
26
14.3
web
8
5.6
2
Step 2
Rows versus distinct events
Every iOS and web row is a distinct event. Android has hundreds of repeats: the client retries uploads on a bad connection and the pipeline keeps both copies.
Platform
Rows
Events
Duplicate rows
android
995
688
307
ios
736
736
0
web
134
134
0
Tableau
COUNT([event_id]) -COUNTD([event_id])
✓ The xmetric engine ran this formula and got the SQL’s Duplicate rows column, row for row.
SQL
SELECT platform,
COUNT(*) ASROWS,
COUNT(DISTINCT event_id) AS events,
COUNT(*) -COUNT(DISTINCT event_id) AS duplicate_rows
FROM input
GROUPBY platform
ORDERBY duplicate_rows DESC
Rows
Platform
Rows
Events
Duplicate rows
android
995
688
307
ios
736
736
0
web
134
134
0
3
Step 3
Count events, not rows
Counted by distinct event id, Android drops just behind iOS. The engagement gap was a retry bug.
SELECT platform,
ROUND(COUNT(DISTINCTCASEWHEN event_type ='habit_logged'THEN event_id END) *1.0/COUNT(DISTINCT user_id), 1) AS habits_per_user
FROM input
GROUPBY platform
ORDERBY habits_per_user DESC
Rows
Platform
Habits per user
ios
14.3
android
13.7
web
5.6
That's the case for a visual first pass: one drag of event_id onto the view as a count and a distinct count shows the gap before anyone builds a dashboard on it.
Common mistake
Adding up weekly active users
Each week counts its own distinct users, so a user active in all four weeks is counted four times. Count distinct users over the whole period instead.
Wrong
Point at a bar to read it.
Tableau
WINDOW_SUM(COUNTD([user_id]))
//viewatweeklevel
SQL
WITH w AS (
SELECTdate_trunc('week', event_date) AS week,
COUNT(DISTINCT user_id) AS users
FROM input
GROUPBY week
)
SELECTSUM(users) AS active_users
FROM w
SELECTCOUNT(DISTINCT user_id) AS active_users
FROM input
Run it on your own file
Drop a CSV export of your own table and the same steps run on it, in this browser. For Parquet, open the file in the xmetric app; nothing is uploaded either way.
Drop a CSV anywhere on this page
Up to 10,000 rows. The sample, events.csv, shows the shape.
When another tool is the better choice
If this is you
A Parquet or CSV file on your laptop and a question to answer today
xmetric
Open it in a tab and drag fields; no server, no repo, no upload.
If this is you
A recurring report that should be reviewed in pull requests and deployed by CI
Evidence
SQL and Markdown in Git, built to a static site. Its hosted Team plan costs $2,500 / month, unlimited users, monthly billing; Core is free to self-host.
If this is you
A custom data app with hand-built charts in JavaScript
Observable Framework
Data loaders in any language precompute snapshots at build time; you write the charts.
If this is you
A team portal on a warehouse with roles and a shared SQL editor
Apache Superset / Preset
Free to self-host; Preset hosts it, with Professional at $20/user/month billed annually; $25/user/month billed monthly.
Questions
Does xmetric upload my Parquet file?
No. Parquet, CSV and Excel files are read inside your browser tab. Nothing leaves your machine unless you choose to save the workbook online.
Do I need to convert Parquet to CSV first?
No. The xmetric app opens .parquet files directly. The demo on this page uses a CSV copy of the same table so it loads instantly here.
Can I paste the SQL into the DuckDB CLI?
Yes. Every step shows DuckDB SQL over a table called input. Replace input with read_parquet('events.parquet') and it runs as is.
Why does COUNT give a different answer from COUNTD on event ids?
Because the same event can arrive twice. Pipelines that deliver at least once, and mobile clients that retry uploads, write duplicate rows with the same id. COUNT counts rows; COUNTD counts events.