Back to Nodes

Data Profiler

Last updated May 21, 2026

Analyze incoming data and produce a statistical profile of every field — types, null counts, unique counts, numeric stats, top string values and length distribution.

6 Weekly Downloads
291 Monthly Downloads

Included Nodes

Data Profiler

Description

n8n-nodes-data-profiler

An n8n community node that analyzes incoming data and produces a statistical profile of every field — types, null counts, unique counts, numeric stats, top string values and length distribution.

Think of it as a lightweight pandas.DataFrame.describe() for arbitrary JSON, available as a single drag-and-drop node in your workflow. Useful when you fetch a new API for the first time, when something downstream broke and you need to understand the shape of the data you actually got, or when you want quick data quality signals before loading into a database.

Why this exists

n8n shows you raw JSON in the right panel, which is great for one item but useless when you want to answer questions like:

  • “How often is this field missing?”
  • “Is status always a string, or does it sometimes come back as null?”
  • “What are the most common values for country?”
  • “What’s the range of price across all 5,000 items?”
  • This node answers all of them in one click.

    Installation

    In your n8n instance, go to Settings → Community Nodes → Install and enter:

    n8n-nodes-data-profiler
    

    For self-hosted n8n with manual installation:

    npm install n8n-nodes-data-profiler
    

    Usage

    Drop the Data Profiler node after any node that produces structured data (HTTP Request, database query, Read CSV, etc.). That’s it — no credentials needed.

    Modes

  • Profile Array (default) — treats all incoming items as a single dataset and produces one combined report. This is what you want 95% of the time.
  • Profile Each Item — outputs one profile per incoming item. Useful when each item is itself a large nested object and you want them analyzed independently.
  • Parameters

    | Parameter | Default | Description |
    |—|—|—|
    | Mode | Profile Array | How to group incoming items |
    | Depth | 2 | How many levels deep to traverse nested objects |
    | Sample Size | 3 | How many example values to include per field |
    | Top Values Count | 5 | How many most frequent values to show for string fields |

    Example

    Input (5 items from some user API):

    [
      { "id": 1, "name": "Alice", "country": "US", "age": 30,   "tags": ["admin", "billing"] },
      { "id": 2, "name": "Bob",   "country": "US", "age": null, "tags": ["billing"] },
      { "id": 3, "name": "Carol", "country": "DE", "age": 45,   "tags": [] },
      { "id": 4, "name": "Dan",   "country": "US", "age": 22,   "tags": ["admin"] },
      { "id": 5, "name": "Eve",   "country": "FR", "age": 38,   "tags": ["admin", "ops", "billing"] }
    ]
    

    Output (abbreviated):

    {
      "meta": {
        "mode": "profileArray",
        "totalItems": 5,
        "fieldsFound": 5,
        "profiledAt": "2026-05-15T13:22:00.000Z"
      },
      "profile": {
        "age": {
          "types": { "number": { "count": 4, "percent": 80 }, "null": { "count": 1, "percent": 20 } },
          "count": 5, "nullCount": 1, "nullPercent": 20,
          "uniqueCount": 4, "uniquePercent": 100,
          "samples": [30, 45, 22],
          "numeric": { "min": 22, "max": 45, "avg": 33.75, "median": 34 }
        },
        "country": {
          "types": { "string": { "count": 5, "percent": 100 } },
          "count": 5, "nullCount": 0, "nullPercent": 0,
          "uniqueCount": 3, "uniquePercent": 60,
          "samples": ["US", "US", "DE"],
          "string": {
            "minLength": 2, "maxLength": 2, "avgLength": 2,
            "topValues": [
              { "value": "US", "count": 3, "percent": 60 },
              { "value": "DE", "count": 1, "percent": 20 },
              { "value": "FR", "count": 1, "percent": 20 }
            ]
          }
        },
        "tags": {
          "types": { "array": { "count": 5, "percent": 100 } },
          "count": 5, "nullCount": 0, "nullPercent": 0,
          "uniqueCount": 5, "uniquePercent": 100,
          "samples": [["admin", "billing"], ["billing"], []],
          "array": { "minLength": 0, "maxLength": 3, "avgLength": 1.6 }
        }
      }
    }
    

    You can then feed this into a Set, IF, or Code node to act on quality signals — e.g. “if email.nullPercent > 10, send a Slack alert”.

    Common patterns

    Quick data-quality gate before loading into a database:
    HTTP Request → Data Profiler → IF (profile.email.nullPercent < 5) → Postgres Insert

    Understand a new API:
    HTTP Request → Data Profiler → Edit Fields (extract profile) → log to console / save to file

    Compare two runs of the same dataset:
    Two HTTP Request branches → each through Data Profiler → Merge → Diff via Code node

    Notes

  • Arrays are profiled as a single field (length distribution, presence). To profile the items inside an array, pipe through n8n’s built-in Item Lists → Split Out Items first.
  • Depth controls only nested objects. Arrays are never recursed into.
  • The node is purely stateless — same input gives the same output every time.

License

MIT