INITDB(1)
๐ initdb โ the PostgreSQL glow-up tool ๐
PostgreSQL 18.6 Documentation ยท INITDB(1) ยท she's giving database-cluster-birth energy โจ
๐ธ NAME ๐ธ
initdb โ create a new PostgreSQL database cluster. bestie, this is literally where every single Postgres era begins ๐ซถ
โจ SYNOPSIS โจ
initdb [option...] [--pgdata | -D] directory
that's it. that's the whole vibe. options go in, a directory goes at the end, and a whole cluster pops out ๐
๐ฆ DESCRIPTION ๐ฆ
okay so initdb creates a new PostgreSQL database cluster. that's the whole mission statement. no cap.
Creating a database cluster consists of a few iconic little steps: creating the directories in which the cluster data will live, generating the shared catalog tables (these are the tables that belong to the whole cluster rather than to any particular database), and creating the postgres, template1, and template0 databases.
Now let's talk about the girlies in that trio:
postgresโ a default database meant for use by users, utilities and third party applications. she's the main character ๐template1andtemplate0โ meant as source databases to be copied by laterCREATE DATABASEcommands. they're the blueprints, the patterns, the ~originals~.
๐จtemplate0should never be modified ๐จ but you can add objects totemplate1, which by default will be copied into databases created later. See Section 22.3 for more details.
Okay, real talk about permissions for a sec ๐
Although initdb will attempt to create the specified data directory, it might not have permission if the parent directory of the desired data directory is root-owned. to initialize in such a setup, the move is:
- create an empty data directory as root
- then use
chownto assign ownership of that directory to the database user account - then
suto become the database user to runinitdb
slay, problem solved ๐
who is allowed to run this? the plot twist nobody expects:
initdb must be run as the user that will own the server process, because the server needs to have access to the files and directories that initdb creates. and since the server cannot be run as root, you must not run initdb as root either.
๐ it will in fact refuse to do so. she said no and she meant it.
security tea โ โ for security reasons the new cluster created by initdb will only be accessible by the cluster owner by default. the --allow-group-access option allows any user in the same group as the cluster owner to read files in the cluster. this is useful for performing backups as a non-privileged user. very "let your friends in but only your specific friends" energy ๐ซถ
locale & encoding, the part everyone skips and then regrets ๐ญ
initdb initializes the database cluster's default locale and character set encoding. these can also be set separately for each database when it is created. initdb determines those settings for the template databases, which will serve as the default for all other databases.
By default, initdb uses the locale provider libc (see Section 23.1.4). the libc locale provider takes the locale settings from the environment, and determines the encoding from the locale settings.
To choose a different locale for the cluster, use the option --locale. there are also individual options --lc-* and --icu-locale (see below) to set values for the individual locale categories.
โ ๏ธ note that inconsistent settings for different locale categories can give nonsensical results, so this should be used with care. mixing and matching is not always the serve you think it is, bestie.
Alternatively, initdb can use the ICU library to provide locale services by specifying --locale-provider=icu. the server must be built with ICU support. to choose the specific ICU locale ID to apply, use the option --icu-locale.
๐ง heads up: note that for implementation reasons and to support legacy code,initdbwill still select and initializelibclocale settings when the ICU locale provider is used. she's got range like that.
When initdb runs, it will print out the locale settings it has chosen. if you have complex requirements or specified multiple options, it is advisable to check that the result matches what was intended. always do the vibe check on your locale output, fr fr โ
More details about locale settings can be found in Section 23.1.
To alter the default encoding, use the --encoding. more details can be found in Section 23.3. ๐
to be continued, bestieโฆ โจ
โจ OPTIONS โจ
Okay bestie, here's the whole menu of flags ๐ Every single one, no skips, no shortcuts.
-Aauthmethod</b>, *--auth=authmethod* โ sets the default auth method for local users, and it's the one that gets written intopg_hba.conf(both thehostandlocallines). Wanna know what values are legal? Peep Section 20.1.initdbwill pre-fill thosepg_hba.confentries using whatever method you picked, and it does that for non-replication and replication connections. ๐ซถ
โ ๏ธ Do not usetrustunless you genuinely trust every single local user on your system. Like, all of them. And yet โtrustis the default, because ease of installation said "main character energy" ๐
--auth-host=authmethod โ the auth method for local users coming in over TCP/IP connections; this is what lands in thehostlines ofpg_hba.conf.--auth-local=authmethod โ the auth method for local users coming in over Unix-domain socket connections; this one's for thelocallines ofpg_hba.conf.-Ddirectory</b>, *--pgdata=directory* โ where your database cluster should live. It's literally the only thinginitdbneeds from you โ but you can dodge typing it by setting thePGDATAenvironment variable, which is lowkey convenient because the database server (postgres) can find the data directory later using that exact same variable. Iconic coordination. โจ-Eencoding</b>, *--encoding=encoding* โ picks the encoding for the template databases. It also becomes the default encoding for every database you create afterwards, unless you override it at that point. All the character sets the PostgreSQL server supports are listed in Section 23.3.1.
By default, the template database encoding is derived from the locale. But if --no-locale is specified (or equivalently, if the locale is C or POSIX), then the default is UTF8 for the ICU provider and SQL_ASCII for the libc provider.
- **
-g</b>, **--allow-group-access*** โ lets users in the *same group* as the cluster owner read all the cluster files thatinitdb` creates. Heads up though: this option is ignored on Windows, because Windows doesn't do POSIX-style group permissions. Sorry bestie ๐ --icu-locale=locale โ sets the ICU locale, for when the ICU provider is the one in use. Locale support is all explained in Section 23.1.--icu-rules=rules โ extra collation rules to customize how the default collation behaves. ICU only, babes. ๐ง- **
-k</b>, **--data-checksums*** โ puts checksums on data pages so corruption from the I/O system can't just silently vibe in the background undetected. This is **enabled by default**; use--no-data-checksums` to turn checksums off.
Fair warning: enabling checksums might cost you a small performance penalty. When it's on, checksums get calculated for all objects, in all databases, and every checksum failure gets reported in the pg_stat_database view. Section 28.2 has the details.
--locale=locale โ the default locale for the database cluster. If you don't specify it, the locale is inherited from the environment thatinitdbis running in. Locale support lives in Section 23.1.
And if --locale-provider is builtin, then --locale or --builtin-locale must be specified, and it has to be set to C, C.UTF-8 or PG_UNICODE_FAST.
--lc-collate=locale,--lc-ctype=locale,--lc-messages=locale,--lc-monetary=locale,--lc-numeric=locale,--lc-time=locale โ just like--locale, but each one only sets the locale in that one specific category. One category per flag, very focused, very slay. ๐--no-localeโ literally just--locale=C. Same thing, shorter to type.--builtin-locale=locale โ the locale name to use when the builtin provider is the one doing the work. Locale support: Section 23.1.- *
--locale-provider={builtin*|libc|icu}** โ sets the locale provider for databases created in the new cluster. You *can* override it later in theCREATE DATABASEcommand whenever you make new databases. Default islibc` (see Section 23.1.4). --no-data-checksumsโ do not enable data checksums. That's it, that's the whole thing.--pwfile=filename โ makesinitdbread the bootstrap superuser's password out of a file. The first line of that file is what counts as the password. ๐-Tconfig</b>, *--text-search-config=config* โ sets the default text search configuration. More info over atdefault_text_search_config.-Uusername</b>, *--username=username* โ sets the user name of the bootstrap superuser. Defaults to the name of the operating-system user who's runninginitdb.- **
-W</b>, **--pwprompt*** โ makesinitdb` prompt you for a password to give the bootstrap superuser. If you're not planning on using password authentication, this isn't important. But otherwise? You won't be able to use password authentication until a password is set up. No password, no entry. ๐ญ -Xdirectory</b>, *--waldir=directory* โ where the write-ahead log should be stored.--wal-segsize=size โ sets the WAL segment size, in megabytes. This is the size of each individual file in the WAL log. Default size is 16 megabytes. The value must be a power of 2 between 1 and 1024 (megabytes). And heads up: this can only be set during initialization โ you cannot change it later. Periodt.
Why would you touch it? It can be useful for controlling the granularity of WAL log shipping or archiving. Also, in databases with a high volume of WAL, the sheer number of WAL files per directory can become a whole performance and management problem. Bumping up the WAL file size reduces the number of WAL files. Fewer files, fewer problems. ๐
Other, less commonly used, options are also available:
-cname=value</b>, *--set*name=value โ forcibly sets the server parameter name to value duringinitdb, AND installs that setting in the generatedpostgresql.conffile, so it'll keep applying during future server runs. You can give this option more than once to set several parameters. It's mainly useful when the environment is such that the server won't start at all using the default parameters. Emergency-mode vibes. ๐จ- *
-d</b>, *--debug*** โ prints debugging output from the bootstrap backend, plus a few other messages that the general public doesn't really care about. The bootstrap backend is the programinitdb` uses to create the catalog tables. Be warned: this option generates a tremendous amount of extremely boring output. Like, astonishing amounts. ๐ --discard-cachesโ runs the bootstrap backend with thedebug_discard_caches=1option. This takes a very long time and is only of use for deep debugging. Deep. Like, trench-deep.-Ldirectory โ tellsinitdbwhere to find its input files for initializing the database cluster. Normally you don't need this. If you do need to specify their location explicitly, you'll be told. You'll know. ๐ซถ- **
-n</b>, **--no-clean*** โ by default, wheninitdb` figures out that an error stopped it from completely creating the database cluster, it removes any files it might have created before it discovered it couldn't finish the job. This option inhibits that tidying-up, which makes it useful for debugging. -N</b>, *--no-sync*** โ by default,initdbwaits for all files to be written safely to disk. This option makesinitdb` return *without waiting โ which is faster, but means a subsequent operating system crash can leave your data directory **corrupt. Generally this is useful for testing, but it should not be used when creating a production installation. Please bestie, not in prod. ๐--no-sync-data-filesโ by default,initdbsafely writes all database files to disk. This option tellsinitdbto skip synchronizing all files in the individual database directories, the database directories themselves, and the tablespace directories โ i.e., everything in thebasesubdirectory and any other tablespace directories. Other files, like the ones inpg_walandpg_xact, will still be synchronized unless--no-syncis also specified.
Note that if --no-sync-data-files is used together with --sync-method=syncfs, some or all of those files and directories will get synchronized anyway, because syncfs processes entire file systems. Sneaky. ๐
This option is primarily intended for internal use by tools that separately ensure the skipped files are synchronized to disk.
--no-instructionsโ by default,initdbwrites instructions for how to start the cluster at the end of its output. This option leaves those instructions out. Mainly intended for tools that wrapinitdbin platform-specific behavior, where those instructions are likely to be wrong anyway.- **
-s</b>, **--show*** โ show internal settings and exit, without doing anything else. Handy for debugging yourinitdb` installation. ๐ --sync-method=method โ when set tofsync, which is the default,initdbrecursively opens and synchronizes all files in the data directory. The search for files will follow symbolic links for the WAL directory and each configured tablespace.
On Linux, syncfs may be used instead, to ask the operating system to synchronize the whole file systems containing the data directory, the WAL files, and each tablespace. Check out recovery_init_sync_method for the caveats you should know about when using syncfs.
This option has no effect when --no-sync is used.
- **
-S</b>, **--sync-only*** โ safely writes all database files to disk and exits. It does **none** of the normalinitdboperations. Generally this is useful for ensuring reliable recovery after changingfsyncfromofftoon`.
Other options:
- **
-V</b>, **--version*** โ prints theinitdb` version and exits. - **
-?</b>, **--help*** โ shows help aboutinitdb` command line arguments, and exits.
๐ธ ENVIRONMENT ๐ธ
PGDATAโ specifies the directory where the database cluster is to be stored; can be overridden using the-Doption.PG_COLORโ specifies whether to use color in diagnostic messages. Possible values arealways,autoandnever.TZโ specifies the default time zone of the created database cluster. The value should be a full time zone name (see Section 8.5.3).
๐ NOTES ๐
initdb can also be invoked via pg_ctl initdb. Two doors, same room, you're welcome. ๐ชโจ
๐ SEE ALSO ๐
pg_ctl(1), postgres(1), Section 20.1
And that's a wrap, bestie!! ๐ This lil masterpiece came to you courtesy of PostgreSQL 18.6, dated 2026, and it's the INITDB(1) page. Go forth and initialize something gorgeous. ๐๐ฆ
๐ฆ where this page comes from
- opensuse-leap 16.0: postgresql18-server 18.6-160000.1.1 ยท PostgreSQL
- opensuse-leap 16.0: postgresql18-server 18.6-160000.1.1 ยท PostgreSQL
- opensuse-leap 16.0: postgresql18-server 18.6-160000.1.1 ยท PostgreSQL
- opensuse-leap 16.0: postgresql18-server 18.6-160000.1.1 ยท PostgreSQL
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms