Data Types
Every column in a PostgreSQL table has a data type that constrains the values it can hold and determines how those values are stored, compared, and indexed. PostgreSQL ships with an unusually rich built-in type system — far broader than what most relational databases offer out of the box — and it lets you extend that system further with your own custom types, domains, and composite types.
Type categories at a glance
The table below groups PostgreSQL's most commonly used types by category. Each category is covered in more depth on its own dedicated page — this is the map of the territory.
Category | Example types | Typical use |
|---|---|---|
Numeric |
| Counts, IDs, money (NUMERIC), scientific measurements |
Character |
| Names, descriptions, free-form text |
Date/Time |
| Timestamps, schedules, durations |
Boolean |
| Flags, on/off switches, three-valued logic with |
UUID |
| Globally unique identifiers, distributed-system primary keys |
Array |
| Small, denormalized lists of scalar values |
JSON / JSONB |
| Semi-structured data, flexible schemas, API payloads |
Range |
| Reservations, price bands, validity windows |
Custom / Composite |
| Fixed value sets (enums), structured multi-field values |
Geometric |
| Coordinates and shapes (basic 2D geometry; PostGIS extends this) |
Why the type matters
Choosing the right type isn't just a formality — it affects storage size, query performance, what values PostgreSQL will reject outright, and which operators and index types are available to you. A column typed as INTEGER can never accidentally hold the string "twelve"; a column typed as TIMESTAMPTZ can never silently lose timezone information. Picking a precise type up front is one of the cheapest ways to prevent entire categories of bugs later.
PostgreSQL's type system covers numeric, character, date/time, boolean, UUID, array, JSON/JSONB, range, and custom types — plus geometric types for basic 2D data.
This breadth is a key reason PostgreSQL is called object-relational rather than purely relational.
The right type enforces correctness at the database level and unlocks type-specific operators and indexes.
Each category below has its own dedicated page with worked examples.