Temporal with PostgreSQL persistence

Running self-hosted Temporal on PostgreSQL is a documented option within a set of tested versions, and the work depends on schema setup, database availability and security settings. This page explains how to plan and verify each part.

On this page

Temporal PostgreSQL persistence: what the integration covers

If your team hosts Temporal Server in its own infrastructure and needs a database for workflow state, PostgreSQL is one of the supported choices. Temporal persistence can use PostgreSQL through the server's SQL persistence support, and the database schema is created and updated with temporal-sql-tool. The Temporal persistence documentation tests PostgreSQL 13 to 16, and PostgreSQL 14 is the oldest version still in its community support window as of the PostgreSQL versioning policy, so the version you choose should be checked against both lists before you build.

This integration covers five areas: the database connection from the Temporal services, the schema that temporal-sql-tool creates, sizing of the database for your expected workflow load, high availability of the database itself, and security of the connection and the data it holds. Each area has its own decisions. The connection decides how many services open connections and how they authenticate. The schema decides how upgrades must be sequenced. Sizing depends on your workflow history volume and retention, which you must estimate from your own workload rather than from a generic figure.

Visibility is a separate store. Temporal visibility holds the data used to list and search workflow executions, and it can run on Elasticsearch, OpenSearch, or a SQL database. Choosing PostgreSQL for persistence does not decide the visibility store, and the visibility configuration is covered on sibling pages, so this page treats it only as a boundary. Confirm early whether your visibility needs will be met by the same PostgreSQL cluster or by a different store, because that choice changes capacity planning and backup scope.

Before you start, confirm three things with your own team. First, the PostgreSQL major version you will run and its end-of-support date, since your Temporal upgrade plan will outlast some versions. Second, which team owns the database cluster, including backups, failover and patching, and whether that team already runs PostgreSQL for other systems. Third, whether your Temporal Server version and Helm chart version are compatible with the database settings you plan to use. The Temporal deployment documentation notes that Helm chart versions below 0.73.1 do not work with server images 1.30 and later, so check this during planning, not during the first deployment.

A useful way to scope the work is to write down the answers to these questions before requesting a quote: which environments will share or separate clusters, what backup and restore targets your organization requires, who approves schema changes, and whether the database must run in a separate network zone from the Temporal services. The rest of this page takes each area in turn, starting with the connection and schema, and then moving to sizing, high availability and security.

What you need before connecting Temporal to PostgreSQL

These six items decide whether Temporal can reach its database, start cleanly and stay secure once it runs. Settle them in the order listed, since the server version shapes the schema and database steps that follow. Work through each item with your platform, database and security owners so the first schema run is not the first real test of the setup.

Temporal Server version and deployment method

Fix the server version and deployment method before anything else, because schema and upgrade steps depend on both. Temporal Server v1.32.1 was published on October 8, 2026, with patch releases v1.31.4 and v1.30.8 for earlier minor lines. Choose Docker Compose, Go binaries, a Helm chart that runs each service in its own Kubernetes pod, or a custom Go build. If you use Helm, the documented chart floor is 0.73.1 for server images 1.30 and later, so confirm the chart version before you pin the image.

Supported PostgreSQL version

Temporal's persistence testing covers PostgreSQL 13 to 16, so check the Temporal persistence documentation for the server release you chose before you select a newer database major. The PostgreSQL project currently supports versions 14 through 18, and version 14 reaches end of life on November 12, 2026. Pick a version that stays supported for your planned operating life, and confirm how you will move between majors later using a planned upgrade method.

Database account with schema rights

Create a dedicated database account for Temporal rather than sharing an administrative login. Schema setup and later schema upgrades need rights to create and alter tables, while routine operation needs far fewer. Ask your DBA to confirm whether one account or two will run setup and daily operation, and record the decision. Avoid superuser roles for the runtime account, and keep the credentials in your approved secrets store.

