---
title: How Variant will Replace JSONB in Lakehouses
description: A deep dive into the variant data type in lakehouses
image: https://floedb.ai/hubfs/jin-blog1.png
---

Or follow us on social media:

 Floe is under active development and will enter Beta soon. We’d love for you to help us shape the world's best Lakehouse SQL compute engine.

[GitHub ](https://github.com/eng-floe/floecat) [LinkedIn ](https://linkedin.com/company/floedb)

[Engineering](https://floedb.ai/blog/tag/engineering),

[Data Types](https://floedb.ai/blog/tag/data-types)

# How Variant will Replace JSONB in Lakehouses

 by[![Jin](https://floedb.ai/hubfs/avatars/jin.png) Jin ](https://floedb.ai/blog/author/jin)·Apr 22, 2026 12:28:35 PM

![](https://floedb.ai/hubfs/jin-blog1.png)

In the [last post](https://floedb.ai/blog/why-json-isnt-a-problem-for-databases-anymore), we explored how [binary encoding can speed up retrieval](https://floedb.ai/blog/why-json-isnt-a-problem-for-databases-anymore) for JSON records, and semi-structured data in general. That was a significant improvement from storing plain-text JSON in a database. Now, with Iceberg Table v3 introducing a native `variant` type and Parquet standardizing a `variant` representation, adoption is accelerating across the tooling ecosystem. In this post, we’ll explore how lakehouse users can benefit from `variant`.

## What Is `variant`?

`variant` is a binary format for semi-structured data and can represent data beyond JSON. For example, consider a record like this:

```
{
  "event_type": "checkout_started",
  "ts": "2026-04-14T10:15:21Z",
  "session": {
    "device": "macos",
    "app_version": "26.0.1"
  }
}
```

After the data is stored as `variant`, we can query it with JSONPath-style expressions such as:

```
SELECT payload:$.session.device
FROM event_table;
```

In Parquet, the most common file format for lakehouses, a `variant` value is typically stored as a group with two binary fields, metadata and value, annotated with the `VARIANT` logical type:

```
optional group payload (VARIANT) {
  required binary metadata;
  required binary value;
}
```

## Why Use `variant`?

There are four main reasons to use `variant`:

### 1. Richer Types

`variant` goes beyond JSON primitive types. It supports richer [primitive types](https://github.com/apache/parquet-format/blob/master/VariantShredding.md#encoding-types) such as **date, timestamp, timestamptz, decimal, and UUID**, so query engines do not have to fall back to representing every fields as JSON strings. That leads to more accurate data representation and fewer type-related compromises.

### 2. More Efficient Storage

Because `variant` is binary, it stores values more compactly than plain-text JSON. Fields are encoded in binary representation. Object keys can be deduplicated in `metadata` (from `payload`'s schema above) rather than repeated in every value, resulting in lower storage overhead.

### 3. Faster Retrieval

`variant` avoids much of the repeated structural parsing work required with plain JSON. Instead of reparsing JSON text on every read, the query engine can navigate the binary structure directly and fetch only the fields it needs. This is especially useful for analytical workloads, where queries often touch only a small part of a larger payload. With plain JSON, extracting `$.session.device` requires parsing the entire string and walking the object tree. With `variant`, the engine can use binary metadata to jump more directly to the nested field. In addition, array offsets in the `variant` encoding support direct access; for example, large arrays store offsets to their children, so extracting an element is **O(1)**.

### 4. An Open Ecosystem Standard

This is the part that matters most for lakehouses. Traditional databases each define their own `jsonb`-style encoding, which ties data to a specific system. `variant` is different: it is an **open standardized type in Parquet**, with Iceberg defining the table semantics around it. That means the same files can be read and written across different engines.

In other words, `variant` is not just a better encoding. It is a shared one. That interoperability is why adoption is moving quickly across the ecosystem: once the format is standardized, libraries and query engines can all support the same representation.

## Putting `variant` to Work

`variant` is most valuable when you need flexibility without giving up structure, performance, or usability. It offers many benefits while requiring little extra setup, and lets you keep semi-structured data in its original shape while still making it queryable.

### Use Case 1: Observability Data

Observability payloads have a common envelope, but different services emit different attributes. [OpenTelemetry](https://opentelemetry.io/docs/specs/otel/logs/data-model/) standardized many of these fields, and they are best modelled as `variant`.

A realistic log or span event might look like this:

```
{
  "timestamp": "2026-04-14T10:15:21.231Z",
  "severity_text": "INFO",
  "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
  "span_id": "00f067aa0ba902b7",
  "resource": {
    "service.name": "checkout",
    "service.namespace": "store",
    "service.instance.id": "checkout-7f9c6b87d9-rx2pl",
    "deployment.environment.name": "production",
    "host.name": "ip-10-42-1-17",
    "cloud.region": "eu-west-1"
  },
  "attributes": {
    "http.request.method": "POST",
    "url.path": "/api/checkout",
    "server.address": "api.store.example",
    "http.response.status_code": 200,
    "request.body.size": 1834,
    "cart.value": 89.5,
    "cart.currency": "GBP"
  }
}
```

This is hard to model well with a fixed relational schema. Some fields are always present, some appear only for HTTP traffic, and some are application-specific. `variant` provides a useful middle ground, here's one way to extract important fields as top-level columns:

```
CREATE TABLE observability_events (
  event_date DATE,
  signal_type STRING,
  service_name STRING,
  payload VARIANT
)
```

With this design, we can keep a few stable relational columns, but the evolving payloads are stored in `variant`. Then retrieval uses path expressions instead of reparsing a JSON string.

### Use Case 2: Key/Value Attributes

Key-value attributes show up everywhere, for example in:

- product catalog metadata
- user profile custom fields
- tags and labels
- metrics dimensions
- feature flags
- security context

For example, a product record might look like this:

```
{
  "sku": "shoe-123",
  "category": "running_shoes",
  "price": 129.99,
  "attributes": {
    "color": "blue",
    "size": 8,
    "material": "mesh",
    "waterproof": false,
    "release_date": "2026-03-01"
  }
}
```

Or a hotel listing sample data:

```
{
  "listing_id": "htl-9831",
  "city": "London",
  "price_gbp": 249.0,
  "attributes": {
    "stars": 5,
    "has_breakfast": true,
    "pet_friendly": false,
    "amenities": ["wifi", "gym", "air_conditioning"]
  }
}
```

Some attribute might be missing, while others are added over time. `variant` allows us to store them flexibly, without forcing every possible attribute into the table schema. Otherwise, we might have to create a wide table with lots of nullable columns.

### Typical Workflow

In practice, a common `variant` workflow in a lakehouse looks like this:

- ingest data directly into a `variant` column, instead of storing raw JSON text
- keep a small set of stable top-level columns
- use JSON-path-style accessors to extract optional fields

If we flatten everything, the schema becomes sparse and wide. If we keep it as JSON text, every query becomes a parsing exercise. `variant` offers a middle path: it preserves flexibility while still enabling efficient access.

## Optimization Opportunity

Parquet’s `variant` [shredding spec](https://github.com/apache/parquet-format/blob/master/VariantShredding.md) lets writers extract selected fields from a `variant` payload into strongly typed Parquet columns. Commonly queried fields can be read much more efficiently. Instead of scanning the full semi-structured payload, readers can project only the typed columns they need.

Iceberg builds on that at the planning layer. It already uses column-level statistics such as value counts, null counts, lower bounds, and upper bounds to prune files before execution. In Iceberg v3, that idea extends to [**fields inside a `variant` column**](https://iceberg.apache.org/spec/#bounds-for-variant-geometry-and-geography): statistics can be recorded for normalized JSON paths within the payload. That means predicates on nested fields can eliminate more files before the engine reads any data.

This is where `variant` goes beyond a convenience feature for semi-structured data and becomes a real performance tool in lakehouse systems.

## Conclusion

Semi-structured data is a natural part of the data lakehouse. Logs, traces, events, attributes, and evolving business objects are not going away, so the lakehouse needs a format that can handle them natively.

`variant` is a major step in that direction. It provides the flexibility of JSON while adding richer types, efficient binary encoding, direct access to nested fields, and open interoperability through Parquet and Iceberg. With Iceberg v3 defining the table semantics and Parquet defining the file encoding, `variant` is emerging as a true open standard rather than just another proprietary `jsonb` dialect.

That is why adoption is accelerating across catalogs, libraries, and query engines. Once the representation is standardized, tools can understand the same column format instead of inventing incompatible encodings!

In future post we will look at how query engine can optimize access using **shredded fields**, nested-field stats, and smarter planning.

Author

 Jin

 Jin is passionate about performance and concurrency, especially parallelizing algorithms. He enjoys contributing across the full lifecycle of building software products. Driving efficiency and scalability keeps him up at night!

 Follow us

 Floe is under active development and will enter Beta soon. We’d love for you to help us shape the world's best Lakehouse SQL compute engine. Please follow us by clicking the button below.

[ Follow us

](https://floedb.ai/blog/how-variant-will-replace-jsonb-in-lakehous#floe-popup-form-newsletter_popup)

![](https://floedb.ai/hubfs/raw_assets/public/floe/assets/cat-snowskate.png)

```json
{
  "@context" : "https://schema.org",
  "@type" : "BlogPosting",
  "author" : {
    "@type" : "Person",
    "name" : "Jin",
    "url" : "https://floedb.ai/blog/author/jin"
  },
  "dateModified" : "2026-04-22T16:34:19.989Z",
  "datePublished" : "2026-04-22T16:28:35.000Z",
  "headline" : "How Variant will Replace JSONB in Lakehouses",
  "image" : [ "https://floedb.ai/hubfs/jin-blog1.png" ],
  "mainEntityOfPage" : {
    "@id" : "https://floedb.ai/blog/how-variant-will-replace-jsonb-in-lakehous",
    "@type" : "WebPage"
  },
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "url" : "https://floedb.ai/hubfs/logo.svg"
    }
  }
}
```