Home / Alt manpages / dropdb(1)

  • dropdb(1)
  • User command
  • linux

Drop a PostgreSQL Database Safely with dropdb

You will finish with a controlled way to remove one PostgreSQL database, including a check that your connection options point at the intended server. The examples match the dropdb shipped with PostgreSQL 16.15 on this machine, from Ubuntu package version 16.15-0ubuntu0.24.04.1.

Allow about fifteen minutes if the database is disposable and another ten minutes if you need to inspect sessions or coordinate an outage. You need the PostgreSQL client utilities, a running server, and a database role that owns the target database or has superuser privileges. Ordinary shell commands do not need sudo; the database privilege is what matters.

1. Confirm the installed command

Check the binary before preparing a destructive command:

$ command -v dropdb
/usr/bin/dropdb
$ dropdb --version
dropdb (PostgreSQL) 16.15 (Ubuntu 16.15-0ubuntu0.24.04.1)

The exact package suffix can differ on another host. Do not assume that the client version is the same as the server version: verify both when a compatibility issue matters. You can also ask for the option list without connecting:

$ dropdb --help

Checkpoint: if command -v finds a different binary, stop and inspect its package and version before using examples from this guide.

2. Identify the server and maintenance database

dropdb connects to a maintenance database and asks the server to remove the named database. It does not connect to the target database as its working session. By default it tries the postgres database, then template1 if that database is absent or is the target.

Make the destination explicit when more than one PostgreSQL instance is reachable. The host can be a DNS name, an IP address, or a Unix socket directory. The port and role are also connection choices:

$ dropdb --host=DB_HOST --port=5432 --username=DB_ADMIN --maintenance-db=postgres --if-exists --echo TARGET_DATABASE

Replace every uppercase placeholder. Do not paste a production hostname into a command intended for a test database, and do not rely on PGHOST, PGPORT or PGUSER being unset. Those environment variables supply default connection parameters and can quietly redirect an otherwise familiar command.

The command above includes --if-exists and --echo. The first avoids an error when the target is already absent, but emits a notice; it does not make a mistaken target safe. The second prints the generated SQL, which is useful for a checkpoint but is not a confirmation prompt.

3. Check the target before deleting it

Before the irreversible step, connect with psql to inspect the current database and list the names visible on that server:

$ psql --host=DB_HOST --port=5432 --username=DB_ADMIN --dbname=postgres -c 'SELECT current_database(), inet_server_addr(), inet_server_port();'
$ psql --host=DB_HOST --port=5432 --username=DB_ADMIN --dbname=postgres -c '\l'

Compare the returned address, port and database list with your change record. If postgres is not available, use the same maintenance database you plan to pass to dropdb, such as template1. Do not run the deletion until the target name and server identity are unambiguous.

Checkpoint: record the exact target as TARGET_DATABASE in your notes, then check it character by character against the command you will run. A similarly named staging database is still the wrong database.

4. Preview an interactive deletion

Use --interactive when running the command by hand:

$ dropdb --host=DB_HOST --port=5432 --username=DB_ADMIN --maintenance-db=postgres --interactive --echo TARGET_DATABASE
Database "TARGET_DATABASE" will be permanently deleted.
Are you sure? (y/n) y
DROP DATABASE TARGET_DATABASE;

The prompt is a useful human checkpoint, not a transaction or backup. Answer n to leave the database in place. The command asks for a password automatically if authentication requires one. Add --password to prompt before the connection attempt, or --no-password in a script where waiting for input would be unsafe. Avoid putting a password in the command line, where it can be exposed through process inspection or shell history.

Warning: dropping a database removes its tables, data, objects and database-level configuration. It is not an operation that can be undone with a second dropdb command. Restore from a tested backup, or recreate the database and restore its dump, if you need recovery.

5. Handle active connections deliberately

A database with other sessions may not be droppable. First inspect connections from the maintenance database:

$ psql --host=DB_HOST --port=5432 --username=DB_ADMIN --dbname=postgres -c "SELECT pid, usename, application_name, client_addr FROM pg_stat_activity WHERE datname = 'TARGET_DATABASE';"

Stop applications that should no longer use the database, then repeat the query. This gives you a chance to identify a live service rather than forcibly disconnecting it.

If the planned change explicitly permits terminating those sessions, add --force to the interactive command:

$ dropdb --host=DB_HOST --port=5432 --username=DB_ADMIN --maintenance-db=postgres --interactive --force TARGET_DATABASE

--force attempts to terminate all existing connections to the target before dropping it. It can interrupt queries and cause application errors, so use it only inside an approved maintenance window. It does not stop clients from reconnecting; prevent the application from doing that first. The role still needs the authority to terminate sessions and drop the database.

6. Verify the result

After a successful deletion, query the maintenance database and confirm that the target is no longer listed:

$ psql --host=DB_HOST --port=5432 --username=DB_ADMIN --dbname=postgres -Atc "SELECT 1 FROM pg_database WHERE datname = 'TARGET_DATABASE';"
$

An empty result is the expected result. For a repeatable check that tolerates an already absent database, use:

$ dropdb --host=DB_HOST --port=5432 --username=DB_ADMIN --maintenance-db=postgres --if-exists --no-password TARGET_DATABASE

Use --no-password only when credentials are available through an approved non-interactive method, such as a correctly protected .pgpass entry. Otherwise the command fails instead of stopping to ask for a password. This is usually the safer failure mode for automation.

Common failure boundaries

  • "database does not exist": check spelling, connection defaults and the server identity. --if-exists changes the report, not the destination.
  • "permission denied": connect as the database owner or an authorised superuser. sudo on the client machine does not grant PostgreSQL privileges.
  • Active-session errors: inspect pg_stat_activity, stop the owning application, or obtain approval for --force.
  • Authentication or password prompts: specify --username and the approved credential method. Do not place secrets in shell history.
  • Maintenance database unavailable: pass --maintenance-db=template1 only after checking that it exists and is not the target.

Done means

  • You confirmed the installed dropdb version and the actual server endpoint.
  • You checked the target name against the server's database list.
  • You used --interactive for a manual destructive run.
  • You treated --force as a service-disrupting action and obtained approval before using it.
  • The target is absent from pg_database, or a tested backup and restore path is ready if recovery is required.