Network reachability from Temporal hosts

Every Temporal Server host must reach the PostgreSQL primary on its listening port, and the database should accept connections only from those hosts. Confirm firewall rules, routing, DNS names and any connection pooler in the path, such as PgBouncer, before the first schema run. Test from each Temporal host itself, since a path that works from one subnet can fail from another. Also confirm how failover endpoints resolve if your database runs in a high availability setup.

TLS and certificate material

Decide whether connections between Temporal and PostgreSQL use TLS, and gather the certificate material before setup begins. You need the CA bundle that signs the database server certificate, plus client certificates if the database uses certificate authentication. Confirm the chain, expiry dates and hostname matching, and name the owner of renewal. Temporal's mTLS settings for internode and frontend traffic are a separate configuration and need their own certificates.

Private hosts, not public internet

Run Temporal services on hosts that are not reachable from the public internet, with network access limited to trusted internal networks, as the Temporal deployment documentation directs. Self-hosted Temporal uses a noopAuthorizer by default when no Authorizer is configured, which allows every API request with no authentication or access control. An exposed frontend is therefore a direct risk. Confirm that load balancers, bastions and monitoring endpoints follow the same boundary.

Which PostgreSQL versions Temporal persistence supports today

Temporal's persistence documentation lists PostgreSQL 13 to 16 as the versions it tests against. PostgreSQL's own versioning policy lists 14, 15, 16, 17 and 18 as supported. The two lists overlap on 14, 15 and 16, which are the only major versions that appear in both. The PostgreSQL end-of-support dates are November 12, 2026 for 14, November 11, 2027 for 15, November 9, 2028 for 16, November 8, 2029 for 17 and November 14, 2030 for 18. Version 13 and earlier are unsupported by PostgreSQL and should not be chosen for a new deployment, even though Temporal still lists 13 as tested.

The gap is versions 17 and 18. PostgreSQL supports them, but Temporal's persistence page does not list them as tested, so the documented test matrix does not cover them. That does not mean they fail, and it does not mean they work. Before you choose either version, read the Temporal release notes for the server version you plan to run and confirm whether PostgreSQL 17 or 18 is named as supported for that release. If the notes are silent, ask Temporal directly what testing exists for the version you intend to use, and record the answer in your design file so the decision can be audited later.

Use these two lists in a fixed order. Start from the Temporal release notes for your server version, then pick the newest PostgreSQL major version that both those notes and PostgreSQL's policy support. Plan the end-of-support date into that choice. A database built on version 14 today reaches end of support on November 12, 2026, so it will need a major upgrade soon after go-live. A major upgrade of the database is separate work from Temporal schema and server upgrades. It needs its own test window, a restore rehearsal and a rollback plan. Minor PostgreSQL releases keep the storage format, so they are lower-risk maintenance that you can schedule on their own.

SQLite is meant only for development and testing. Use it on a developer workstation or in a throwaway test environment to try workflows, but never as the persistence layer for a shared, staging or production Temporal service. Any environment that stores real workflow history needs one of the production stores Temporal documents, and for this page that means PostgreSQL. Write the rule into your environment standards and check it during configuration review of Docker Compose files or Helm values, so a development setting does not reach a shared cluster. Confirm the current list of supported stores in the persistence documentation before you commit, because support changes between server releases.

How the Temporal PostgreSQL persistence setup runs in order

