JSONB in PostgreSQL is like a magic box. You can store flexible data. You can mix keys and values. You can keep nested objects. And the best part? You can search inside it—fast. If you know how.

TLDR: JSONB lets you store and search structured data inside PostgreSQL. Use operators like ->, ->>, and @> to query it. Add GIN indexes to speed things up, often 2x faster or more. Use the right index for the right query pattern.

Let’s break it down. Simple. Fun. Practical.

First, What Is JSONB?

JSONB stands for JSON Binary. It stores JSON in a decomposed binary format. That means:

Imagine a table like this:

CREATE TABLE products (
  id SERIAL PRIMARY KEY,
  data JSONB
);

The data column might look like:

{
  "name": "Laptop",
  "brand": "Dell",
  "price": 1200,
  "specs": {
    "ram": "16GB",
    "storage": "512GB"
  },
  "tags": ["electronics", "computers"]
}

Now let’s search it.


1. Search by Key with -> (Get JSON Object)

Use -> to get a JSON object field.

SELECT data -> 'brand' 
FROM products;

This returns JSON like:

"Dell"

It keeps the JSON format.

Best for: Getting raw JSON values.


2. Search by Key with ->> (Get Text Value)

Use ->> when you want plain text.

SELECT data ->> 'brand' 
FROM products;

This returns:

Dell

No quotes. Just text.

This is super useful in WHERE clauses:

SELECT *
FROM products
WHERE data ->> 'brand' = 'Dell';

Now we’re filtering.


3. Search Nested Fields

What about nested data? Like specs.ram?

You can chain operators:

SELECT *
FROM products
WHERE data -> 'specs' ->> 'ram' = '16GB';

That’s it. Clean and readable.

Pro tip: Always use ->> when comparing to text values.


4. Search with Containment Operator @>

This is where JSONB shines.

The @> operator checks if the JSON contains something.

SELECT *
FROM products
WHERE data @> '{"brand": "Dell"}';

This finds rows where brand is Dell.

It even works for nested fields:

SELECT *
FROM products
WHERE data @> '{"specs": {"ram": "16GB"}}';

Why this rocks:


5. Search in JSON Arrays

Remember the tags array?

"tags": ["electronics", "computers"]

Search like this:

SELECT *
FROM products
WHERE data -> 'tags' ? 'electronics';

The ? operator checks if an array contains a value.

Super handy for categories, labels, roles, or permissions.


6. Search with jsonb_array_elements()

Need deeper array logic? Use jsonb_array_elements().

Example:

SELECT *
FROM products,
     jsonb_array_elements(data -> 'tags') AS tag
WHERE tag = '"electronics"';

This expands the array into rows.

Then filters.

It’s powerful. But slower without indexes.


7. Search with Path Queries (jsonb_path_query)

PostgreSQL supports JSONPath.

Example:

SELECT *
FROM products
WHERE jsonb_path_exists(data, '$.specs.ram ? (@ == "16GB")');

This feels like JavaScript.

It’s great for:

But indexing becomes very important here.


How to Make JSONB Searches 2x Faster

Here’s the secret sauce: GIN indexes.

Without indexes? Slow scans.

With indexes? Lightning.

1. Basic GIN Index

CREATE INDEX idx_products_data
ON products
USING GIN (data);

This supports:

Most common setup. Huge performance boost.


2. GIN Index with jsonb_path_ops

Smaller. Faster. More focused.

CREATE INDEX idx_products_data_path
ON products
USING GIN (data jsonb_path_ops);

This is optimized for @> containment only.

Pros:

Cons:


3. Expression Index for Specific Fields

If you often search by brand:

CREATE INDEX idx_products_brand
ON products ((data ->> 'brand'));

Now this runs much faster:

SELECT *
FROM products
WHERE data ->> 'brand' = 'Dell';

This is often 2x faster than a full JSONB scan.

Sometimes much more.


When Should You Use JSONB?

Use JSONB when:

Don’t use it when:

In those cases, classic columns may be better.


Performance Tips Summary

Indexes are not optional at scale.

They make the difference between milliseconds and seconds.


Final Thoughts

JSONB turns PostgreSQL into a hybrid beast. Part relational. Part document database.

You can:

And when you add the right GIN index?

Speed doubles. Sometimes more.

So experiment. Test your queries. Add indexes smartly.

JSONB is powerful. But only when you search it the right way.

Now go make your database fly.

🚀