Enum

How to use the PostgreSQL enum data type: creating enums with CREATE TYPE, using enums as column types, ordering, adding and renaming values, and when to use enums vs lookup tables.

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

Quick Answer

A PostgreSQL enum is a custom data type that restricts a column to a fixed set of text values defined in a specific order. Create one with CREATE TYPE name AS ENUM('val1', 'val2'); and use it as a column type. Enum values are case-sensitive and can be compared with standard operators.

Spin up a Postgres database in 20 seconds with Vela.

Try Vela Sandbox

Introduction to the PostgreSQL enum data type

An enum type restricts a column to a fixed, ordered set of string values. The ordering of values is the order in which they are declared — this means you can sort and compare enum values with standard operators (>, <, =, etc.).

Enum values are case-sensitive: 'high' and 'HIGH' are different values.

Create an enum type with:

CREATE TYPE enum_name AS ENUM('value1', 'value2', 'value3', ...);

Creating and using an enum

-- Define the enum type
CREATE TYPE priority AS ENUM('low', 'medium', 'high');

-- Use it as a column type
CREATE TABLE requests (
  id           INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  title        VARCHAR(255) NOT NULL,
  priority     priority NOT NULL,
  request_date DATE NOT NULL
);

-- Insert rows
INSERT INTO requests (title, priority, request_date) VALUES
  ('Create an enum tutorial', 'high',   '2019-01-01'),
  ('Review the enum tutorial', 'medium', '2019-01-01'),
  ('Publish the tutorial',     'low',    '2019-01-01')
RETURNING *;

Sorting and filtering by enum value

-- Sort by enum order (low < medium < high)
SELECT * FROM requests ORDER BY priority;

-- Filter requests with priority greater than 'low'
SELECT * FROM requests
WHERE priority > 'low'
ORDER BY priority;

-- Attempting an invalid value raises an error
INSERT INTO requests (title, priority, request_date)
VALUES ('Urgent task', 'urgent', '2019-01-02');
-- ERROR: invalid input value for enum priority: "urgent"

Adding new values to an enum

-- Append a new value at the end
ALTER TYPE priority ADD VALUE 'urgent';

-- Insert before or after an existing value
ALTER TYPE priority ADD VALUE 'critical' AFTER 'high';

-- Conditionally add
ALTER TYPE priority ADD VALUE IF NOT EXISTS 'urgent';

-- Verify the current values
SELECT enum_range(null::priority);
-- {low,medium,high,critical,urgent}

Getting the first and last enum values

SELECT
  enum_first(NULL::priority) AS first_value,
  enum_last(NULL::priority)  AS last_value;
-- low | urgent

Renaming an enum value

ALTER TYPE priority RENAME VALUE 'urgent' TO 'very high';

SELECT enum_range(null::priority);
-- {low,medium,high,critical,"very high"}

Production tips

  • Use enums for small, stable value sets (status codes, priority levels, days of week) — they provide type safety and natural ordering with no extra joins.
  • Avoid enums for frequently changing value sets — adding a value requires a DDL change, not just an INSERT into a lookup table.
  • Enum values are case-sensitive — standardize on lowercase or uppercase consistently to avoid subtle bugs.
  • For portability across databases, use a VARCHAR column with a CHECK constraint or a lookup table instead of an enum.

Reference: PostgreSQL documentation — Enumerated types.

Continue in PostgreSQL Data Types: XML.

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

Frequently Asked Questions

What is a PostgreSQL enum?

An enum (enumerated type) is a custom data type that constrains a column to a predefined list of string values. The values have a defined order — the order in which they are listed when the type is created — so you can use comparison operators like > and < on enum columns. Enum values are case-sensitive.

How do you create and use an enum in PostgreSQL?

First define the type: CREATE TYPE priority AS ENUM('low', 'medium', 'high'); Then use it as a column type: CREATE TABLE requests (id SERIAL PRIMARY KEY, title VARCHAR(255) NOT NULL, priority priority NOT NULL); Inserting a value not in the enum raises an error immediately.

How do you add a new value to an existing enum?

Use ALTER TYPE ... ADD VALUE: ALTER TYPE priority ADD VALUE 'urgent'; By default the new value is appended at the end. Use BEFORE or AFTER to position it: ALTER TYPE priority ADD VALUE 'critical' AFTER 'high'; Use IF NOT EXISTS to avoid an error if the value already exists.

How do you rename an enum value in PostgreSQL?

Use ALTER TYPE ... RENAME VALUE: ALTER TYPE priority RENAME VALUE 'urgent' TO 'very high'; Values containing spaces will be quoted in output. Renaming is safe and does not require updating existing rows — PostgreSQL updates the type definition in place.

When should I use enums versus a lookup table with foreign keys?

Use enums for small, stable sets of values that rarely change (e.g. RGB colors, compass directions, day of week). Use a lookup table when the value list changes frequently, when you need to store additional metadata per value, or when portability to other databases matters — not all databases support enums.