This sequence takes a self-hosted Temporal Server from version checks to a running server on PostgreSQL, with the schema in place and a test workflow completing. Each step ends with a check so that problems surface where they are introduced. Your platform and database teams perform the steps in your environment, and DeployOpen can run them under a fixed-scope engagement.

  1. Confirm server and PostgreSQL versions

    Before anything is installed, select the Temporal Server release and the PostgreSQL major version together. Temporal's persistence documentation lists testing against PostgreSQL 13 to 16, so confirm in the current release notes and persistence docs that your chosen major version is covered. PostgreSQL 14 is supported only until November 12, 2026, so factor that date into your plan. If you are upgrading an existing deployment, move one minor version at a time. Done when the team has written down the server release, the PostgreSQL major version and the documentation pages it checked.

  2. Provision the PostgreSQL database and role

    A database administrator creates an empty PostgreSQL database for Temporal and a login role for the schema tool. The role needs the rights that the official schema setup documentation lists for creating database objects, and no more. Confirm that list for your Temporal release instead of copying grants from another project. Keep the database on a private network segment, consistent with Temporal's guidance that its services run on hosts not reachable from the public internet. Done when you can connect to the empty database with that role from the host that will run temporal-sql-tool.

  3. Create the schema with temporal-sql-tool

    Run temporal-sql-tool against the empty database to create the Temporal schema, using the setup command and flags shown in the official self-hosted persistence documentation for your release. Run the tool from the release family you plan to operate and keep its output with your change record. Schema changes for later releases are separate work, and the upgrade documentation says schema upgrades run before server upgrades when release notes call for them. Done when a query of the database's schema version returns the version that the release documentation expects.

  4. Configure the persistence section of the server config

    The platform engineer sets the persistence section of the Temporal server configuration so that the default store points to PostgreSQL, using the host, port, database name and role from the earlier steps. Store the password in your secrets system and reference it from configuration rather than writing it into a plain file. Key names in this section can change between releases, so check them against the self-hosted configuration reference for your version. If you also use PostgreSQL for advanced visibility, configure that store with its own section. Done when the configuration is in place on the staging host and ready for the next step.

  5. Start the Temporal server

    Start the Temporal Server services with the configuration from the previous step, using the deployment method you selected, such as Docker Compose, Go binaries or Helm. If you deploy with Helm, confirm the chart version against the server image, because chart versions below 0.73.1 do not work with server images 1.30 and later. Watch the startup logs for database connection errors or schema mismatch messages. Done when every service reports as running and the frontend answers a basic cluster status request from an internal host using the Temporal CLI.

  6. Verify namespace creation and a test workflow

    Create a namespace with the Temporal CLI and confirm that it appears in the namespace list. Then run a small test workflow with a worker from a development client that connects through the frontend, and check that the workflow completes and its history is visible in the Web UI or the CLI. Record the results together with the server release and schema version so later upgrades have a baseline. The default configuration has no Authorizer, so this test accepts unauthenticated requests. Confirm access controls before any shared use. Done when the namespace is listed and the test workflow reaches a completed status.

How schema setup and server upgrades depend on each other

In a self-hosted Temporal deployment on PostgreSQL, the persistence schema and the Temporal Server version must move together in a fixed order. The tool that creates and changes that schema is temporal-sql-tool. Before you plan any server upgrade, read the release notes for the target version. When they call for a schema upgrade, that schema change has to run before the server is upgraded. Treating the two as independent steps is one of the more common ways an upgrade stalls partway through, because the new server expects database structures that do not yet exist.

Temporal's documented rule is to upgrade one minor version at a time. Backward compatibility is guaranteed only between two successive minor versions, so a jump across several minor lines is not a supported path. The documented practice is to move first to the latest patch release of your current minor line, then step to the next minor line. Plan the sequence as a list of intermediate versions before the change window opens, and confirm the schema requirements for each step. Ask your team to record which schema version each server version expects, so the rollback point for every step is clear.

Test every schema change in a non-production environment that matches production closely enough to be useful. Use a PostgreSQL version from the supported range, the same Temporal Server version and configuration, and a copy of production-scale data where practical. Run the schema update, start the new server, and check that workflows start, complete and replay as expected. Decide in advance how you will roll back. Schema changes are not always reversible in the same way as a binary swap, so confirm with Temporal's documentation whether a rollback of a schema step is supported, and take a verified database backup before you begin.

