Boolean Data Type in PostgreSQL

Learn how to use the PostgreSQL BOOLEAN type to store true, false, and NULL values, including accepted literal formats, default values, and partial index patterns.

4 min read · Back to overview

Quick Answer

The PostgreSQL BOOLEAN type stores three values: true, false, and NULL. It accepts multiple literal formats including TRUE/FALSE, 't'/'f', 'yes'/'no', and '1'/'0', and uses 1 byte of storage per value.

Spin up a Postgres database in 20 seconds with Vela.

Try Vela Sandbox

The PostgreSQL BOOLEAN data type (abbreviated BOOL) stores three-valued logic: true, false, and NULL. It is the standard choice for flag columns, feature toggles, and any binary yes/no attribute. One byte is used per stored value.

Syntax

column_name BOOLEAN
column_name BOOL   -- alias, identical behavior

PostgreSQL accepts a wide range of input literals. String literals must be quoted; only the bare keywords true and false are unquoted:

True valuesFalse values
true, 't', 'true'false, 'f', 'false'
'y', 'yes', '1''n', 'no', '0'

Practical Example

Create a product catalog with a boolean availability flag:

CREATE TABLE products (
  id        SERIAL PRIMARY KEY,
  name      VARCHAR(100) NOT NULL,
  sku       VARCHAR(50)  NOT NULL UNIQUE,
  available BOOLEAN      NOT NULL DEFAULT true
);

INSERT INTO products (name, sku, available)
VALUES
  ('Titanium Mug',       'MUG-001', TRUE),
  ('Carbon Fiber Wallet','WAL-002', FALSE),
  ('Merino Wool Hoodie', 'HOD-003', 't'),
  ('Bamboo Desk Lamp',   'LMP-004', '1'),
  ('Recycled Notebook',  'NTB-005', 'yes'),
  ('Leather Keychain',   'KEY-006', '0');

Query available products using the column directly — no comparison operator needed:

SELECT name, sku FROM products WHERE available;

Find unavailable products with NOT:

SELECT name, sku FROM products WHERE NOT available;

Verify the stored format:

SELECT name, available FROM products ORDER BY id;
          name           | available
-------------------------+-----------
 Titanium Mug            | t
 Carbon Fiber Wallet     | f
 Merino Wool Hoodie      | t
 Bamboo Desk Lamp        | t
 Recycled Notebook       | t
 Leather Keychain        | f

Adding or Changing a Default Value

Set a DEFAULT on an existing table:

ALTER TABLE products
ALTER COLUMN available SET DEFAULT false;

Now new rows inserted without specifying available default to false:

INSERT INTO products (name, sku) VALUES ('Mystery Item', 'MST-007');

SELECT name, available FROM products WHERE sku = 'MST-007';
    name     | available
-------------+-----------
 Mystery Item | f

Partial Indexes on Boolean Columns

A partial index on a boolean column indexes only the matching subset of rows, making lookups on the filtered set extremely efficient:

-- Index only available products
CREATE INDEX idx_products_available ON products (id)
WHERE available = true;

-- Verify the index is used
EXPLAIN SELECT id, name FROM products WHERE available = true;

This index is far smaller than a full-table index and speeds up dashboard queries that frequently filter on availability.

Testing with Vela

Testing default value changes or flag migrations on a production table can be risky. With Vela’s database branching, you can create an instant copy-on-write clone of your production database, apply the ALTER TABLE and data migration on the branch, run your application test suite against the branch connection string, and only promote the change once you have confirmed correct behavior — all without touching the live database.

Production Tips

  • Use the boolean column directly in WHERE clauses (WHERE is_active) rather than WHERE is_active = TRUE — it is shorter and equally readable.
  • Always pair NOT NULL with a DEFAULT for flag columns to avoid three-valued logic surprises: a NULL boolean is neither true nor false and is excluded from both WHERE available and WHERE NOT available.
  • Partial indexes on boolean columns are highly efficient — CREATE INDEX ON products (id) WHERE available indexes only active rows, keeping the index small.
  • Avoid storing boolean values as integers in PostgreSQL — the native BOOLEAN type is more readable, type-safe, and integrates with WHERE col syntax.
  • Inspect a table’s boolean columns with \d+ table_name in psql to verify defaults and constraints.

Continue in PostgreSQL Data Types: CHAR, VARCHAR, and TEXT.

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

Frequently Asked Questions

What values can a PostgreSQL BOOLEAN column store?
A BOOLEAN column stores true, false, or NULL. PostgreSQL accepts TRUE, FALSE, 't', 'f', 'true', 'false', 'y', 'n', 'yes', 'no', '1', and '0' as input. All string literals must be quoted; bare true and false keywords require no quotes.
Does querying a boolean column lock the table?
No. Simple SELECT queries on BOOLEAN columns take no exclusive lock. Only DDL changes such as adding or dropping the column, or setting a new DEFAULT, acquire an AccessShareLock on the table.
What happens to dependent views when I change a boolean column?
Adding a DEFAULT or a NOT NULL constraint does not affect dependent views. Dropping or renaming the column does affect views and will raise an error unless you use DROP COLUMN ... CASCADE or ALTER TABLE ... RENAME COLUMN, which updates view definitions automatically.
Can I use IF EXISTS with a boolean column operation?
There is no IF EXISTS guard for boolean literals, but you can use ALTER TABLE ... ALTER COLUMN IF EXISTS to safely skip the statement when the column does not exist.
What is the safest way to add a boolean column in production?
Add the column with a DEFAULT value in one statement: ALTER TABLE products ADD COLUMN is_featured BOOL NOT NULL DEFAULT false. PostgreSQL can do this without rewriting the table when the default is a constant, making it safe for large tables.