General Questions
Q: When should SPQR be used, and when is it not a good fit? A: Use SPQR when:- Your data no longer fits on a single PostgreSQL instance (> several TB).
- You experience performance degradation in reads/writes, and vertical scaling has reached its limits.
- You need to “cool down” part of your data without losing availability.
- Your database is already sharded and you need automated re-sharding.
- Recommended to start sharding when you have >40 CPU cores, >4 hosts, or >600 GB of data.
- You have complex queries involving multiple shards (e.g., cross-shard JOINs).
- Transactions modify data across multiple shards.
- You need OLAP workloads — use Greenplum instead.
- License: SPQR uses the open PostgreSQL license.
- Simplicity: SPQR is built to solve a single, focused problem — routing application queries to shards.
- Performance: SPQR is optimized for minimal overhead.
- Deploy at least 3 routers in different availability zones.
- Set up alerts for metrics (CPU, connections, errors).
- Use HA-managed services for shards (Odyssey/PgBouncer as connection poolers, PgConsul/Patroni for HA management).
default_target_session_attrs = read-only, read queries are distributed among replicas.
If a replica becomes unresponsive (SELECT pg_is_in_recovery(); timeout), SPQR stops sending queries to it and periodically checks its status in the background. Once it’s healthy again, traffic resumes automatically.
Q: Are there risks of duplicated queries when using a load balancer in front of SPQR?
A: Yes. If a client disconnects and the load balancer retries the query, SPQR treats it as a new one — potentially causing duplication (e.g., INSERT).
Use idempotent operations or implement deduplication at the application layer.
Q: How to set up backups?
A: Full PITR (Point-In-Time Recovery) for the SPQR cluster consists of shard PITRs plus a backup of SPQR metadata stored in etcd.
We recommend using WAL-G for this purpose.
Q: How to diagnose issues and collect statistics?
A: Enable debug logging in the router config and use /* __spqr__reply_notice = true */ for detailed error messages.
The router provides a PostgreSQL-compatible admin console with SHOW commands for metrics (e.g., SHOW clients WHERE dbname = testdb; or SHOW shards;).
Q: How to configure logging and tracing?
A: Use the following router parameters:
log_level— debug, info, warning, error, fatalpretty_logging— enables structured outputpgproto_debug— detailed PostgreSQL protocol loggingnotice_message_format— configures NOTICE message formatting Tracing is available through thewith_jaegerflag infeature_flags, and latency metrics are available viatime_quantiles.
Transactions
Q: How does SPQR process SQL queries? A: SPQR handles queries differently depending on their type and context:- Regular queries: SPQR parses the query, identifies the target table, column, and key value, then matches it to pre-defined sharding rules (range or hash). It routes the query to the corresponding shard.
- Queries with routing hints: Query routing can be influenced by special hints (provided as SQL comments or router settings).
- Transactions: When
BEGIN TRANSACTIONis received, SPQR buffers subsequent statements (likeSETcommands) in memory. The entire transaction is sent to a specific shard only when the target shard can be determined unambiguously.
- At session start:
SET __spqr__commit_strategy TO '2pc'. - Or add
/* __spqr__commit_strategy: 2pc */to yourCOMMIT. - Ensure
max_prepared_transactions> 0 on all shards. Note: Without 2PC, changes may be partially applied.
- For cross-shard operations, use
/*__spqr__engine_v2: true*/. COPYoperations are allowed with/*__spqr__allow_multishard: true*/.- Transactions modifying multiple shards are not supported.
SET statements:
__spqr__execute_on— target specific shard__spqr__distribution— choose routing distribution__spqr__scatter_query— broadcast query to all shards
__spqr__commit_strategy hint defines the transaction commit mode:
1pc— one-phase commit (best effort)2pc— two-phase commit (requires/* __spqr__engine_v2: true */and PostgreSQLmax_prepared_transactionsset).
/* __spqr__engine_v2: true */ for writes.
Q: Can related tables be sharded by the same key?
A: Yes — SPQR allows colocating related data on the same shard, enabling efficient intra-shard JOINs.
Q: Does SPQR support distributed sequences?
A: Yes — via CREATE REFERENCE TABLE ... AUTO INCREMENT. SPQR guarantees globally unique IDs.
Q: How are queries without a sharding key handled?
A: By default, multi-shard queries (without a key) are forbidden.
You can enable them with /* __spqr__scatter_query: true */.
Results from all shards are merged, but consistency is not guaranteed.
Connections and Authentication
Q: How to connect to SPQR? A: SPQR uses the standard PostgreSQL protocol — applications see it as a regular PostgreSQL cluster. You can connect viapsql or any PostgreSQL driver using the router’s host and port.
The admin console runs on a separate port (defined by admin_console_port), e.g.:
pool_mode in frontend rules:
SESSION— a client session is bound to one backend connectionTRANSACTION— connection is released to the pool after each transaction
Performance
Q: How does SPQR performance compare to vanilla PostgreSQL? A:- SPQR shows ~10–30% performance drop depending on workload type compared to vanilla PostgreSQL.
- Optimization work is ongoing.
- 3 routers × 4 vCPU, 16 GB RAM
- 3 coordinators × 1 vCPU, 4 GB RAM
- Total: 15 vCPU, 60 GB RAM
- 3 routers × 4 vCPU, 16 GB RAM
- 3 coordinators × 2 vCPU, 8 GB RAM
- Total: 18 vCPU, 72 GB RAM
- 5 routers × 4 vCPU, 16 GB RAM
- 3 coordinators × 2 vCPU, 8 GB RAM
- Total: 26 vCPU, 104 GB RAM
Data Migration and Rebalancing
Q: How to shard an existing database? A: Steps:- Connect your current cluster as the first shard.
- Define sharding keys for your tables.
- Create key ranges covering the entire key space.
- Add new shards to the config and move data using
REDISTRIBUTE KEY RANGE.
- Use standard PostgreSQL drivers (e.g.,
pgx). - Specify all routers in your configuration for load balancing.
-
Add a new shard in
router.yaml/coordinator.yamlor viaADD SHARD. -
Reassign key ranges using:
SPLIT KEY RANGE— split rangeMOVE KEY RANGE— move range (locks data)REDISTRIBUTE KEY RANGE— automatic migration
-
Use
SYNC REFERENCE TABLESto copy reference tables.
- Integer (
int,bigint) - String (
varchar) - UUID
- Hash functions:
CITY,MURMUR(for integers only) — custom hash functions are not supported - Composite keys
error processing query ... : syntax error, what should I do?
A: This usually indicates an internal SPQR parser issue rather than an actual SQL syntax error.
1. Report it to SPQR developers:
- Include the full query text
- SPQR and PostgreSQL versions
- Sharding configuration
- Check your query against SPQR documentation
- Simplify the query (split it, remove complex constructs)
- Rare PostgreSQL operators
- Nonstandard syntax
- Custom functions