The detailed schema steps, including commands and the order for each version pair, are covered in the Temporal Cluster upgrade pages in the sibling group. Use those pages as the working runbook and this section as the decision framework. Confirm the schema requirements against the release notes for each version you plan to pass through, because the exact steps depend on the versions involved. If you use a Helm chart to deploy the server, check its version compatibility as well, since chart versions and server image versions must match the documented pairings.

Finally, assign ownership for the schema step. The person who runs temporal-sql-tool should be the same person who reviews the release notes and signs off the rollback plan. Record the outcome of each non-production test, the backup identifier and the decision point after which you will not roll back. This record is useful for your change board and for later audits of how production changes were controlled.

Which Temporal stores map to PostgreSQL and which need another system

This table maps each Temporal store to PostgreSQL and to the other databases Temporal documents for that role. Confirm each row against the server version you plan to run, because support ranges differ between persistence and advanced visibility and change across minor releases. The main takeaway is that PostgreSQL covers persistence and advanced visibility, while Elasticsearch or OpenSearch is a separate system to plan for once visibility queries grow.

Temporal storePostgreSQL support and rangeOther documented optionsSeparate system needed
Persistence storeSupported on PostgreSQL 13 to 16Cassandra 3.11, 4.0 and 5.0.4 or later; MySQL 5.7 and 8.0.19 or laterNo. PostgreSQL holds this data directly.
Advanced visibility storeSupported on PostgreSQL 12 or later, from server 1.20Elasticsearch 7 and 8; OpenSearch 2 or later from server 1.30.1; MySQL 8.0.17 or laterNo for PostgreSQL. Yes if you choose Elasticsearch or OpenSearch, which Temporal recommends beyond a few workflow executions.
Cassandra as visibility storeNot applicable. PostgreSQL is not a Cassandra option hereCassandra visibility was removed in server 1.24Not applicable. Do not plan a Cassandra visibility store on current releases.
SQLiteNot applicable for productionDevelopment and testing onlyNot applicable. Use PostgreSQL or another supported store for any shared environment.
Web UI and other componentsConfirm in your target server release notesConfirm in your target server release notes before sizingConfirm before design. Plan identity for the Web UI, such as OIDC single sign-on, separately.

How to size and protect the PostgreSQL database under Temporal

Sizing the PostgreSQL database starts with knowing what drives its load and growth. Under Temporal, the database stores workflow execution state and event history, so growth follows three inputs: how many workflow executions run, how many events each execution records, and how long closed executions stay in the namespace before the retention period removes them. Ask your team to estimate these inputs from your own workflow design, including activity counts and typical run length, rather than relying on a generic figure. If you also use PostgreSQL for advanced visibility, list queries and search attribute writes add reads and writes on top of execution persistence. Load test with workflow shapes that match production, measure table growth under your retention setting, and confirm against the Temporal persistence documentation how each table grows for your server version.

PostgreSQL supports hot standby servers that accept read-only queries, which gives you a copy ready to take over when the primary fails. The replication mode is the key decision. With synchronous replication, a commit waits until a standby confirms it, so less committed data is at risk during a failure, but every write pays the network round trip to that standby in commit latency. With asynchronous replication, commits return sooner, but a failover can lose the most recent transactions that had not reached the standby. Temporal writes history on the critical path of every workflow task, so measure commit latency between your zones before choosing a mode. Be aware that PostgreSQL does not detect a failed primary or notify the standby. Automatic failover needs external tools, which you must select, configure, test and operate, including a fencing step so a former primary cannot keep accepting writes.

Connection management is the next place where the database limits a Temporal deployment. Each Temporal service and its pods open connections to PostgreSQL, and as the number of replicas grows, the total can reach the server's connection limit and slow every service. PgBouncer can pool connections between the Temporal services and the database, which reduces the number of server-side connections. Confirm before rollout that the pooling mode you choose works with Temporal's persistence driver and with any session-level behavior it depends on. Test failover through the pooler as well, because the connection target changes when a standby is promoted and the pooler must route to the new primary. Track connection counts and wait times after go-live so pool sizing stays matched to the service replica count.

