<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>article Eliminate Cross-Cloud Data Sharing Costs with Cloudflare R2 and Delta Lake in Technical Blog</title>
    <link>https://community.databricks.com/t5/technical-blog/eliminate-cross-cloud-data-sharing-costs-with-cloudflare-r2-and/ba-p/137330</link>
    <description>&lt;H2&gt;&lt;SPAN class="im"&gt;The Challenge: Cross-Cloud Data Sharing is Expensive&lt;BR /&gt;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;Sharing data across cloud providers or even across regions in the same provider, egress fees can be quite high - in many cases orders of magnitude higher than the actual storage costs.&lt;/SPAN&gt;&lt;SPAN class="im"&gt;&lt;BR /&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN class="im"&gt;For organizations operating in multi-cloud environments or sharing data with external partners, these egress fees create a serious barrier to collaboration. Traditional data sharing approaches force you to choose between:&lt;BR /&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN class="im"&gt;&lt;STRONG&gt;High costs:&lt;/STRONG&gt; Pay premium egress fees for every data transfer&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class="im"&gt;&lt;STRONG&gt;Vendor lock-in:&lt;/STRONG&gt; Keep everyone on the same cloud provider&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class="im"&gt;&lt;STRONG&gt;Stale data:&lt;/STRONG&gt; Share snapshots infrequently to minimize costs&lt;BR /&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;&lt;SPAN class="im"&gt;The Solution: Cloudflare R2 as a Zero-Egress Bridge&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;Use Cloudflare R2, an S3-compatible object storage service with zero egress fees, as an intermediary for cross-cloud data replication.&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN class="im"&gt;The architecture is simple and elegant:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN class="im"&gt;the Provider maintains a managed Delta table in their Databricks workspace&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class="im"&gt;Data is replicated to an external Delta table stored on Cloudflare R2&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class="im"&gt;the Recipient(s) access the R2-hosted data from their own cloud/region and sync to local managed tables&lt;BR /&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;&lt;SPAN class="im"&gt;Provider Setup: Publishing Data to R2&lt;BR /&gt;&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN class="im"&gt;The provider workflow is straightforward. Here's how to set it up:&lt;BR /&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN class="im"&gt;&lt;STRONG&gt;1. Create Cloudflare R2 Storage Credential&lt;/STRONG&gt;&lt;BR /&gt;First, configure Databricks to access your R2 bucket using Cloudflare API tokens:&lt;/SPAN&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;SPAN class="im"&gt;-- Verify your credential&lt;BR /&gt;DESCRIBE STORAGE CREDENTIAL r2_credential;&lt;BR /&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;SPAN class="im"&gt;The credential setup is done through the Databricks UI (Catalog → External Data → Credentials), where you provide your Cloudflare Account ID, Access Key ID, and Secret Access Key.&lt;BR /&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN class="im"&gt;&lt;STRONG&gt;2. Define External Location&lt;/STRONG&gt;&lt;BR /&gt;Point to your R2 bucket using the S3-compatible URL format:&lt;/SPAN&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;SPAN class="im"&gt;CREATE EXTERNAL LOCATION IF NOT EXISTS r2_location&lt;BR /&gt;URL 'r2://{bucket-name}@{account-&lt;WBR /&gt;id}.&lt;A href="http://r2.cloudflarestorage.com/" target="_blank" rel="noopener" data-saferedirecturl="https://www.google.com/url?q=http://r2.cloudflarestorage.com&amp;amp;source=gmail&amp;amp;ust=1762216949133000&amp;amp;usg=AOvVaw2thjp2VkxA20sgVwai_SHD"&gt;r2.cloudflarestorage.com&lt;/A&gt;'&lt;BR /&gt;WITH (STORAGE CREDENTIAL r2_credential)&lt;BR /&gt;COMMENT 'Cloudflare R2 bucket for cross-cloud data replication';&lt;BR /&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;STRONG&gt;3. Create a Replica Table&lt;/STRONG&gt;&lt;BR /&gt;&lt;SPAN&gt;Create a replica table (external table on R2):&lt;/SPAN&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;SPAN&gt;CREATE TABLE {source-catalog-name}.{source-&lt;/SPAN&gt;&lt;WBR /&gt;&lt;SPAN&gt;schema-name}.{source-table-&lt;/SPAN&gt;&lt;WBR /&gt;&lt;SPAN&gt;name}_r2_replica (&lt;/SPAN&gt;&lt;SPAN class="im"&gt;&lt;BR /&gt;&amp;nbsp; -- Same schema as source&lt;BR /&gt;&amp;nbsp; ...&lt;BR /&gt;)&lt;BR /&gt;&lt;/SPAN&gt;&lt;SPAN&gt;LOCATION 'r2://{bucket}@{account}.&lt;/SPAN&gt;&lt;A href="http://r2.cloudflarestorage.com/%7Bsource-table-name%7D_r2_replica" target="_blank" rel="noopener" data-saferedirecturl="https://www.google.com/url?q=http://r2.cloudflarestorage.com/%257Bsource-table-name%257D_r2_replica&amp;amp;source=gmail&amp;amp;ust=1762216949133000&amp;amp;usg=AOvVaw37jeyJv9uxbfYCa5Cd5zaw"&gt;r2.&lt;WBR /&gt;cloudflarestorage.com/{source-&lt;WBR /&gt;table-name}_r2_replica&lt;/A&gt;&lt;SPAN&gt;'&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;PARTITIONED BY (...) -- if the source data is partitioned&lt;/SPAN&gt;&lt;SPAN class="im"&gt;&lt;BR /&gt;TBLPROPERTIES ('delta.autoOptimize.&lt;WBR /&gt;optimizeWrite' = 'true');&lt;BR /&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;SPAN class="im"&gt;&lt;STRONG&gt;4. Replicate Changes with &lt;FONT face="courier new,courier"&gt;MERGE&lt;/FONT&gt;&lt;/STRONG&gt;&lt;BR /&gt;Use a simple insert-only &lt;STRONG&gt;&lt;FONT face="courier new,courier"&gt;MERGE&lt;/FONT&gt;&lt;/STRONG&gt; operation to synchronize new data:&lt;BR /&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;SPAN&gt;MERGE INTO {source-catalog-name}.{source-&lt;/SPAN&gt;&lt;WBR /&gt;&lt;SPAN&gt;schema-name}.{source-table-&lt;/SPAN&gt;&lt;WBR /&gt;&lt;SPAN&gt;name}_r2_replica AS target&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;USING {source-catalog-name}.{source-&lt;/SPAN&gt;&lt;WBR /&gt;&lt;SPAN&gt;schema-name}.{source-table-&lt;/SPAN&gt;&lt;WBR /&gt;&lt;SPAN&gt;name} AS source&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;ON target.{primary-identifier} = source.{primary-identifier}&lt;/SPAN&gt;&lt;SPAN class="im"&gt;&lt;BR /&gt;WHEN NOT MATCHED THEN INSERT *;&lt;BR /&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;SPAN class="im"&gt;For production scenarios requiring updates and deletes, consider enabling Change Data Feed (CDF) on the source table for comprehensive change tracking.&lt;BR /&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3&gt;&lt;SPAN class="im"&gt;Recipient Setup: Consuming Data from R2&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN class="im"&gt;Recipients can access the replicated data from any cloud provider or region:&lt;BR /&gt;&lt;BR /&gt;&lt;STRONG&gt;1. Configure R2 Access&lt;/STRONG&gt;&lt;BR /&gt;Recipients use the same credential and external location setup as the provider (requires read access to the R2 bucket). For best practice create a least privilege, &lt;STRONG&gt;read-only&lt;/STRONG&gt; Cloudflare scoped API token for the recipient side.&lt;BR /&gt;&lt;BR /&gt;&lt;STRONG&gt;2. Create a View&lt;/STRONG&gt;&lt;BR /&gt;Important: Recipients should create a view pointing to the R2 location, not an external table, to avoid metadata corruption:&lt;BR /&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;SPAN&gt;CREATE OR REPLACE VIEW {target-catalog-name}.{target-&lt;/SPAN&gt;&lt;WBR /&gt;&lt;SPAN&gt;schema-name}.vw_{source-table-&lt;/SPAN&gt;&lt;WBR /&gt;&lt;SPAN&gt;name}_r2_replica AS&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;SELECT * FROM delta.`r2://{bucket}@{account}&lt;/SPAN&gt;&lt;WBR /&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;A href="http://r2.cloudflarestorage.com/%7Bsource-table-name%7D_r2_replica" target="_blank" rel="noopener" data-saferedirecturl="https://www.google.com/url?q=http://r2.cloudflarestorage.com/%257Bsource-table-name%257D_r2_replica&amp;amp;source=gmail&amp;amp;ust=1762216949133000&amp;amp;usg=AOvVaw37jeyJv9uxbfYCa5Cd5zaw"&gt;r2.cloudflarestorage.com/{&lt;WBR /&gt;source-table-name}_r2_replica`&lt;/A&gt;&lt;WBR /&gt;&lt;SPAN&gt;;&lt;/SPAN&gt;&lt;SPAN class="im"&gt;&lt;BR /&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;SPAN class="im"&gt;&lt;STRONG&gt;3. Create Local Managed Table&lt;/STRONG&gt;&lt;BR /&gt;Set up a local table for synchronized data:&lt;BR /&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;SPAN&gt;CREATE TABLE {target-catalog-name}.{target-&lt;/SPAN&gt;&lt;WBR /&gt;&lt;SPAN&gt;schema-name}.{source-table-&lt;/SPAN&gt;&lt;WBR /&gt;&lt;SPAN&gt;name} (&lt;/SPAN&gt;&lt;SPAN class="im"&gt;&lt;BR /&gt;&amp;nbsp; -- Same schema&lt;BR /&gt;&amp;nbsp; ...&lt;BR /&gt;)&lt;BR /&gt;&lt;/SPAN&gt;&lt;SPAN&gt;PARTITIONED BY (...) -- if partitioned&lt;/SPAN&gt;&lt;SPAN class="im"&gt;&lt;BR /&gt;TBLPROPERTIES ('delta.autoOptimize.&lt;WBR /&gt;optimizeWrite' = 'true');&lt;BR /&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;SPAN class="im"&gt;&lt;STRONG&gt;4. Synchronize with MERGE&lt;/STRONG&gt;&lt;BR /&gt;Pull new data from R2 into the local managed table:&lt;BR /&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;SPAN&gt;MERGE INTO {target-catalog-name}.{target-&lt;/SPAN&gt;&lt;WBR /&gt;&lt;SPAN&gt;schema-name}.{source-table-&lt;/SPAN&gt;&lt;WBR /&gt;&lt;SPAN&gt;name} AS target&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;USING {target-catalog-name}.{target-&lt;/SPAN&gt;&lt;WBR /&gt;&lt;SPAN&gt;schema-name}.vw_{source-table-&lt;/SPAN&gt;&lt;WBR /&gt;&lt;SPAN&gt;name}_r2_replica AS source&lt;/SPAN&gt;&lt;BR /&gt;&lt;SPAN&gt;ON target.{primary-identifier} = source.{primary-identifier}&lt;/SPAN&gt;&lt;SPAN class="im"&gt;&lt;BR /&gt;WHEN NOT MATCHED THEN INSERT *;&lt;BR /&gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;SPAN class="im"&gt;This example is doing a simple insert only &lt;STRONG&gt;&lt;FONT face="courier new,courier"&gt;MERGE&lt;/FONT&gt;&lt;/STRONG&gt;, for stateful sources you could implement type1 or type2 SCDs along with Change Data Feed on the source table as required.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Schedule this as a Lakeflow Job for continuous synchronization (hourly, daily, etc.).&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Benefits&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;This cross cloud/cross region replication pattern can be used for contingency, business continuity or distaster recovery as well as data sharing.&amp;nbsp; Key benefits of this cross solution include:&lt;BR /&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN&gt;Zero Egress Costs - Cloudflare R2 charges $0 for data egress&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN&gt;Global Distribution - Leverages Cloudflare's global CDN for fast data access worldwide&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN&gt;Hyper-scalar Independence - Maintain a durable replica which is independent of the cloud provider on the provider or recipient end&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN&gt;Unlimited Scalability - Add as many recipients as needed without worrying about increasing costs&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN&gt;Maintain Control - Providers keep full control over the source data&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;</description>
    <pubDate>Wed, 05 Nov 2025 11:21:14 GMT</pubDate>
    <dc:creator>jeffreyaven</dc:creator>
    <dc:date>2025-11-05T11:21:14Z</dc:date>
    <item>
      <title>Eliminate Cross-Cloud Data Sharing Costs with Cloudflare R2 and Delta Lake</title>
      <link>https://community.databricks.com/t5/technical-blog/eliminate-cross-cloud-data-sharing-costs-with-cloudflare-r2-and/ba-p/137330</link>
      <description>&lt;P&gt;Discover how to eliminate egress costs when sharing data between cloud providers or regions using Cloudflare R2 as an intermediary between different Databricks workspaces.&lt;/P&gt;</description>
      <pubDate>Wed, 05 Nov 2025 11:21:14 GMT</pubDate>
      <guid>https://community.databricks.com/t5/technical-blog/eliminate-cross-cloud-data-sharing-costs-with-cloudflare-r2-and/ba-p/137330</guid>
      <dc:creator>jeffreyaven</dc:creator>
      <dc:date>2025-11-05T11:21:14Z</dc:date>
    </item>
  </channel>
</rss>

