PostgreSQL Data Types
A reference of PostgreSQL data types with storage and the notes that matter: integers and identity, numeric, text versus varchar, timestamptz, uuid, jsonb, network types, arrays, ranges and extensions.
Free · No sign-up · Your inputs stay in your browser
Reference
PostgreSQL data types
| Type | Storage | Range and notes |
|---|---|---|
| smallint / integer / bigint | 2 / 4 / 8 bytes | ±32,767; ±2.1 × 10^9; ±9.2 × 10^18. No unsigned types. |
| generated always as identity | - | The modern auto-increment, replacing serial and bigserial. |
| numeric(p,s) | variable | Exact, up to 131,072 digits before the point. For money. |
| real / double precision | 4 / 8 bytes | Approximate floating point. |
| boolean | 1 byte | true, false or null. |
| text | variable | Unlimited length, and no slower than varchar. The idiomatic string type. |
| varchar(n) | variable | text with a length check; changing n later rewrites nothing since 9.2. |
| char(n) | variable | Blank-padded; rarely what you want. |
| bytea | variable | Binary data. |
| uuid | 16 bytes | Native type; gen_random_uuid() is built in since 13, uuidv7() since 18. |
| date | 4 bytes | 4713 BC to 5874897 AD. |
| timestamp | 8 bytes | Without time zone: a wall-clock time with no zone attached. |
| timestamptz | 8 bytes | With time zone: stored as UTC, shown in the session's TimeZone. Use this for events. |
| time / timetz | 8 / 12 bytes | Time of day. |
| interval | 16 bytes | A duration: '2 days 3 hours'. |
| json | variable | Stored as text, keeps formatting and duplicate keys. |
| jsonb | variable | Binary, indexable with GIN, deduplicated keys. Use jsonb unless you need the original text. |
| inet / cidr | 7 or 19 bytes | IPv4 and IPv6 addresses and networks, with operators like << (is contained by). |
| macaddr | 6 bytes | |
| integer[] / text[] | variable | Arrays of any type, indexable with GIN. |
| int4range / tstzrange | variable | Ranges, with exclusion constraints to forbid overlapping bookings. |
| tsvector / tsquery | variable | Full-text search. |
| enum (CREATE TYPE) | 4 bytes | Values can be added but not removed or reordered easily. |
| money | 8 bytes | Locale-dependent formatting; numeric is the safer choice. |
| point / polygon (PostGIS geometry) | variable | Built-in geometric types; PostGIS adds geography with real-world units. |
| vector(n) (pgvector) | 4 × n + 8 bytes | Extension for embeddings with HNSW and IVFFlat indexes. |
From the PostgreSQL documentation, current through version 18. The two choices that cause the most pain later: timestamp where timestamptz was meant, and json where jsonb was meant. Both are easy to get right on day one and expensive to migrate.
About this tool
Method, assumptions, practical next steps, and limits.
Two common mistakes
timestamp without time zone stores a wall-clock time and is the wrong choice for events; timestamptz stores an absolute instant and displays it in the session zone. json keeps text as written and cannot be indexed efficiently; jsonb is parsed, indexable with GIN and almost always what you want. The data types chapter covers every type.
text is fine
In PostgreSQL text and varchar have the same performance; varchar(n) only adds a length check. Use text with a CHECK constraint when a limit is a business rule.