Point-in-time recovery depends on a base backup plus continuous archiving of write-ahead log segments. It lets you restore to a chosen moment only if the archive has no gaps, so archiving failures need an alert of their own. Store archives outside the failure domain of the primary, and set retention to match the recovery window your business requires. Schedule restore drills into a separate environment: restore the base backup, replay archived logs to a target time, start Temporal against the restored database with the matching server and schema versions, and check that sample workflow executions and their histories read correctly. Record the measured restore time and the data loss window from each drill, and update the runbook with what you learn. An archive that has never been restored is an untested assumption.

How to secure the Temporal to PostgreSQL connection and the API

A self-hosted Temporal cluster has two exposure points: the connection from Temporal services to the PostgreSQL persistence store, and the Temporal API that workers, clients and the Web UI call. Each has its own authentication model and defaults, so each needs a deliberate decision before the cluster handles production workflows. The cards below cover the database side first, then the API controls and the checks that confirm they apply to your deployment.

PostgreSQL authentication methods

PostgreSQL supports several client authentication methods, including password, certificate, GSSAPI, LDAP and OAuth, selected per connection in the server's host-based authentication configuration. For Temporal, decide which method the Temporal services use to reach the persistence database and which database role they run as. Confirm the method against the PostgreSQL version you run, because the available options and their settings depend on that version. Keep the role limited to the schemas Temporal needs.

Moving off MD5 password authentication

PostgreSQL 18 deprecated MD5 password authentication in favor of SCRAM. If your Temporal database roles or existing connection settings still use MD5 hashes, plan a move to SCRAM before or during the upgrade to PostgreSQL 18. Check the password encryption setting on the server, the hashes stored for each Temporal role, and the client configuration of every service that connects. Test the change in a non-production environment first, since a mismatch blocks the Temporal services from starting.

Certificate and transport encryption for the database

Client certificates and encrypted connections protect the traffic between Temporal services and PostgreSQL, especially when the database sits on a separate host or network segment. Decide whether the servers verify the server certificate, whether clients present their own certificate, and how certificates are issued, rotated and revoked. Confirm the exact connection parameters your Temporal version accepts for TLS, since they are set in the Temporal persistence configuration and in the PostgreSQL server settings.

Network placement of Temporal services

The Temporal deployment documentation says Temporal services should run on hosts that are not reachable from the public internet, with network access restricted to trusted internal networks. Apply this to the frontend, history, matching and worker services, and to the PostgreSQL listener. Limit which source addresses can reach the database port, and confirm that firewall or security group rules match the topology you actually deploy, including Kubernetes network policies if you use Helm.

Default authorization on the Temporal API

If no Authorizer is configured, self-hosted Temporal uses the default noopAuthorizer, which allows every API request with no authentication or access control. Treat this as an open API until you configure an Authorizer and confirm it blocks unauthorized calls. Test with a client that has no credentials and with a client that holds a role for only one namespace. Record which namespaces each identity can reach before any workflow reaches production.

mTLS and identity mapping

Self-hosted Temporal supports mTLS with separate settings for internode traffic and frontend traffic, so you can encrypt service-to-service calls and authenticate clients on the frontend independently. A ClaimMapper maps JWT or certificate claims to namespace roles. Decide which identities workers, clients and operators present, how their certificates or tokens are issued, and which claims grant which namespace roles. Confirm the exact claim fields your identity provider emits before writing the mapping.

OIDC sign-in for the Web UI

Temporal supports OIDC single sign-on for the Web UI, so operators authenticate through your identity provider instead of a shared access path. Decide which identity provider and client registration the Web UI uses, which groups or claims grant access, and how the Web UI reaches the frontend service. Confirm the callback addresses, token lifetimes and session behavior against the version you run, and keep the Web UI off public networks unless your access design requires it.

