HSTORE

How to use the PostgreSQL hstore data type to store key-value pairs in a single column: enabling the extension, operators, querying, and updating hstore data.

5 min read · Last updated: March 2026 · Back to overview

Quick Answer

PostgreSQL hstore is a key-value store data type where both keys and values are text strings. Enable it with CREATE EXTENSION hstore; then use the -> operator to read values, @> for containment checks, and the || operator to merge new pairs.

Spin up a Postgres database in 20 seconds with Vela.

Try Vela Sandbox

Introduction to PostgreSQL hstore

The hstore module provides a data type for storing sets of key-value pairs within a single PostgreSQL value. Both keys and values are text strings. hstore is useful for semi-structured data — rows that have many optional attributes that are rarely queried across the whole table.

Before using hstore, enable the extension:

CREATE EXTENSION hstore;

Creating a table with an hstore column

CREATE TABLE books (
  id    SERIAL PRIMARY KEY,
  title VARCHAR(255),
  attr  hstore
);

Inserting hstore data

hstore values are written as comma-separated "key" => "value" pairs:

INSERT INTO books (title, attr) VALUES (
  'PostgreSQL Tutorial',
  '"paperback"  => "243",
   "publisher"  => "postgresqltutorial.com",
   "language"   => "English",
   "ISBN-13"    => "978-1449370000",
   "weight"     => "11.2 ounces"'
);

Querying hstore data

-- Get a specific key's value using ->
SELECT attr -> 'ISBN-13' AS isbn FROM books;

-- Filter by a key's value in WHERE
SELECT title, attr -> 'weight' AS weight
FROM books
WHERE attr -> 'ISBN-13' = '978-1449370000';

-- Check if a key exists using ?
SELECT title FROM books WHERE attr ? 'publisher';

-- Check for a key-value pair using @>
SELECT title FROM books
WHERE attr @> '"weight"=>"11.2 ounces"'::hstore;

-- Check for multiple keys using ?&
SELECT title FROM books
WHERE attr ?& ARRAY['language', 'weight'];

Modifying hstore data

-- Add a new key-value pair
UPDATE books SET attr = attr || '"freeshipping"=>"yes"'::hstore;

-- Update an existing key
UPDATE books SET attr = attr || '"freeshipping"=>"no"'::hstore;

-- Remove a key
UPDATE books SET attr = delete(attr, 'freeshipping');

Getting all keys and values

-- All keys as an array
SELECT akeys(attr) FROM books;

-- All keys as a set
SELECT skeys(attr) FROM books;

-- All values as an array
SELECT avals(attr) FROM books;

-- Convert hstore to JSON
SELECT title, hstore_to_json(attr) AS json FROM books;

-- Expand to key-value rows
SELECT title, (EACH(attr)).* FROM books;

Production tips

  • For new schemas, prefer JSONB over hstore — JSONB supports nested data, typed values, and richer operators.
  • Create a GIN index on hstore columns for efficient key-existence (?) and containment (@>) queries: CREATE INDEX idx_books_attr ON books USING GIN (attr);
  • hstore values are always text — if you need to store numbers, booleans, or nested objects, JSONB is the right choice.
  • Use hstore_to_json() when integrating with APIs or clients that expect JSON format.

Reference: PostgreSQL documentation — hstore.

Continue in PostgreSQL Data Types: Array.

Related in this section: Boolean · CHAR, VARCHAR, and TEXT · NUMERIC

Frequently Asked Questions

What is PostgreSQL hstore?

hstore is a PostgreSQL extension that provides a data type for storing a set of key-value pairs in a single column. Both keys and values are text strings — no nesting or typed values are supported. It is useful for semi-structured data, rows with many rarely-queried attributes, or simple attribute dictionaries.

How do you enable the hstore extension?

Run CREATE EXTENSION hstore; once per database. After that, you can use hstore as a column type in CREATE TABLE statements. Use CREATE EXTENSION IF NOT EXISTS hstore; to avoid an error if it is already installed.

How do you query a specific key from an hstore column?

Use the -> operator: SELECT attr -> 'ISBN-13' AS isbn FROM books; returns the value associated with the key ISBN-13 as text. Use the -> operator in WHERE clauses to filter by value: WHERE attr -> 'ISBN-13' = '978-1449370000'.

How do you add or update key-value pairs in hstore?

Use the || (concatenation) operator in an UPDATE statement: UPDATE books SET attr = attr || '"freeshipping"=>"yes"'; — this adds or overwrites the freeshipping key. To remove a key, use the delete() function: UPDATE books SET attr = delete(attr, 'freeshipping');

When should I use hstore versus JSONB?

Use JSONB for most new development — it supports nested structures, typed values, richer operators, and better indexing. Use hstore when you need simple flat key-value storage with text-only values and already have it deployed. For new schemas, JSONB is almost always the better choice.