diff --git a/generated_types/protos/influxdata/iox/namespace/v1/service.proto b/generated_types/protos/influxdata/iox/namespace/v1/service.proto
index f629ac4995..ff1ed74427 100644
--- a/generated_types/protos/influxdata/iox/namespace/v1/service.proto
+++ b/generated_types/protos/influxdata/iox/namespace/v1/service.proto
@@ -111,4 +111,8 @@ message Namespace {
 
   // The maximum number of columns a table belonging to this namespace may have.
   int32 max_columns_per_table = 5;
+
+  // The default partitioning scheme used for any new tables that are created
+  // in this namespace, if any.
+  optional influxdata.iox.partition_template.v1.PartitionTemplate partition_template = 6;
 }
diff --git a/ioxd_querier/src/rpc/namespace.rs b/ioxd_querier/src/rpc/namespace.rs
index 03f6e24399..c63ca9a309 100644
--- a/ioxd_querier/src/rpc/namespace.rs
+++ b/ioxd_querier/src/rpc/namespace.rs
@@ -38,6 +38,7 @@ fn namespace_to_proto(namespace: Namespace) -> proto::Namespace {
         retention_period_ns: namespace.retention_period_ns,
         max_tables: namespace.max_tables,
         max_columns_per_table: namespace.max_columns_per_table,
+        partition_template: namespace.partition_template.as_proto().cloned(),
     }
 }
 
@@ -186,6 +187,7 @@ mod tests {
                         retention_period_ns: TEST_RETENTION_PERIOD_NS,
                         max_tables: TEST_MAX_TABLES,
                         max_columns_per_table: TEST_MAX_COLUMNS_PER_TABLE,
+                        partition_template: None,
                     },
                     proto::Namespace {
                         id: 2,
@@ -193,6 +195,7 @@ mod tests {
                         retention_period_ns: TEST_RETENTION_PERIOD_NS,
                         max_tables: TEST_MAX_TABLES,
                         max_columns_per_table: TEST_MAX_COLUMNS_PER_TABLE,
+                        partition_template: None,
                     },
                 ]
             }
diff --git a/service_grpc_namespace/src/lib.rs b/service_grpc_namespace/src/lib.rs
index 5a57987a42..90646eeb20 100644
--- a/service_grpc_namespace/src/lib.rs
+++ b/service_grpc_namespace/src/lib.rs
@@ -265,6 +265,7 @@ fn namespace_to_proto(namespace: CatalogNamespace) -> Namespace {
         retention_period_ns: namespace.retention_period_ns,
         max_tables: namespace.max_tables,
         max_columns_per_table: namespace.max_columns_per_table,
+        partition_template: namespace.partition_template.as_proto().cloned(),
     }
 }
 
@@ -276,6 +277,7 @@ fn namespace_to_create_response_proto(namespace: CatalogNamespace) -> CreateName
             retention_period_ns: namespace.retention_period_ns,
             max_tables: namespace.max_tables,
             max_columns_per_table: namespace.max_columns_per_table,
+            partition_template: namespace.partition_template.as_proto().cloned(),
         }),
     }
 }
@@ -311,6 +313,7 @@ mod tests {
     use std::time::Duration;
 
     use assert_matches::assert_matches;
+    use data_types::partition_template::PARTITION_BY_DAY_PROTO;
     use generated_types::influxdata::iox::{
         namespace::v1::namespace_service_server::NamespaceService as _,
         partition_template::v1::PartitionTemplate,
@@ -396,6 +399,7 @@ mod tests {
             .expect("no namespace in response");
         assert_eq!(created_ns.name, NS_NAME);
         assert_eq!(created_ns.retention_period_ns, Some(RETENTION));
+        assert_eq!(created_ns.partition_template, None);
 
         // There should now be one namespace
         {
@@ -425,6 +429,7 @@ mod tests {
         assert_eq!(updated_ns.id, created_ns.id);
         assert_eq!(created_ns.retention_period_ns, Some(RETENTION));
         assert_eq!(updated_ns.retention_period_ns, None);
+        assert_eq!(created_ns.partition_template, updated_ns.partition_template);
 
         // Listing the namespaces should return the updated namespace
         {
@@ -547,6 +552,45 @@ mod tests {
         assert_eq!(all_namespaces.len(), 1);
     }
 
+    #[tokio::test]
+    async fn custom_namespace_template_returned_in_responses() {
+        let catalog: Arc<dyn Catalog> =
+            Arc::new(MemCatalog::new(Arc::new(metric::Registry::default())));
+        let handler = NamespaceService::new(Arc::clone(&catalog));
+
+        // Ensure the create reponse feeds back the partition template
+        let req = CreateNamespaceRequest {
+            name: NS_NAME.to_string(),
+            retention_period_ns: None,
+            partition_template: Some(PARTITION_BY_DAY_PROTO.as_ref().clone()),
+            service_protection_limits: None,
+        };
+        let created_ns = handler
+            .create_namespace(Request::new(req))
+            .await
+            .expect("failed to create namespace")
+            .into_inner()
+            .namespace
+            .expect("no namespace in response");
+        assert_eq!(created_ns.name, NS_NAME);
+        assert_eq!(created_ns.retention_period_ns, None);
+        assert_eq!(
+            created_ns.partition_template,
+            Some(PARTITION_BY_DAY_PROTO.as_ref().clone())
+        );
+
+        // And then make sure that a list call will include the details.
+        let listed_ns = handler
+            .get_namespaces(Request::new(Default::default()))
+            .await
+            .expect("must return namespaces")
+            .into_inner()
+            .namespaces;
+        assert_matches!(listed_ns.as_slice(), [listed_ns] => {
+            assert_eq!(listed_ns.partition_template, Some(PARTITION_BY_DAY_PROTO.as_ref().clone()));
+        })
+    }
+
     #[tokio::test]
     async fn invalid_custom_namespace_template_returns_error() {
         let catalog: Arc<dyn Catalog> =