Payload encryption with codecs

Temporal can encrypt workflow and activity payloads through custom codecs and a codec server, so sensitive data is not stored in plain form in the persistence database. Decide which payloads carry regulated or confidential data, where encryption keys are held and rotated, and who can decrypt payloads in the Web UI through the codec server. Note that encryption protects payload content but does not replace the database and API controls above, and confirm the codec approach with your security team before workflows handle personal data.

When Cassandra is the better fit than PostgreSQL for Temporal

Choose Cassandra for persistence only when your organization has a concrete reason to, and be wary of any single number that claims to settle the question. Temporal's persistence documentation lists Cassandra 3.11, 4.0 and 5.0.4 or later as tested versions, alongside PostgreSQL 13 to 16 and MySQL 5.7 and 8.0.19 or later. Both paths are supported, so the decision turns on fit. Four factors should drive it: the database skills your team already has, the operating model you can sustain over time, the write volume your workflows will generate, and how long you must keep workflow history. Assign an owner to each factor before the comparison starts, because a choice that looks right on one factor often changes when another is weighed.

Visibility is the part of this decision that changes most. Cassandra visibility was removed in Temporal Server 1.24, so a Cassandra persistence deployment still needs a separate visibility store, and so does a PostgreSQL one. Temporal's visibility documentation supports Elasticsearch 7 and 8, OpenSearch 2 or later from Temporal Server 1.30.1, and MySQL 8.0.17 or later, PostgreSQL 12 or later and SQLite from 1.20. It also recommends Elasticsearch or OpenSearch for anything beyond a few workflow executions. Choosing Cassandra for persistence therefore adds a second data platform to build, back up, secure and upgrade alongside the visibility store. Confirm the visibility choice in the same design review as the persistence choice, so the two are not decided in isolation.

Run a workload test with your own data before committing to either store. Use realistic workflow shapes from your own designs: activities per workflow, signal and timer patterns, payload sizes, retention periods and the number of namespaces you expect. Measure sustained write throughput, persistence latency at peak load, history growth over time, and the time needed to restore the database from backup into a test environment. Run the same test against both candidate stores, on comparable hardware, with the same Temporal Server version, so that the results reflect the store and not the setup. Record the operational steps each store required, including schema setup, upgrades and failover, because those steps consume most of a team's effort after go-live.

Before the test, confirm the points that no document can answer for you. Ask whether your database team already operates Cassandra's routine maintenance and node replacement procedures, or whether it runs PostgreSQL daily, including the replication and failover tooling that PostgreSQL does not supply on its own. Confirm which Cassandra and PostgreSQL versions your platform team can support in your environment, and check the Temporal release notes for the server version you plan to run. Agree on who is paged when persistence degrades and which runbook they follow. A store that performs well in a test can still be the wrong choice if the team that must run it at night cannot support it confidently.

Write the decision down with its evidence: the test results, the supported versions, the visibility store, the staffing assumptions and the owner of each factor. Revisit the record whenever the Temporal release notes change persistence or visibility support, because version support for either store can change between releases. If the results favor Cassandra, plan the visibility store and its upgrade path in the same design document from the start, not as a later task. If they favor PostgreSQL, record the database high availability and backup decisions that come with it, so the choice is complete and auditable.

Temporal PostgreSQL persistence failures and their fixes

This table lists six failures that self-hosted Temporal on PostgreSQL commonly shows, with the likely cause, the check to run and the fix for each. Work through the rows in order when a deployment stops after an upgrade or a database change. The main takeaway is that most failures trace back to upgrade order, schema state or connection handling.

