Smarter Data Placement with Tablespaces and Wildcards

YugabyteDB has long supported PostgreSQL-compatible tablespaces to help control where data lives in a distributed cluster. This is especially useful when you want to place specific tables or indexes in particular regions or availability zones, for performance, cost, or regulatory reasons.

But with a recent enhancement (#26671) starting in YugabyteDB 2024.2.4.0, things just got a lot more flexible!

What’s New: Use * Wildcards in Tablespace Placement

Previously, you had to explicitly list every zone in the placement block of a tablespace. Now, you can use the * wildcard to match all zones within a region, or even all regions.

Example:

Let’s say you want a table to live in any zone in the us-west1 region. You can now define your tablespace like this:

				
					CREATE TABLESPACE ts_uswest
  WITH (replica_placement = 
    '{"num_replicas": 3,
      "placement_blocks": [
        {"cloud": "gcp", "region": "us-west1", "zone": "*", "min_num_replicas": 3}
      ]
    }');
				
			

Or go even broader with:

				
					{"cloud": "gcp", "region": "*", "zone": "*"}
				
			

This means fewer lines of configuration, easier scaling, and more flexibility when adding or removing zones!

Why This Matters
  • ✅ Great for multi-AZ deployments where zones may vary

  • ✅ Useful when regions have dynamic topology

  • ✅ Simplifies replica placement policies during expansion or failover planning

Bonus Tip: Combine this with yb_tserver gflags like placement_cloud, placement_region, and placement_zone for full control over where tablets land in your cluster!

Example:

				
					yugabyte=# SELECT split_part(version(), '-', 3) "YB Version";
 YB Version
------------
 2024.2.4.0
(1 row)

yugabyte=# SELECT host, cloud, region, zone FROM yb_servers() ORDER BY region, zone;
   host    | cloud | region  | zone
-----------+-------+---------+-------
 127.0.0.1 | gcp   | region1 | zone1
 127.0.0.4 | gcp   | region1 | zone2
 127.0.0.7 | gcp   | region1 | zone3
 127.0.0.2 | gcp   | region2 | zone1
 127.0.0.5 | gcp   | region2 | zone2
 127.0.0.8 | gcp   | region2 | zone3
 127.0.0.3 | gcp   | region3 | zone1
 127.0.0.6 | gcp   | region3 | zone2
 127.0.0.9 | gcp   | region3 | zone3
(9 rows)

yugabyte=# CREATE TABLESPACE region1_zoneless
yugabyte-#   WITH (replica_placement='{"num_replicas": 3, "placement_blocks": [
yugabyte'#     {"cloud":"gcp","region":"region1","zone":"*","min_num_replicas":3}
yugabyte'#   ]}');
CREATE TABLESPACE

yugabyte=# CREATE TABLESPACE region2_zoneless
yugabyte-#   WITH (replica_placement='{"num_replicas": 1, "placement_blocks": [
yugabyte'#     {"cloud":"gcp","region":"region2","zone":"*","min_num_replicas":1}
yugabyte'#   ]}');
CREATE TABLESPACE

yugabyte-#   WITH (replica_placement='{"num_replicas": 3, "placement_blocks": [
yugabyte'#     {"cloud":"gcp","region":"*","zone":"zone1","min_num_replicas":3}
yugabyte'#   ]}');
ERROR:  A wildcard '*' at region level should be followed by a wildcard at zone level

yugabyte=# CREATE TABLESPACE gcp_regionless_zoneless
yugabyte-#   WITH (replica_placement='{"num_replicas": 3, "placement_blocks": [
yugabyte'#     {"cloud":"gcp","region":"*","zone":"*","min_num_replicas":3}
yugabyte'#   ]}');
CREATE TABLESPACE

				
			

Have Fun!

Spotted outside the 2025 AWS Summit NYC: Shopify lighting up the city with innovation