PostgreSQL setup for Apache Fineract starts with the tenants database
PostgreSQL is the recommended database for Apache Fineract, and a production setup centers on five decisions: the tenants database and its tenant schemas, connection pooling through HikariCP variables, running the database in UTC, read replicas for read instances, and storage sized for transaction history. A team preparing a self-hosted, multi-tenant core banking deployment needs to make each of these choices explicitly and write them down before the first environment is built. Fineract routes each API request through the Fineract-Platform-TenantId header, and the connections for each tenant are read from a tenants database. That database is the directory of where tenant data lives, so its design shapes everything that follows.
The Fineract README is direct that a production deployment can be complex, costly and time-consuming, and that the project does not provide a comprehensive production deployment guide. The database layout, backup scope and failover design are therefore the team's own decisions, not defaults the project supplies. Confirm the exact tenants database and tenant schema setup for your chosen release in the Apache Fineract platform documentation and in the repository, then record the naming, ownership and privilege model for each database role. Treat the tenants database as a control point: a wrong entry there can point a tenant at another tenant's data.
Fix the time zone, pool and replica decisions early, because they are hard to change once data accumulates. Set the database and application instances to UTC so that interest, accrual and business-date logic does not depend on server locale. Size connection pools per instance type, since read, write and batch instances place different loads on the same server, and confirm the FINERACT_HIKARI_* settings against your PostgreSQL connection limits. Plan read replicas only where read instances will use them, and document which workloads are allowed to read stale data. Finally, estimate storage for transaction history with your data owners, and ask the vendor or your own DBA to confirm growth assumptions for your release.
Which PostgreSQL configuration options change the design
This table compares the PostgreSQL and Fineract settings that shape the architecture, from tenant layout to pool sizing, time zone, replicas and storage. Read each row as a decision: when the option fits, what it affects, and what to confirm in the Fineract documentation for your release before you commit.
| Decision | When it fits | What it affects | What to confirm |
|---|---|---|---|
| Tenants database with per-tenant schemas | Any multi-tenant Fineract deployment, where each tenant or legal entity needs its own data set | Tenant isolation, backup scope, restore granularity and the number of schemas the server must manage | Confirm how the tenants database registers each schema and how your chosen release expects tenant connections to be configured |
| Separate tenant databases per institution | Institutions with strict data residency or separate operational ownership of each tenant | Stronger isolation, but more databases to back up, patch, monitor and migrate, and higher operational cost | Confirm whether your release and operating model support this layout and how tenant records map to each database |
| HikariCP pool settings through FINERACT_HIKARI_* variables | Every deployment, with pool size chosen per instance type (read, write, batch) | Total connection count on PostgreSQL, timeouts during Close of Business, and queueing under peak load | Confirm the exact variable names, defaults and recommended sizes for your release in the Fineract documentation |
| Server and application time zone set to UTC | Deployments that serve more than one region, or that need consistent business dates and audit timestamps | Accuracy of interest accrual, business date logic, reporting cut-offs and audit trails across servers | Confirm how Fineract handles business dates and time zones in your release, and align the database, container and host clocks |
| Read instances on streaming replicas | High read load from reporting or self-service, using the documented read, write and batch instance model | Reporting freshness, because replicas lag the primary, and the separation of read traffic from write and batch work | Confirm which endpoints the read instance serves in your release and how replica lag is measured and tolerated |
| Synchronous or asynchronous replication for the primary | Synchronous replication when no committed posting may be lost; asynchronous when lower commit latency matters more | Commit latency on every posting, data loss exposure on failover, and the choice of standby for read traffic | Confirm the replication mode with your recovery objectives; PostgreSQL does not detect primary failure, so failover tooling is a separate decision |
| Storage sizing for transaction history | Any production ledger, because journal entries, loan schedules and audit records grow with every posting and business day | Disk growth rate, vacuum load, backup size, restore time and the cost of retained history | Ask for a growth estimate based on your account volume and history retention period, then test it on a copy of realistic data |
Which PostgreSQL topology fits each environment
A non-production environment exists to test configuration, migrations and integrations, so a single PostgreSQL server is usually enough. Create the tenants database and the tenant schemas on that server, and keep the environment's data disposable enough that a restore from a dump is an acceptable recovery path. Because no customer data should sit there, the replication and failover decisions for production do not need to be copied into this tier.
- Single server: One PostgreSQL instance hosts the tenants database and every tenant schema, which keeps setup and reset simple.
- No standby by default: Without a standby, there is no automatic failover to configure, so an outage means a restart or a restore.
- Data handling: Use masked or synthetic data where possible, because a non-production copy of client records still carries privacy obligations.
- Version parity: Run the same major PostgreSQL version as production so that upgrade and migration tests mean something.
Confirm with your team which PostgreSQL major version production will run, and check that your test environment matches it before any migration rehearsal.
A production deployment with one write instance and one batch instance needs a primary database that accepts all writes, plus at least one standby so that a failed primary does not end the business day. Fineract runs Liquibase migrations only on the write instance, so the write path must always be reachable. Choose synchronous replication when losing committed transactions is unacceptable, accepting that every commit waits for the standby. Choose asynchronous replication when lower commit latency matters more and you can accept a small window of possible loss on failover. PostgreSQL does not detect a failed primary or notify the standby, so a failover tool must watch the primary, promote the standby and redirect connections.
- Database layout: The tenants database and all tenant schemas sit on the primary, and the standby holds a full copy.
- Synchronous standby: Commits wait for the standby, which protects committed data but adds latency to every write and can stall writes if the standby is unavailable.
- Asynchronous standby: Commits do not wait, which keeps latency low, but transactions not yet shipped can be lost on failover.
- External failover: Add a tool that detects primary failure, promotes the standby and updates the endpoint the write and batch instances use.
- Batch isolation: Long Close of Business runs load the same primary, so size connections and I/O for overlapping work.
Confirm the recovery point your institution can accept, then test the failover path with the write and batch instances connected.
For high load, the Fineract documentation recommends one write instance, one batch instance and multiple read instances on database read replicas. Read instances serve queries from hot standby servers, which takes read traffic off the primary, but replicas are only as current as their replication lag allows. Plan the replica set so that the read instances can tolerate that lag, and make sure the write and batch instances point only at the primary. Replica count, placement and replication mode are sizing decisions that depend on your transaction volume and read pattern.
- Layout: The primary serves the write and batch instances, and each read instance connects to a hot standby.
- Replication mode: Use asynchronous standbys for read replicas where lag is acceptable, and reserve synchronous standby for a failover candidate that must not lose committed data.
- Lag awareness: Confirm which screens and reports can show slightly stale data before routing them to a replica.
- External failover: Failover tooling must promote a standby, reconfigure the remaining replicas to follow the new primary and update the write endpoint.
- Connection budget: Each replica adds connections, so align pool sizes with the limits you set on every server.
Confirm with the Fineract documentation and your database team how read instances are routed and what happens to replicas after a promotion.
How to set up PostgreSQL for Fineract step by step
This sequence takes a PostgreSQL environment from version selection to a verified Fineract database layer, with a tenants database, tenant schemas, UTC time handling, pool settings, replicas for read instances and a migration run from the write instance only.
Choose a supported PostgreSQL major version
The platform team selects a PostgreSQL major version that is still inside its published support window at the planned go-live date. Per the PostgreSQL versioning policy, 18 is supported until November 14, 2030, 17 until November 8, 2029, 16 until November 9, 2028, 15 until November 11, 2027 and 14 until November 12, 2026, while 13 and earlier are unsupported. Fineract's documentation names PostgreSQL as the recommended database, so this choice should be recorded with its end-of-support date. Check: the chosen version appears in the current support table, and the team has a dated plan for the next major upgrade.
Provision the primary and standby servers
The infrastructure team builds one primary server for writes and one or more standbys for hot standby reads, in the network zone and cloud account the organization controls. PostgreSQL supports both synchronous and asynchronous replication, and the choice affects commit latency and data loss exposure, so the team should decide it with the risk owner. PostgreSQL does not detect primary failure or promote a standby by itself, so an external failover tool must be selected and tested as part of this step. Check: the primary accepts connections, each standby reports streaming replication status, and the failover mechanism has been named in writing.
Create the tenants database and tenant schemas
The database administrator creates the tenants database that Fineract reads to locate each tenant's connection details, then creates a schema for each tenant in the list. Fineract identifies tenants through the Fineract-Platform-TenantId header, so tenant identifiers, schema names and the tenants database entries must match exactly. Credentials for each tenant should be scoped to its own schema, and the team should confirm with the Fineract documentation how the tenants database is initialized in the chosen release. Check: querying the tenants database returns one row per planned tenant, and each tenant schema is listed on the primary with the expected owner and privileges.
Set database and server time zone to UTC
The database administrator sets the server time zone and each database's default time zone to UTC so that timestamps written by the application and by the database share one reference. The same setting should be confirmed on each replica and on the application hosts' view of time, since business date and batch timing depend on consistent timestamps. Changing time zone settings after data exists is risky, so this must be set before the first migration. Check: running a query for the current timestamp on the primary and each replica returns a UTC offset of zero, and the server parameter is persisted in configuration so it survives a restart.
Configure HikariCP pool variables for each instance
The application team sets the Fineract connection pool variables through environment variables for each instance, distinguishing read, write and batch instances. Pool sizes must be planned against PostgreSQL's connection limit across all instances and any pooler, so the total is calculated before values are set. Values should be stored with the rest of the deployment configuration rather than hard coded in images. Check: each running instance logs a pool started with the intended maximum size, and the sum of maximum pool sizes across instances stays below the connection limit configured on the database server.
Point read instances at replicas
The application team configures read instances to connect to a standby through its read replica address, while write and batch instances connect to the primary. Fineract's documentation recommends one write instance, one batch instance and multiple read instances on replicas for high load, so each instance type needs its own datasource configuration. Replication lag should be understood before users rely on read results, because a read immediately after a write may not yet show the change. Check: a test write through the write instance appears on the replica, and requests routed to read instances are served from the standby.
Run Liquibase migrations from the write instance only
The database administrator or release engineer runs Fineract's Liquibase database migrations from a single write instance, since the documentation states migrations run only on write instances. On Kubernetes, the migration can run as a separate job using the liquibase-only Spring profile, which keeps schema changes out of read and batch pods. Take a verified backup before the run and record the release version being applied. Check: the Liquibase changelog table on each tenant schema shows all changesets applied without failed entries, and read and batch instances start without attempting migrations.
Verify connectivity, schema state and replication lag
The operations team closes the setup with a checklist that covers connectivity, schema state and replication health. Each Fineract instance should answer a health request, each tenant should return data through the API with its tenant header, and replication lag should be measured on each standby under normal load and recorded as the baseline for alerts. The team should confirm the replication lag threshold with the business owners, since acceptable lag depends on how read results are used. Check: a documented run shows successful health responses per instance, successful tenant-scoped API calls, a lag measurement for every standby, and an alert configured for lag above the agreed threshold.
Which security controls the database layer needs
The PostgreSQL database holds the tenants database and every tenant schema, so its access controls matter as much as the Fineract application's. The cards below cover the controls to decide on before go-live, and each names the PostgreSQL documentation topic to read first.
Choose SCRAM over MD5 passwords
PostgreSQL 18 deprecated MD5 password authentication in favor of SCRAM. Set password_encryption to scram-sha-256 and confirm that the Fineract database role's stored password uses SCRAM before any environment file or secret carries it. Check every Fineract instance type, including read and batch, uses the same method. Ask your DBA to review pg_hba.conf for any remaining md5 entries.
Pick an authentication method per role
The PostgreSQL authentication docs list password, GSSAPI, SSPI, LDAP, RADIUS, certificate, PAM and OAuth options. For Fineract, certificate or directory-backed authentication may suit the write, read and batch roles better than shared passwords, but confirm that the JDBC driver version in your Fineract image supports the method you pick. Document the decision per role in pg_hba.conf.
Limit network exposure to Fineract instances
Only the write, batch and read Fineract instances, and any PgBouncer tier, should reach the PostgreSQL port. Restrict this with listen_addresses, host-based rules in pg_hba.conf and network security groups or firewall rules outside the database host. Confirm that no administrative client or developer workstation has a route to the primary.
Encrypt client connections with TLS
Enable ssl on the server and require TLS in the JDBC connection string for every Fineract instance. Decide whether clients should verify the server certificate against a private CA, and plan certificate renewal before expiry. Ask your team to confirm that unencrypted connections are rejected in pg_hba.conf with a hostssl rule rather than left as a fallback.
Separate credentials for tenant schemas
Each tenant uses its own schema, so give each tenant's database access a separate role with rights limited to that schema. The shared tenants database should hold only the connection metadata that Fineract needs. Review which role owns the Liquibase migrations, since it can alter schemas, and keep it separate from the runtime role that serves API traffic.
Back up and recover to a point in time
Plain dumps capture a moment, but continuous archiving with a base backup and WAL files allows point-in-time recovery to a chosen second before an error. Back up the tenants database and every tenant schema together, and test restores on a schedule. Confirm the archive location and retention with your operations team and the recovery objectives set by the business.
How to size storage for Fineract transaction history
Storage for a Fineract database grows with every client, account, posting and batch run, so the sizing estimate has to start from your own volumes rather than a generic rule. The inputs to measure are the number of active and total client and loan or savings accounts, the average number of journal entries and transactions posted per account per day, the retention period you must keep online, the growth of indexes that sit alongside the tables, and the number of tenants whose schemas share the same PostgreSQL cluster. Each of these moves storage differently. Account counts drive the size of the base tables, daily postings drive the rate of growth, retention drives the total footprint, and indexes often add a large share on top of the raw data.
Batch processing adds a second planning dimension. The Close of Business job can run for several hours on deployments with millions of accounts, and the README notes that it supports remote partitioning across worker nodes. During that window the database sees heavy reads and writes at once, so the team should measure I/O throughput and temporary space use during a COB run, not only average daily load. Ask your Fineract implementation partner or the project documentation which tables a COB run writes to, and confirm how the platform's own data retention and archival options interact with your backup strategy in the Fineract platform documentation.
No sizing figures are provided on this page, so build the estimate yourself. Load a copy of production data into a test environment with the same PostgreSQL major version, the same tenant layout and the same storage class, then run a full COB cycle and a representative set of postings. Record table and index sizes before and after, measure WAL volume and backup size, and project forward using your retention period. Repeat the test with a larger synthetic account count to see how growth scales. Record the results in your capacity plan and review them after each major Fineract or PostgreSQL upgrade, because both can change table layout and index usage.
What to confirm in your environment before go-live
The PostgreSQL layer sits under every Fineract transaction, so its choices need checking against the Fineract release you run and the recovery targets your institution has agreed. The cards below cover the items that most often differ between a design on paper and the environment that goes live.
PostgreSQL version against Fineract
Confirm that the PostgreSQL major version you plan to run is listed as supported by the Fineract release notes for the version you deploy, and that it sits inside its published support window for your go-live and planned operating period. Check the end-of-support dates in the PostgreSQL versioning policy before you commit, because a database major upgrade later is a separate project with its own testing. Ask your Fineract vendor or the release documentation which database versions were tested with that release.
Replication and failover against recovery objectives
Hot standby replication and failover are not the same thing. PostgreSQL does not detect a failed primary or promote a standby by itself, so the tooling you choose must do that work. Write down the recovery time and data loss your institution has agreed, then test whether your chosen synchronous or asynchronous setup and failover tool can meet them, including the step that stops Fineract from writing to the old primary.
Pooler and HikariCP interaction
If PgBouncer or another pooler sits between Fineract and PostgreSQL, the pool sizes in Fineract and the pooling mode in the pooler both limit connections, and they can conflict. Confirm which pooling mode the pooler runs, whether Fineract's connection settings assume session behavior, and how the combined limits behave during Close of Business, when batch work and API traffic run together. Test this under load rather than assuming the defaults will hold.
Replication lag tolerance for read instances
Read instances in Fineract serve queries from database read replicas, so they can show data that is behind the primary. Decide how much lag each read use case can tolerate, for example for customer balance screens versus reporting, and confirm that the lag you measure in testing stays inside that limit during peak posting periods. Also confirm which endpoints in your deployment are routed to read instances, since that routing determines which users see stale values.
Managed service differences
If you run PostgreSQL through a cloud managed service, confirm which parts of the setup you still control. Check how the service handles tenant database creation, extension and role permissions, time zone settings, parameter groups, failover behavior, read replica endpoints and backup retention. Each of these can differ from a self-managed cluster, and the differences affect the Fineract configuration you write.
Release-specific database settings
Check that the Fineract release you run supports each database setting you chose, including the tenant database layout, the instance type variables and the time zone handling. Settings that work in one release can change in another, and the release notes and documentation for your exact version are the reference. Record the version you tested so that a later Fineract upgrade starts from a known configuration.
What buyers ask before setting up PostgreSQL for Fineract
What does a PostgreSQL setup for Fineract cost and what drives the price?
The price follows from the written scope, and DeployOpen does not publish a price list. The main cost drivers are the number of Fineract tenants and tenant schemas, whether you run a single primary or a primary with read replicas, how much automation and monitoring you want, the target environments (cloud, data center or air-gapped), and how much backup and restore testing is included. Ask for the quote to split one-time work (design, build, migration and testing) from recurring work (patching, upgrades, monitoring and retainer support), and to state who provisions the infrastructure and who pays for it. Ask whether your database storage and backup costs are excluded from the quote.
How long does a PostgreSQL setup for Fineract usually take?
Duration depends on the number of tenants, the availability design, the environment and how quickly your team approves access and change windows. A single-tenant build with one primary is typically shorter than a multi-tenant build with replicas, automatic failover and tested recovery. Fixed-scope engagements agree timelines in writing before work starts, so ask for the schedule to show design, build, load testing, restore testing and cutover as separate phases. DeployOpen can give a timeline only after the scope is agreed, and no duration is fixed by the project itself.
What does our internal team need to provide for the database work?
Plan for four inputs. First, database administration skills, or a named owner who will operate PostgreSQL after handover. Second, network access between the Fineract instances, the tenants database, read replicas and any connection pooler, with firewall rules approved in advance. Third, backup targets such as object storage or a backup server with retention rules set by your policy. Fourth, change windows for the cutover, major version work and failover tests. Confirm these with your security and operations teams before the scope is signed, since approvals often set the schedule.
Can our own team set up PostgreSQL for Fineract without a partner?
Yes, if your team has PostgreSQL operations experience and the time to build and test the setup. The Fineract project states that a production deployment can be complex, costly and time-consuming and that it does not provide a comprehensive production deployment guide, so most teams need to design the tenants database, pooling, replication and recovery themselves. Compare your team's skills in high availability, point-in-time recovery and upgrades against the scope. A partner is useful when you need the design written down, tested recovery, and a handover your team can run.
How do PostgreSQL versions and upgrades affect the plan?
Choose a supported major version at the start and plan the upgrade path before go-live. PostgreSQL 18 was first released on September 25, 2025, and the community supports version 14 until November 12, 2026, while 13 and earlier are unsupported. Minor releases are applied by replacing executables and restarting, because they do not change the storage format. Major upgrades can use dump and restore, pg_upgrade or logical replication, and logical replication can keep downtime to several seconds. Confirm which Fineract release you run supports the chosen PostgreSQL major version before you commit.
Does DeployOpen issue compliance attestations for our database?
No. DeployOpen prepares systems, controls and evidence for compliance assessments, such as configuration records, backup and restore test results, access settings and change logs. It does not issue audit reports, attestations or certifications. Independent auditors and certification bodies perform those assessments. Ask us for the evidence list that will be produced for your assessor, and confirm with your auditor which records they will accept before the build starts.
Does PostgreSQL fail over automatically when the primary goes down?
Not by itself. PostgreSQL supports hot standby servers and both synchronous and asynchronous replication, but it does not provide software that detects a primary failure and promotes a standby. Automatic failover needs external tooling and a tested runbook, which adds a design decision about consistency and fencing. Ask the team to show the failover test results and the expected data loss under asynchronous replication, and confirm how Fineract connections will be redirected after promotion.
How DeployOpen scopes and delivers Fineract database setup
DeployOpen plans, builds, documents and supports the PostgreSQL layer under Apache Fineract inside infrastructure you control. Engagements are fixed-scope, with the tenants database, tenant schemas, pooling, time zone, replicas and storage agreed in writing before any build starts.
How we scope
- Inventory every Fineract tenant and confirm the tenants database and tenant schema layout before sizing begins.
- Confirm which instances will be write, batch and read, and which of them connect to PostgreSQL read replicas.
- Agree in writing the PostgreSQL major version, hosting model and the owner for each database role and credential.
How we build
- Configure the tenants database, tenant schemas and connection settings for each instance type, with UTC set as the database time zone.
- Set HikariCP pool variables against planned connection limits on PostgreSQL and any read replicas, then load test them.
- Size storage for transaction history growth and test replication behavior, including failover tooling your team selects.
How we hand over
- Deliver a configuration record covering tenant databases, pool settings, replica routing and storage assumptions.
- Document the runbook for connection changes, replica lag checks, major and minor PostgreSQL upgrades and restore tests.
- Walk your platform, database and security staff through the build and confirm they can run it without DeployOpen.
How we support
- Offer ongoing support, upgrades and testing as a retainer after handover, scoped separately from the build.
- Review pool sizing and storage growth when tenant count, account volume or Fineract release changes.
- Plan PostgreSQL minor and major upgrades against the supported version calendar and Fineract release notes together.