FailureLikely causeCheck to runFix
Schema version mismatch after a server upgradeThe server moved to a version whose schema changes were not applied to the databaseCompare the schema version in the database with the version the server release expectsApply the schema upgrades for the target version with temporal-sql-tool, then restart the server
Server starts before schema upgrades runThe rollout replaced server services before the schema job finishedReview rollout order and schema job logs to confirm the schema step completed firstRun schema upgrades first, then roll out server services, following the release notes order
Connection exhaustion without poolingEach Temporal service opens direct connections, and the total exceeds the PostgreSQL connection limitCompare active connections in pg_stat_activity with max_connections during peak loadPlace a connection pooler such as PgBouncer in front of the database and size pool limits to the connection budget
Authentication failures after moving to SCRAMPasswords are still stored as MD5, pg_hba.conf names the old method, or the client driver lacks SCRAM supportCheck password_encryption, the method in pg_hba.conf and the SCRAM support of the database driverReset role passwords so they are stored as SCRAM, set the scram-sha-256 method, and update the client
Helm chart older than 0.73.1 with server images 1.30 and laterThe release uses a chart version below 0.73.1 with a server image of 1.30 or laterCheck the chart version of the release and the server image tag in the deployed manifestsUpgrade the chart to 0.73.1 or later before moving the server image to 1.30 or later
Failover does not occurPostgreSQL does not detect a failed primary or promote a standby on its own, and no external tool is configuredConfirm whether an external failover tool exists and test a controlled switchover in a non-production environmentDeploy and test an external failover tool, and confirm the server endpoint follows the new primary

Questions teams ask before running Temporal on PostgreSQL

How much does it cost to run Temporal on PostgreSQL?

The cost has five parts: server infrastructure, managed or self-run PostgreSQL hosting with storage and backups, database administration time, testing, and any partner fee set by a written scope. Infrastructure, database administration and patching recur every month or quarter, while design, initial schema setup and the first test cycle are mostly one-time. Cost rises with the number of environments, the database high availability design and the security controls you require. For a managed comparison, the Temporal pricing page lists Temporal Cloud pay-as-you-go pricing from 50 US dollars per million actions, plus storage rates of 0.042 US dollars per GB-hour for active storage and 0.00105 US dollars per GB-hour for retained storage. Ask any partner for a quote that separates one-time work from recurring work and names who pays for each line.

How long does a self-hosted Temporal and PostgreSQL setup take?

Duration depends on the scope you agree, not on a standard timeline. The main drivers are whether a PostgreSQL platform with high availability and backups already exists, whether you have a Kubernetes cluster ready for Helm-based deployment, how many environments you need, and how much identity and network hardening is required. Security requirements add time: Temporal's documentation says services should run on hosts not reachable from the public internet, and mTLS, ClaimMapper roles, an Authorizer and OIDC sign-in each need design and testing. Upgrade constraints also matter, since Helm chart versions below 0.73.1 do not work with server images 1.30 and later. Ask for a written plan with milestones and the assumptions behind each one.

What does a PostgreSQL-backed Temporal project need from our staff?

Plan on named owners in several groups. Your platform or Kubernetes team deploys and operates the Temporal services, and your database administrators size, back up and monitor PostgreSQL, including replication and point-in-time recovery. Network and security staff define the internal-only access paths and certificate authority for mTLS. Your identity team connects OIDC for the Web UI and maps claims to namespace roles. Application teams own the workers and workflow code, and someone must own on-call response for the service. Also confirm who approves changes to the Temporal Server version and schema, because upgrades must follow the documented order. If these owners are not identified before the work starts, the schedule is usually the first thing to slip.

Can our team run Temporal on PostgreSQL without outside help?

A team with solid Kubernetes and PostgreSQL experience can do it, since Temporal documents several deployment methods and tests persistence on PostgreSQL 13 to 16. The difficult parts are usually not the first install. They are the security defaults, the database failover design, and the upgrade sequence. Temporal's default noopAuthorizer allows every API request until you configure an Authorizer, and PostgreSQL does not detect a failed primary or promote a standby on its own. Upgrades must move one minor version at a time, with schema changes first when release notes call for them. A partner can take on scoped deliverables such as the build, hardening, testing and runbooks, while your team keeps operational ownership. Decide which parts you will own before you choose.

Which PostgreSQL version should we choose for Temporal?

Start with the versions Temporal tests against. Its persistence documentation lists PostgreSQL 13 to 16, but PostgreSQL 13 is already outside its community support window. According to the PostgreSQL versioning policy, PostgreSQL 14 is supported until November 12, 2026, PostgreSQL 15 until November 11, 2027, PostgreSQL 16 until November 9, 2028, PostgreSQL 17 until November 8, 2029, and PostgreSQL 18 until November 14, 2030. Because the Temporal persistence list in the supplied documentation stops at 16, confirm with Temporal's current persistence page whether it supports 17 or 18 for your server version before you choose. Plan your major upgrade path before go-live, because each PostgreSQL major version has a fixed end-of-support date.

How do we keep PostgreSQL highly available for Temporal?

PostgreSQL supports hot standby servers and two replication modes: synchronous replication, where a commit waits for standbys, and asynchronous replication. Synchronous replication reduces data loss on failover but adds commit latency, so test it with your Temporal workload before choosing it. PostgreSQL does not provide automatic failover software, so you need an external tool to detect a failed primary and promote a standby, and you need to test that promotion path. Connection pooling with PgBouncer can reduce connection pressure, and continuous archiving with point-in-time recovery covers corruption or operator error that replication copies. Test restores on a schedule, not only the backup jobs. Confirm the design with your database team and your Temporal version's documented requirements.

What recurring work follows after a Temporal and PostgreSQL go-live?

Recurring work falls into three groups. PostgreSQL minor releases come at least once every three months, and they do not change the storage format, so applying them means replacing executables and restarting. Major upgrades need a planned method such as pg_upgrade, pg_dumpall with restore, or logical replication, which can limit downtime to several seconds according to the PostgreSQL documentation. Temporal Server upgrades must go one minor version at a time, starting with the latest patch of the current minor, and schema upgrades must run before server upgrades when the release notes call for them. Add regular reviews of the Authorizer, certificates, backups and monitoring alerts. Budget staff time for these tasks every month and for each major upgrade, and ask any partner to price them separately from the build.

How DeployOpen scopes and delivers Temporal persistence work

DeployOpen plans, implements, hardens, documents and supports self-hosted Temporal with PostgreSQL persistence inside your own cloud accounts, data centers or air-gapped networks. Most engagements are fixed-scope, with deliverables and timelines agreed in writing before work starts. Ongoing support, upgrades and continuous testing are available as retainers.

How we scope

  • The written scope names the PostgreSQL major version and the Temporal Server release it must support.
  • It records the schema setup with temporal-sql-tool, the sizing inputs and the database high availability design.
  • Engagements are fixed-scope, and the scope also states when Cassandra would be the better fit for your workload.

How we build

  • Temporal services run on hosts not reachable from the public internet, with access limited to trusted networks.
  • Deployment uses Docker Compose, Go binaries or Helm charts, with chart versions 0.73.1 or later for server 1.30+.
  • Authorization, mTLS and OIDC for the Web UI are configured before workflow traffic is accepted.

How we hand over

  • Handover includes the schema version record, server and PostgreSQL configuration, and the runbook for each upgrade.
  • Upgrades go one minor version at a time, with schema upgrades run before server upgrades when release notes require them.
  • Backup, point-in-time recovery and PostgreSQL major upgrade procedures are documented for your operators.

How we support

  • Ongoing support, upgrades and continuous testing are available as retainers after handover.
  • Retainers can cover Temporal Server minor upgrades, PostgreSQL minor updates and schema changes between releases.
  • Ask for the PostgreSQL support window, the Temporal release you plan to run and who patches each layer.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.