
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
    <channel>
        <title><![CDATA[ The Cloudflare Blog ]]></title>
        <description><![CDATA[ Get the latest news on how products at Cloudflare are built, technologies used, and join the teams helping to build a better Internet. ]]></description>
        <link>https://blog.cloudflare.com</link>
        <atom:link href="https://blog.cloudflare.com/" rel="self" type="application/rss+xml"/>
        <language>en-us</language>
        <image>
            <url>https://blog.cloudflare.com/favicon.png</url>
            <title>The Cloudflare Blog</title>
            <link>https://blog.cloudflare.com</link>
        </image>
        <lastBuildDate>Sat, 04 Apr 2026 08:12:29 GMT</lastBuildDate>
        <item>
            <title><![CDATA[R2 Data Catalog: Managed Apache Iceberg tables with zero egress fees]]></title>
            <link>https://blog.cloudflare.com/r2-data-catalog-public-beta/</link>
            <pubDate>Thu, 10 Apr 2025 14:00:00 GMT</pubDate>
            <description><![CDATA[ R2 Data Catalog is now in public beta: a managed Apache Iceberg data catalog built directly into your R2 bucket. ]]></description>
            <content:encoded><![CDATA[ <p><a href="https://iceberg.apache.org/"><u>Apache Iceberg</u></a> is quickly becoming the standard table format for querying large analytic datasets in <a href="https://www.cloudflare.com/learning/cloud/what-is-object-storage/">object storage</a>. We’re seeing this trend firsthand as more and more developers and data teams adopt Iceberg on <a href="https://www.cloudflare.com/developer-platform/products/r2/"><u>Cloudflare R2</u></a>. But until now, using Iceberg with R2 meant managing additional infrastructure or relying on external data catalogs.</p><p>So we’re fixing this. Today, we’re launching the <a href="https://developers.cloudflare.com/r2/data-catalog/"><u>R2 Data Catalog</u></a> in open beta, a managed Apache Iceberg catalog built directly into your Cloudflare R2 bucket.</p><p>If you’re not already familiar with it, Iceberg is an open table format built for large-scale analytics on datasets stored in object storage. With R2 Data Catalog, you get the database-like capabilities Iceberg is known for – <a href="https://en.wikipedia.org/wiki/ACID"><u>ACID</u></a> transactions, schema evolution, and efficient querying – without the overhead of managing your own external catalog.</p><p>R2 Data Catalog exposes a standard Iceberg REST catalog interface, so you can connect the engines you already use, like <a href="https://py.iceberg.apache.org/"><u>PyIceberg</u></a>, <a href="https://www.snowflake.com/"><u>Snowflake</u></a>, and <a href="https://spark.apache.org/"><u>Spark</u></a>. And, as always with R2, there are no egress fees, meaning that no matter which cloud or region your data is consumed from, you won’t have to worry about growing data transfer costs.</p><p>Ready to query data in R2 right now? Jump into the <a href="https://developers.cloudflare.com/r2/data-catalog/"><u>developer docs</u></a> and enable a data catalog on your R2 bucket in just a few clicks. Or keep reading to learn more about Iceberg, data catalogs, how metadata files work under the hood, and how to create your first Iceberg table.</p>
    <div>
      <h2>What is Apache Iceberg?</h2>
      <a href="#what-is-apache-iceberg">
        
      </a>
    </div>
    <p><a href="https://iceberg.apache.org/"><u>Apache Iceberg</u></a> is an open table format for analyzing large datasets in object storage. It brings database-like features – ACID transactions, time travel, and schema evolution – to files stored in formats like <a href="https://parquet.apache.org/"><u>Parquet</u></a> or <a href="https://orc.apache.org/"><u>ORC</u></a>.</p><p>Historically, data lakes were just collections of raw files in object storage. However, without a unified metadata layer, datasets could easily become corrupted, were difficult to evolve, and queries often required expensive full-table scans.</p><p>Iceberg solves these problems by:</p><ul><li><p>Providing ACID transactions for reliable, concurrent reads and writes.</p></li><li><p>Maintaining optimized metadata, so engines can skip irrelevant files and avoid unnecessary full-table scans.</p></li><li><p>Supporting schema evolution, allowing columns to be added, renamed, or dropped without rewriting existing data.</p></li></ul><p>Iceberg is already <a href="https://iceberg.apache.org/vendors/"><u>widely supported</u></a> by engines like Apache Spark, Trino, Snowflake, DuckDB, and ClickHouse, with a fast-growing community behind it.</p>
    <div>
      <h3>How Iceberg tables are stored</h3>
      <a href="#how-iceberg-tables-are-stored">
        
      </a>
    </div>
    
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/779M4zsH5QnpDwlTORk1fo/38e7732ca0e20645507bdc0c628f671b/1.png" />
          </figure><p>Internally, an Iceberg table is a collection of data files (typically stored in columnar formats like Parquet or ORC) and metadata files (typically stored in JSON or <a href="https://avro.apache.org/"><u>Avro</u></a>) that describe table snapshots, schemas, and partition layouts.</p><p>To understand how query engines interact efficiently with Iceberg tables, it helps to look at an Iceberg metadata file (simplified):</p>
            <pre><code>{
  "format-version": 2,
  "table-uuid": "0195e49b-8f7c-7933-8b43-d2902c72720a",
  "location": "s3://my-bucket/warehouse/0195e49b-79ca/table",
  "current-schema-id": 0,
  "schemas": [
    {
      "schema-id": 0,
      "type": "struct",
      "fields": [
        { "id": 1, "name": "id", "required": false, "type": "long" },
        { "id": 2, "name": "data", "required": false, "type": "string" }
      ]
    }
  ],
  "current-snapshot-id": 3567362634015106507,
  "snapshots": [
    {
      "snapshot-id": 3567362634015106507,
      "sequence-number": 1,
      "timestamp-ms": 1743297158403,
      "manifest-list": "s3://my-bucket/warehouse/0195e49b-79ca/table/metadata/snap-3567362634015106507-0.avro",
      "summary": {},
      "schema-id": 0
    }
  ],
  "partition-specs": [{ "spec-id": 0, "fields": [] }]
}</code></pre>
            <p>A few of the important components are:</p><ul><li><p><code>schemas</code>: Iceberg tracks schema changes over time. Engines use schema information to safely read and write data without needing to rewrite underlying files.</p></li><li><p><code>snapshots</code>: Each snapshot references a specific set of data files that represent the state of the table at a point in time. This enables features like time travel.</p></li><li><p><code>partition-specs</code>: These define how the table is logically partitioned. Query engines leverage this information during planning to skip unnecessary partitions, greatly improving query performance.</p></li></ul><p>By reading Iceberg metadata, query engines can efficiently prune partitions, load only the relevant snapshots, and fetch only the data files it needs, resulting in faster queries.</p>
    <div>
      <h3>Why do you need a data catalog?</h3>
      <a href="#why-do-you-need-a-data-catalog">
        
      </a>
    </div>
    <p>Although the Iceberg data and metadata files themselves live directly in object storage (like <a href="https://developers.cloudflare.com/r2/"><u>R2</u></a>), the list of tables and pointers to the current metadata need to be tracked centrally by a data catalog.</p><p>Think of a data catalog as a library's index system. While books (your data) are physically distributed across shelves (object storage), the index provides a single source of truth about what books exist, their locations, and their latest editions. Without this index, readers (query engines) would waste time searching for books, might access outdated versions, or could accidentally shelve new books in ways that make them unfindable.</p><p>Similarly, data catalogs ensure consistent, coordinated access, allowing multiple query engines to safely read from and write to the same tables without conflicts or data corruption.</p>
    <div>
      <h2>Create your first Iceberg table on R2</h2>
      <a href="#create-your-first-iceberg-table-on-r2">
        
      </a>
    </div>
    <p>Ready to try it out? Here’s a quick example using <a href="https://py.iceberg.apache.org/"><u>PyIceberg</u></a> and Python to get you started. For a detailed step-by-step guide, check out our <a href="https://developers.cloudflare.com/r2/data-catalog/get-started/"><u>developer docs</u></a>.</p><p>1. Enable R2 Data Catalog on your bucket:
</p>
            <pre><code>npx wrangler r2 bucket catalog enable my-bucket</code></pre>
            <p>Or use the Cloudflare dashboard: Navigate to <b>R2 Object Storage</b> &gt; <b>Settings</b> &gt; <b>R2 Data Catalog</b> and click <b>Enable</b>.</p><p>2. Create a <a href="https://developers.cloudflare.com/r2/api/s3/tokens/"><u>Cloudflare API token</u></a> with permissions for both R2 storage and the data catalog.</p><p>3. Install <a href="https://py.iceberg.apache.org/"><u>PyIceberg</u></a> and <a href="https://arrow.apache.org/docs/index.html"><u>PyArrow</u></a>, then open a Python shell or notebook:</p>
            <pre><code>pip install pyiceberg pyarrow</code></pre>
            <p>4. Connect to the catalog and create a table:</p>
            <pre><code>import pyarrow as pa
from pyiceberg.catalog.rest import RestCatalog

# Define catalog connection details (replace variables)
WAREHOUSE = "&lt;WAREHOUSE&gt;"
TOKEN = "&lt;TOKEN&gt;"
CATALOG_URI = "&lt;CATALOG_URI&gt;"

# Connect to R2 Data Catalog
catalog = RestCatalog(
    name="my_catalog",
    warehouse=WAREHOUSE,
    uri=CATALOG_URI,
    token=TOKEN,
)

# Create default namespace
catalog.create_namespace("default")

# Create simple PyArrow table
df = pa.table({
    "id": [1, 2, 3],
    "name": ["Alice", "Bob", "Charlie"],
})

# Create an Iceberg table
table = catalog.create_table(
    ("default", "my_table"),
    schema=df.schema,
)</code></pre>
            <p>You can now append more data or run queries, just as you would with any Apache Iceberg table.</p>
    <div>
      <h2>Pricing</h2>
      <a href="#pricing">
        
      </a>
    </div>
    <p>While R2 Data Catalog is in open beta, there will be no additional charges beyond standard R2 storage and operations costs incurred by query engines accessing data. <a href="https://r2-calculator.cloudflare.com/"><u>Storage pricing</u></a> for buckets with R2 Data Catalog enabled remains the same as standard R2 buckets – \$0.015 per GB-month. As always, egress directly from R2 buckets remains \$0.</p><p>In the future, we plan to introduce pricing for catalog operations (e.g., creating tables, retrieving table metadata, etc.) and data compaction.</p><p>Below is our current thinking on future pricing. We’ll communicate more details around timing well before billing begins, so you can confidently plan your workloads.</p><div>
    <figure>
        <table>
            <colgroup>
                <col></col>
                <col></col>
            </colgroup>
            <tbody>
                <tr>
                    <td> </td>
                    <td>
                        <p><span><span><strong>Pricing</strong></span></span></p>
                    </td>
                </tr>
                <tr>
                    <td>
                        <p><span><span>R2 storage</span></span></p>
                        <p><span><span>For standard storage class</span></span></p>
                    </td>
                    <td>
                        <p><span><span>$0.015 per GB-month (no change)</span></span></p>
                    </td>
                </tr>
                <tr>
                    <td>
                        <p><span><span>R2 Class A operations</span></span></p>
                    </td>
                    <td>
                        <p><span><span>$4.50 per million operations (no change)</span></span></p>
                    </td>
                </tr>
                <tr>
                    <td>
                        <p><span><span>R2 Class B operations</span></span></p>
                    </td>
                    <td>
                        <p><span><span>$0.36 per million operations (no change)</span></span></p>
                    </td>
                </tr>
                <tr>
                    <td>
                        <p><span><span>Data Catalog operations</span></span></p>
                        <p><span><span>e.g., create table, get table metadata, update table properties</span></span></p>
                    </td>
                    <td>
                        <p><span><span>$9.00 per million catalog operations</span></span></p>
                    </td>
                </tr>
                <tr>
                    <td>
                        <p><span><span>Data Catalog compaction data processed</span></span></p>
                    </td>
                    <td>
                        <p><span><span>$0.05 per GB processed</span></span></p>
                        <p><span><span>$4.00 per million objects processed</span></span></p>
                    </td>
                </tr>
                <tr>
                    <td>
                        <p><span><span>Data egress</span></span></p>
                    </td>
                    <td>
                        <p><span><span>$0 (no change, always free)</span></span></p>
                    </td>
                </tr>
            </tbody>
        </table>
    </figure>
</div>
    <div>
      <h2>What’s next?</h2>
      <a href="#whats-next">
        
      </a>
    </div>
    <p>We’re excited to see how you use R2 Data Catalog! If you’ve never worked with Iceberg – or even analytics data – before, we think this is the easiest way to get started.</p><p>Next on our roadmap is tackling compaction and table optimization. Query engines typically perform better when dealing with fewer, but larger data files. We will automatically re-write collections of small data files into larger files to deliver even faster query performance. </p><p>We’re also collaborating with the broad Apache Iceberg community to expand query-engine compatibility with the Iceberg REST Catalog spec.</p><p>We’d love your feedback. Join the <a href="https://discord.cloudflare.com/"><u>Cloudflare Developer Discord</u></a> to ask questions and share your thoughts during the public beta. For more details, examples, and guides, visit our <a href="https://developers.cloudflare.com/r2/data-catalog/get-started/"><u>developer documentation</u></a>.</p> ]]></content:encoded>
            <category><![CDATA[Developer Week]]></category>
            <category><![CDATA[R2]]></category>
            <category><![CDATA[Data Catalog]]></category>
            <category><![CDATA[Storage]]></category>
            <category><![CDATA[Developer Platform]]></category>
            <category><![CDATA[Product News]]></category>
            <guid isPermaLink="false">6JFB9cHUOoMZnVmYIuTLzd</guid>
            <dc:creator>Phillip Jones</dc:creator>
            <dc:creator>Garvit Gupta</dc:creator>
            <dc:creator>Alex Graham</dc:creator>
            <dc:creator>Garrett Gu</dc:creator>
        </item>
        <item>
            <title><![CDATA[Cloudflare incident on March 21, 2025]]></title>
            <link>https://blog.cloudflare.com/cloudflare-incident-march-21-2025/</link>
            <pubDate>Tue, 25 Mar 2025 01:40:38 GMT</pubDate>
            <description><![CDATA[ On March 21, 2025, multiple Cloudflare services, including R2 object storage experienced an elevated rate of error responses. Here’s what caused the incident, the impact, and how we are making sure it ]]></description>
            <content:encoded><![CDATA[ <p>Multiple Cloudflare services, including <a href="https://www.cloudflare.com/developer-platform/products/r2/"><u>R2 object storage</u></a>, experienced an elevated rate of errors for 1 hour and 7 minutes on March 21, 2025 (starting at 21:38 UTC and ending 22:45 UTC). During the incident window, 100% of write operations failed and approximately 35% of read operations to R2 failed globally. Although this incident started with R2, it impacted other Cloudflare services including <a href="https://www.cloudflare.com/developer-platform/products/cache-reserve/"><u>Cache Reserve</u></a>, <a href="https://www.cloudflare.com/developer-platform/products/cloudflare-images/"><u>Images</u></a>, <a href="https://developers.cloudflare.com/logs/edge-log-delivery/"><u>Log Delivery</u></a>, <a href="https://www.cloudflare.com/developer-platform/products/cloudflare-stream/"><u>Stream</u></a>, and <a href="https://developers.cloudflare.com/vectorize/"><u>Vectorize</u></a>.</p><p>While rotating credentials used by the R2 Gateway service (R2's API frontend) to authenticate with our storage infrastructure, the R2 engineering team inadvertently deployed the new credentials (ID and key pair) to a development instance of the service instead of production. When the old credentials were deleted from our storage infrastructure (as part of the key rotation process), the production R2 Gateway service did not have access to the new credentials. This ultimately resulted in R2’s Gateway service not being able to authenticate with our storage backend. There was no data loss or corruption that occurred as part of this incident: any in-flight uploads or mutations that returned successful HTTP status codes were persisted.</p><p>Once the root cause was identified and we realized we hadn’t deployed the new credentials to the production R2 Gateway service, we deployed the updated credentials and service availability was restored. </p><p>This incident happened because of human error and lasted longer than it should have because we didn’t have proper visibility into which credentials were being used by the Gateway Worker to authenticate with our storage infrastructure. </p><p>We’re deeply sorry for this incident and the disruption it may have caused to you or your users. We hold ourselves to a high standard and this is not acceptable. This blog post exactly explains the impact, what happened and when, and the steps we are taking to make sure this failure (and others like it) doesn’t happen again.</p>
    <div>
      <h2>What was impacted?</h2>
      <a href="#what-was-impacted">
        
      </a>
    </div>
    <p><b>The primary incident window occurred between 21:38 UTC and 22:45 UTC.</b></p><p>The following table details the specific impact to R2 and Cloudflare services that depend on, or interact with, R2:</p>
<div><table><thead>
  <tr>
    <th><span>Product/Service</span></th>
    <th><span>Impact</span></th>
  </tr></thead>
<tbody>
  <tr>
    <td><span>R2</span></td>
    <td><span>All customers using Cloudflare R2 would have experienced an elevated error rate during the primary incident window. Specifically:</span><br /><br /><span>* Object write operations had a 100% error rate.</span><br /><br /><span>* Object reads had an approximate error rate of 35% globally. Individual customer error rate varied during this window depending on access patterns. Customers accessing public assets through custom domains would have seen a reduced error rate as cached object reads were not impacted.</span><br /><br /><span>* Operations involving metadata only (e.g., head and list operations) were not impacted.</span><br /><br /><span>There was no data loss or risk to data integrity within R2's storage subsystem. This incident was limited to a temporary authentication issue between R2's API frontend and our storage infrastructure.</span></td>
  </tr>
  <tr>
    <td><span>Billing</span></td>
    <td><span>Billing uses R2 to store customer invoices. During the primary incident window, customers may have experienced errors when attempting to download/access past Cloudflare invoices.</span></td>
  </tr>
  <tr>
    <td><span>Cache Reserve</span></td>
    <td><span>Cache Reserve customers observed an increase in requests to their origin during the incident window as an increased percentage of reads to R2 failed. This resulted in an increase in requests to origins to fetch assets unavailable in Cache Reserve during this period.</span><br /><br /><span>User-facing requests for assets to sites with Cache Reserve did not observe failures as cache misses failed over to the origin.</span></td>
  </tr>
  <tr>
    <td><span>Email Security</span></td>
    <td><span>Email Security depends on R2 for customer-facing metrics. During the primary incident window, customer-facing metrics would not have updated.</span></td>
  </tr>
  <tr>
    <td><span>Images</span></td>
    <td><span>All (100% of) uploads failed during the primary incident window. Successful delivery of stored images dropped to approximately 25%.</span></td>
  </tr>
  <tr>
    <td><span>Key Transparency Auditor</span></td>
    <td><span>All (100% of) operations failed during the primary incident window due to dependence on R2 writes and/or reads. Once the incident was resolved, service returned to normal operation immediately.</span></td>
  </tr>
  <tr>
    <td><span>Log Delivery</span></td>
    <td><span>Log delivery (for Logpush and Logpull) was delayed during the primary incident window, resulting in significant delays (up to 70 minutes) in log processing. All logs were delivered after incident resolution.</span></td>
  </tr>
  <tr>
    <td><span>Stream</span></td>
    <td><span>All (100% of) uploads failed during the primary incident window. Successful Stream video segment delivery dropped to 94%. Viewers may have seen video stalls every minute or so, although actual impact would have varied.</span><br /><br /><span>Stream Live was down during the primary incident window as it depends on object writes.</span></td>
  </tr>
  <tr>
    <td><span>Vectorize</span></td>
    <td><span>Queries and operations against Vectorize indexes were impacted during the incident window. During the incident window, Vectorize customers would have seen an increased error rate for read queries to indexes and all (100% of) insert and upsert operation failed as Vectorize depends on R2 for persistent storage.</span></td>
  </tr>
</tbody></table></div>
    <div>
      <h2>Incident timeline</h2>
      <a href="#incident-timeline">
        
      </a>
    </div>
    <p><b>All timestamps referenced are in Coordinated Universal Time (UTC).</b></p>
<div><table><colgroup>
<col></col>
<col></col>
</colgroup>
<thead>
  <tr>
    <th><span>Time</span></th>
    <th><span>Event</span></th>
  </tr></thead>
<tbody>
  <tr>
    <td><span>Mar 21, 2025 - 19:49 UTC</span></td>
    <td><span>The R2 engineering team started the credential rotation process. A new set of credentials (ID and key pair) for storage infrastructure was created. Old credentials were maintained to avoid downtime during credential change over.</span></td>
  </tr>
  <tr>
    <td><span>Mar 21, 2025 - 20:19 UTC</span></td>
    <td><span>Set updated production secret (</span><span>wrangler secret put</span><span>) and executed </span><span>wrangler deploy</span><span> command to deploy R2 Gateway service with updated credentials. </span><br /><br /><span>Note: We later discovered the </span><span>--env</span><span> parameter was inadvertently omitted for both Wrangler commands. This resulted in credentials being deployed to the Worker assigned to the </span><span>default</span><span> environment instead of the Worker assigned to the </span><span>production</span><span> environment.</span></td>
  </tr>
  <tr>
    <td><span>Mar 21, 2025 - 20:20 UTC</span></td>
    <td><span>The R2 Gateway service Worker assigned to the </span><span>default</span><span> environment is now using the updated storage infrastructure credentials.</span><br /><br /><span>Note: This was the wrong Worker, the </span><span>production</span><span> environment should have been explicitly set. But, at this point, we incorrectly believed the credentials were updated on the correct production Worker.</span></td>
  </tr>
  <tr>
    <td><span>Mar 21, 2025 - 20:37 UTC</span></td>
    <td><span>Old credentials were removed from our storage infrastructure to complete the credential rotation process.</span></td>
  </tr>
  <tr>
    <td><span>Mar 21, 2025 - 21:38 UTC</span></td>
    <td><span>– IMPACT BEGINS –</span><br /><br /><span>R2 availability metrics begin to show signs of service degradation. The impact to R2 availability metrics was gradual and not immediately obvious because there was a delay in the propagation of the previous credential deletion to storage infrastructure.</span></td>
  </tr>
  <tr>
    <td><span>Mar 21, 2025 - 21:45 UTC</span></td>
    <td><span>R2 global availability alerts are triggered (indicating 2% of error budget burn rate).</span><br /><br /><span>The R2 engineering team began looking at operational dashboards and logs to understand impact.</span></td>
  </tr>
  <tr>
    <td><span>Mar 21, 2025 - 21:50 UTC</span></td>
    <td><span>Internal incident declared.</span></td>
  </tr>
  <tr>
    <td><span>Mar 21, 2025 - 21:51 UTC</span></td>
    <td><span>R2 engineering team observes gradual but consistent decline in R2 availability metrics for both read and write operations. Operations involving metadata only (e.g., head and list operations) were not impacted.</span><br /><br /><span>Given gradual decline in availability metrics, R2 engineering team suspected a potential regression in propagation of new credentials in storage infrastructure.</span></td>
  </tr>
  <tr>
    <td><span>Mar 21, 2025 - 22:05 UTC</span></td>
    <td><span>Public incident status page published.</span></td>
  </tr>
  <tr>
    <td><span>Mar 21, 2025 - 22:15 UTC</span></td>
    <td><span>R2 engineering team created a new set of credentials (ID and key pair) for storage infrastructure in an attempt to force re-propagation.</span><br /><br /><span>Continued monitoring operational dashboards and logs.</span></td>
  </tr>
  <tr>
    <td><span>Mar 21, 2025 - 22:20 UTC</span></td>
    <td><span>R2 engineering team saw no improvement in availability metrics. Continued investigating other potential root causes.</span></td>
  </tr>
  <tr>
    <td><span>Mar 21, 2025 - 22:30 UTC</span></td>
    <td><span>R2 engineering team deployed a new set of credentials (ID and key pair) to R2 Gateway service Worker. This was to validate whether there was an issue with the credentials we had pushed to gateway service.</span><br /><br /><span>Environment parameter was still omitted in the </span><span>deploy</span><span> and </span><span>secret put</span><span> commands, so this deployment was still to the wrong non-production Worker.</span></td>
  </tr>
  <tr>
    <td><span>Mar 21, 2025 - 22:36 UTC</span></td>
    <td><span>– ROOT CAUSE IDENTIFIED –</span><br /><br /><span>The R2 engineering team discovered that credentials had been deployed to a non-production Worker by reviewing production Worker release history.</span></td>
  </tr>
  <tr>
    <td><span>Mar 21, 2025 - 22:45 UTC</span></td>
    <td><span>– IMPACT ENDS –</span><br /><br /><span>Deployed credentials to correct production Worker. R2 availability recovered.</span></td>
  </tr>
  <tr>
    <td><span>Mar 21, 2025 - 22:54 UTC</span></td>
    <td><span>The incident is considered resolved.</span></td>
  </tr>
</tbody></table></div>
    <div>
      <h2>Analysis</h2>
      <a href="#analysis">
        
      </a>
    </div>
    <p>R2’s architecture is primarily composed of three parts: R2 production gateway Worker (serves requests from S3 API, REST API, Workers API), metadata service, and storage infrastructure (stores encrypted object data).</p>
          <figure>
          <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1G9gfdEE4RIuMIUeNz42RN/25d1b4cca187a4a24c600a43ba51fb71/BLOG-2793_2.png" />
          </figure><p>The R2 Gateway Worker uses credentials (ID and key pair) to securely authenticate with our distributed storage infrastructure. We rotate these credentials regularly as a best practice security precaution.</p><p>Our key rotation process involves the following high-level steps:</p><ol><li><p>Create a new set of credentials (ID and key pair) for our storage infrastructure. At this point, the old credentials are maintained to avoid downtime during credential change over.</p></li><li><p>Set the new credential secret for the R2 production gateway Worker using the <code>wrangler secret put</code> command.</p></li><li><p>Set the new updated credential ID as an environment variable in the R2 production gateway Worker using the <code>wrangler deploy</code> command. At this point, new storage credentials start being used by the gateway Worker.</p></li><li><p>Remove previous credentials from our storage infrastructure to complete the credential rotation process.</p></li><li><p>Monitor operational dashboards and logs to validate change over.</p></li></ol><p>The R2 engineering team uses <a href="https://developers.cloudflare.com/workers/wrangler/environments/"><u>Workers environments</u></a> to separate production and development environments for the R2 Gateway Worker. Each environment defines a separate isolated Cloudflare Worker with separate environment variables and secrets. </p><p>Critically, both <code>wrangler secret put</code> and <code>wrangler deploy</code> commands default to the default environment if the --env command line parameter is not included. In this case, due to human error, we inadvertently omitted the --env parameter and deployed the new storage credentials to the wrong Worker (<code>default</code> environment instead of <code>production</code>). To correctly deploy storage credentials to the production R2 Gateway Worker, we need to specify <code>--env production</code>.</p><p>The action we took on step 4 above to remove the old credentials from our storage infrastructure caused authentication errors, as the R2 Gateway production Worker still had the old credentials. This is ultimately what resulted in degraded availability.</p><p>The decline in R2 availability metrics was gradual and not immediately obvious because there was a delay in the propagation of the previous credential deletion to storage infrastructure. This accounted for a delay in our initial discovery of the problem. Instead of relying on availability metrics after updating the old set of credentials, we should have explicitly validated which token was being used by the R2 Gateway service to authenticate with R2's storage infrastructure.</p><p>Overall, the impact on read availability was significantly mitigated by our intermediate cache that sits in front of storage and continued to serve requests.</p>
    <div>
      <h2>Resolution</h2>
      <a href="#resolution">
        
      </a>
    </div>
    <p>Once we identified the root cause, we were able to resolve the incident quickly by deploying the new credentials to the production R2 Gateway Worker. This resulted in an immediate recovery of R2 availability.</p>
    <div>
      <h2>Next steps</h2>
      <a href="#next-steps">
        
      </a>
    </div>
    <p>This incident happened because of human error and lasted longer than it should have because we didn’t have proper visibility into which credentials were being used by the R2 Gateway Worker to authenticate with our storage infrastructure.</p><p>We have taken immediate steps to prevent this failure (and others like it) from happening again:</p><ul><li><p>Added logging tags that include the suffix of the credential ID the R2 Gateway Worker uses to authenticate with our storage infrastructure. With this change, we can explicitly confirm which credential is being used.</p></li><li><p>Related to the above step, our internal processes now require explicit confirmation that the suffix of the new token ID matches logs from our storage infrastructure before deleting the previous token.</p></li><li><p>Require that key rotation takes place through our hotfix release tooling instead of relying on manual wrangler command entry which introduces human error. Our hotfix release deploy tooling explicitly enforces the environment configuration and contains other safety checks.</p></li><li><p>While it’s been an implicit standard that this process involves at least two humans to validate the changes ahead as we progress, we’ve updated our relevant SOPs (standard operating procedures) to include this explicitly.</p></li><li><p><b>In Progress</b>: Extend our existing closed loop health check system that monitors our endpoints to test new keys, automate reporting of their status through our alerting platform, and ensure global propagation prior to releasing the gateway Worker. </p></li><li><p><b>In Progress</b>: To expedite triage on any future issues with our distributed storage endpoints, we are updating our <a href="https://www.cloudflare.com/learning/performance/what-is-observability/">observability</a> platform to include views of upstream success rates that bypass caching to give clearer indication of issues serving requests for any reason.</p></li></ul><p>The list above is not exhaustive: as we work through the above items, we will likely uncover other improvements to our systems, controls, and processes that we’ll be applying to improve R2’s resiliency, on top of our business-as-usual efforts. We are confident that this set of changes will prevent this failure, and related credential rotation failure modes, from occurring again. Again, we sincerely apologize for this incident and deeply regret any disruption it has caused you or your users.</p> ]]></content:encoded>
            <category><![CDATA[Outage]]></category>
            <category><![CDATA[Post Mortem]]></category>
            <guid isPermaLink="false">4I4XNCQlRirlf9SaA9ySTS</guid>
            <dc:creator>Phillip Jones</dc:creator>
        </item>
        <item>
            <title><![CDATA[Developer Week 2024 wrap-up]]></title>
            <link>https://blog.cloudflare.com/developer-week-2024-wrap-up/</link>
            <pubDate>Mon, 08 Apr 2024 13:00:02 GMT</pubDate>
            <description><![CDATA[ Developer Week 2024 has officially come to a close. Here’s a quick recap of the announcements and in-depth technical explorations that went out last week ]]></description>
            <content:encoded><![CDATA[ <p></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7fwPu75tSubJgSS8nJ5gOt/6e2fd9b7cc6f9dcd7b86d73988a6e5fb/Dev-week-wrap-up-1.jpg" />
            
            </figure><p>Developer Week 2024 has officially come to a close. Each day last week, we shipped new products and functionality geared towards giving developers the components they need to build full-stack applications on Cloudflare.</p><p>Even though Developer Week is now over, we are continuing to innovate with the over two million developers who build on our platform. Building a platform is only as exciting as seeing what developers build on it. Before we dive into a recap of the announcements, to send off the week, we wanted to share how a couple of companies are using Cloudflare to power their applications:</p><blockquote><p><i>We have been using Workers for image delivery using R2 and have been able to maintain stable operations for a year after implementation. The speed of deployment and the flexibility of detailed configurations have greatly reduced the time and effort required for traditional server management. In particular, we have seen a noticeable cost savings and are deeply appreciative of the support we have received from Cloudflare Workers.</i>- <a href="http://www.fancs.com/">FAN Communications</a></p></blockquote><blockquote><p><i>Milkshake helps creators, influencers, and business owners create engaging web pages directly from their phone, to simply and creatively promote their projects and passions. Cloudflare has helped us migrate data quickly and affordably with R2. We use Workers as a routing layer between our users' websites and their images and assets, and to build a personalized analytics offering affordably. Cloudflare’s innovations have consistently allowed us to run infrastructure at a fraction of the cost of other developer platforms and we have been eagerly awaiting updates to D1 and Queues to sustainably scale Milkshake as the product continues to grow.</i>- <a href="https://milkshake.app/">Milkshake</a></p></blockquote><p>In case you missed anything, here’s a quick recap of the announcements and in-depth technical explorations that went out last week:</p>
    <div>
      <h2>Summary of announcements</h2>
      <a href="#summary-of-announcements">
        
      </a>
    </div>
    
    <div>
      <h3>Monday</h3>
      <a href="#monday">
        
      </a>
    </div>
    
<table>
<thead>
  <tr>
    <th><span>Announcement</span></th>
    <th><span>Summary</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><a href="http://staging.blog.mrk.cfdata.org/making-full-stack-easier-d1-ga-hyperdrive-queues"><span>Making state easy with D1 GA, Hyperdrive, Queues and Workers Analytics Engine updates</span></a></td>
    <td><span>A core part of any full-stack application is storing and persisting data! We kicked off the week with announcements that help developers build stateful applications on top of Cloudflare, including making D1, Cloudflare’s SQL database and Hyperdrive, our database accelerating service, generally available.</span></td>
  </tr>
  <tr>
    <td><a href="http://staging.blog.mrk.cfdata.org/building-d1-a-global-database"><span>Building D1: a Global Database</span></a></td>
    <td><span>D1, Cloudflare’s SQL database, is now generally available. With new support for 10GB databases, data export, and enhanced query debugging, we empower developers to build production-ready applications with D1 to meet all their relational SQL needs. To support Workers in global applications, we’re sharing a sneak peek of our design and API for D1 global read replication to demonstrate how developers scale their workloads with D1.</span></td>
  </tr>
  <tr>
    <td><a href="http://staging.blog.mrk.cfdata.org/workers-environment-live-object-bindings"><span>Why Workers environment variables contain live objects</span></a></td>
    <td><span>Bindings don't just reduce boilerplate. They are a core design feature of the Workers platform which simultaneously improve developer experience and application security in several ways. Usually these two goals are in opposition to each other, but bindings elegantly solve for both at the same time.</span></td>
  </tr>
</tbody>
</table>
    <div>
      <h3>Tuesday</h3>
      <a href="#tuesday">
        
      </a>
    </div>
    
<table>
<thead>
  <tr>
    <th><span>Announcement</span></th>
    <th><span>Summary</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><a href="http://staging.blog.mrk.cfdata.org/workers-ai-ga-huggingface-loras-python-support"><span>Leveling up Workers AI: General Availability and more new capabilities</span></a></td>
    <td><span>We made a series of AI-related announcements, including Workers AI, Cloudflare’s inference platform becoming GA, support for fine-tuned models with LoRAs, one-click deploys from HuggingFace, Python support for Cloudflare Workers, and more.</span></td>
  </tr>
  <tr>
    <td><a href="http://staging.blog.mrk.cfdata.org/fine-tuned-inference-with-loras"><span>Running fine-tuned models on Workers AI with LoRAs</span></a></td>
    <td><span>Workers AI now supports fine-tuned models using LoRAs. But what is a LoRA and how does it work? In this post, we dive into fine-tuning, LoRAs and even some math to share the details of how it all works under the hood.</span></td>
  </tr>
  <tr>
    <td><a href="http://staging.blog.mrk.cfdata.org/python-workers"><span>Bringing Python to Workers using Pyodide and WebAssembly</span></a></td>
    <td><span>We introduced Python support for Cloudflare Workers, now in open beta. We've revamped our systems to support Python, from the Workers runtime itself to the way Workers are deployed to Cloudflare’s network. Learn about a Python Worker's lifecycle, Pyodide, dynamic linking, and memory snapshots in this post.</span></td>
  </tr>
</tbody>
</table>
    <div>
      <h3>Wednesday</h3>
      <a href="#wednesday">
        
      </a>
    </div>
    
<table>
<thead>
  <tr>
    <th><span>Announcement</span></th>
    <th><span>Summary</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><a href="http://staging.blog.mrk.cfdata.org/r2-events-gcs-migration-infrequent-access"><span>R2 adds event notifications, support for migrations from Google Cloud Storage, and an infrequent access storage tier</span></a></td>
    <td><span>We announced three new features for Cloudflare R2: event notifications, support for migrations from Google Cloud Storage, and an infrequent access storage tier.</span></td>
  </tr>
  <tr>
    <td><a href="http://staging.blog.mrk.cfdata.org/data-anywhere-events-pipelines-durable-execution-workflows"><span>Data Anywhere with Pipelines, Event Notifications, and Workflows</span></a></td>
    <td><span>We’re making it easier to build scalable, reliable, data-driven applications on top of our global network, and so we announced a new Event Notifications framework; our take on durable execution, Workflows; and an upcoming streaming ingestion service, Pipelines.</span></td>
  </tr>
  <tr>
    <td><a href="http://staging.blog.mrk.cfdata.org/prisma-orm-and-d1"><span>Improving Cloudflare Workers and D1 developer experience with Prisma ORM</span></a></td>
    <td><span>Together, Cloudflare and Prisma make it easier than ever to deploy globally available apps with a focus on developer experience. To further that goal, Prisma ORM now natively supports Cloudflare Workers and D1 in Preview. With version 5.12.0 of Prisma ORM you can now interact with your data stored in D1 from your Cloudflare Workers with the convenience of the Prisma Client API. Learn more and try it out now.</span></td>
  </tr>
  <tr>
    <td><a href="http://staging.blog.mrk.cfdata.org/picsart-move-to-workers-huge-performance-gains"><span>How Picsart leverages Cloudflare's Developer Platform to build globally performant services</span></a></td>
    <td><span>Picsart, one of the world’s largest digital creation platforms, encountered performance challenges in catering to its global audience. Adopting Cloudflare's global-by-default Developer Platform emerged as the optimal solution, empowering Picsart to enhance performance and scalability substantially.</span></td>
  </tr>
</tbody>
</table>
    <div>
      <h3>Thursday</h3>
      <a href="#thursday">
        
      </a>
    </div>
    
<table>
<thead>
  <tr>
    <th><span>Announcement</span></th>
    <th><span>Summary</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><a href="http://staging.blog.mrk.cfdata.org/pages-workers-integrations-monorepos-nextjs-wrangler"><span>Announcing Pages support for monorepos, wrangler.toml, database integrations and more!</span></a></td>
    <td><span>We launched four improvements to Pages that bring functionality previously restricted to Workers, with the goal of unifying the development experience between the two. Support for monorepos, wrangler.toml, new additions to Next.js support and database integrations!</span></td>
  </tr>
  <tr>
    <td><a href="http://staging.blog.mrk.cfdata.org/workers-production-safety"><span>New tools for production safety — Gradual Deployments, Stack Traces, Rate Limiting, and API SDKs</span></a></td>
    <td><span>Production readiness isn’t just about scale and reliability of the services you build with. We announced five updates that put more power in your hands – Gradual Deployments, Source mapped stack traces in Tail Workers, a new Rate Limiting API, brand-new API SDKs, and updates to Durable Objects – each built with mission-critical production services in mind.</span></td>
  </tr>
  <tr>
    <td><a href="http://staging.blog.mrk.cfdata.org/whats-next-for-cloudflare-media"><span>What’s new with Cloudflare Media: updates for Calls, Stream, and Images</span></a></td>
    <td><span>With Cloudflare Calls in open beta, you can build real-time, serverless video and audio applications. Cloudflare Stream lets your viewers instantly clip from ongoing streams. Finally, Cloudflare Images now supports automatic face cropping and has an upload widget that lets you easily integrate into your application.</span></td>
  </tr>
  <tr>
    <td><a href="http://staging.blog.mrk.cfdata.org/cloudflare-calls-anycast-webrtc"><span>Cloudflare Calls: millions of cascading trees all the way down</span></a></td>
    <td><span>Cloudflare Calls is a serverless SFU and TURN service running at Cloudflare’s edge. It’s now in open beta and costs $0.05/ real-time GB. It’s 100% anycast WebRTC.</span></td>
  </tr>
</tbody>
</table>
    <div>
      <h3>Friday</h3>
      <a href="#friday">
        
      </a>
    </div>
    
<table>
<thead>
  <tr>
    <th><span>Announcement</span></th>
    <th><span>Summary</span></th>
  </tr>
</thead>
<tbody>
  <tr>
    <td><a href="http://staging.blog.mrk.cfdata.org/browser-rendering-api-ga-rolling-out-cloudflare-snippets-swr-and-bringing-workers-for-platforms-to-our-paygo-plans"><span>Browser Rendering API GA, rolling out Cloudflare Snippets, SWR, and bringing Workers for Platforms to all users</span></a></td>
    <td><span>Browser Rendering API is now available to all paid Workers customers with improved session management.</span></td>
  </tr>
  <tr>
    <td><a href="http://staging.blog.mrk.cfdata.org/cloudflare-acquires-baselime-expands-observability-capabilities"><span>Cloudflare acquires Baselime to expand serverless application observability capabilities</span></a></td>
    <td><span>We announced that Cloudflare has acquired Baselime, a serverless observability company.</span></td>
  </tr>
  <tr>
    <td><a href="http://staging.blog.mrk.cfdata.org/cloudflare-acquires-partykit"><span>Cloudflare acquires PartyKit to allow developers to build real-time multi-user applications</span></a></td>
    <td><span>We announced that PartyKit, a trailblazer in enabling developers to craft ambitious real-time, collaborative, multiplayer applications, is now a part of Cloudflare. This acquisition marks a significant milestone in our journey to redefine the boundaries of serverless computing, making it more dynamic, interactive, and, importantly, stateful.</span></td>
  </tr>
  <tr>
    <td><a href="http://staging.blog.mrk.cfdata.org/blazing-fast-development-with-full-stack-frameworks-and-cloudflare"><span>Blazing fast development with full-stack frameworks and Cloudflare</span></a></td>
    <td><span>Full-stack web development with Cloudflare is now faster and easier! You can now use your framework’s development server while accessing D1 databases, R2 object stores, AI models, and more. Iterate locally in milliseconds to build sophisticated web apps that run on Cloudflare. Let’s dev together!</span></td>
  </tr>
  <tr>
    <td><a href="http://staging.blog.mrk.cfdata.org/javascript-native-rpc"><span>We've added JavaScript-native RPC to Cloudflare Workers</span></a></td>
    <td><span>Cloudflare Workers now features a built-in RPC (Remote Procedure Call) system for use in Worker-to-Worker and Worker-to-Durable Object communication, with absolutely minimal boilerplate. We've designed an RPC system so expressive that calling a remote service can feel like using a library.</span></td>
  </tr>
  <tr>
    <td><a href="http://staging.blog.mrk.cfdata.org/2024-community-update"><span>Community Update: empowering startups building on Cloudflare and creating an inclusive community</span></a></td>
    <td><span>We closed out Developer Week by sharing updates on our Workers Launchpad program, our latest Developer Challenge, and the work we’re doing to ensure our community spaces – like our Discord and Community forums – are safe and inclusive for all developers.</span></td>
  </tr>
</tbody>
</table><p>Here's a video summary, by Craig Dennis, Developer Educator, AI:</p><blockquote><p>🏃<a href="https://twitter.com/CloudflareDev?ref_src=twsrc%5Etfw">@CloudflareDev</a> Developer Week 2024 🧡 ICYMI 🧡 Speed run <a href="https://t.co/0uzPJshC93">pic.twitter.com/0uzPJshC93</a></p>— Craig Dennis (@craigsdennis) <a href="https://twitter.com/craigsdennis/status/1778875721575989734?ref_src=twsrc%5Etfw">April 12, 2024</a></blockquote> 
    <div>
      <h3>Continue the conversation</h3>
      <a href="#continue-the-conversation">
        
      </a>
    </div>
    <p>Thank you for being a part of Developer Week! Want to continue the conversation and share what you’re building? Join us on <a href="https://discord.com/invite/cloudflaredev">Discord</a>. To get started building on Workers, check out our <a href="https://developers.cloudflare.com/workers/">developer documentation</a>.</p> ]]></content:encoded>
            <category><![CDATA[Developer Week]]></category>
            <category><![CDATA[Developers]]></category>
            <category><![CDATA[Product News]]></category>
            <category><![CDATA[Cloudflare Workers]]></category>
            <category><![CDATA[Cloudflare Pages]]></category>
            <category><![CDATA[Rate Limiting]]></category>
            <category><![CDATA[API]]></category>
            <category><![CDATA[D1]]></category>
            <category><![CDATA[Connectivity Cloud]]></category>
            <guid isPermaLink="false">VNnYecAmN7CpST4nBbas0</guid>
            <dc:creator>Phillip Jones</dc:creator>
        </item>
        <item>
            <title><![CDATA[Sippy helps you avoid egress fees while incrementally migrating data from S3 to R2]]></title>
            <link>https://blog.cloudflare.com/sippy-incremental-migration-s3-r2/</link>
            <pubDate>Tue, 26 Sep 2023 13:00:44 GMT</pubDate>
            <description><![CDATA[ Use Sippy to incrementally migrate data from S3 to R2 as it’s requested and avoid migration-specific egress fees ]]></description>
            <content:encoded><![CDATA[ <p></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4whKfl7szHhdKNWCiCETR3/d65f22ad8c25598a41426bd1de59188e/image1-16.png" />
            
            </figure><p>Earlier in 2023, we announced <a href="/r2-super-slurper-ga/">Super Slurper</a>, a data migration tool that makes it easy to copy large amounts of data to <a href="https://developers.cloudflare.com/r2/">R2</a> from other <a href="https://www.cloudflare.com/developer-platform/products/r2/">cloud object storage</a> providers. Since the announcement, developers have used Super Slurper to run thousands of successful migrations to R2!</p><p>While Super Slurper is perfect for cases where you want to move all of your data to R2 at once, there are scenarios where you may want to migrate your data incrementally over time. Maybe you want to avoid the one time upfront <a href="https://www.cloudflare.com/learning/cloud/what-is-aws-data-transfer-pricing/">AWS data transfer bill</a>? Or perhaps you have legacy data that may never be accessed, and you only want to migrate what’s required?</p><p>Today, we’re announcing the open beta of <a href="https://developers.cloudflare.com/r2/data-migration/sippy/">Sippy</a>, an incremental migration service that copies data from S3 (other cloud providers coming soon!) to R2 as it’s requested, without paying unnecessary cloud egress fees typically associated with moving large amounts of data. On top of addressing <a href="https://www.cloudflare.com/learning/cloud/what-is-vendor-lock-in/">vendor lock-in</a>, Sippy makes stressful, time-consuming migrations a thing of the past. All you need to do is replace the S3 endpoint in your application or attach your domain to your new R2 bucket and data will start getting copied over.</p>
    <div>
      <h2>How does it work?</h2>
      <a href="#how-does-it-work">
        
      </a>
    </div>
    <p>Sippy is an incremental migration service built directly into your R2 bucket. Migration-specific <a href="https://www.cloudflare.com/learning/cloud/what-are-data-egress-fees/">egress fees</a> are reduced by leveraging requests within the flow of your application where you’d already be paying egress fees to simultaneously copy objects to R2. Here is how it works:</p><p>When an object is requested from <a href="https://developers.cloudflare.com/r2/api/workers/">Workers</a>, <a href="https://developers.cloudflare.com/r2/api/s3/">S3 API</a>, or <a href="https://developers.cloudflare.com/r2/buckets/public-buckets/">public bucket</a>, it is served from your R2 bucket if it is found.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2QSl0q22LEdoOUp6BzkWhE/12f69030f3c5a4d53edf0a7d62af8b43/image2-16.png" />
            
            </figure><p>If the object is not found in R2, it will simultaneously be returned from your S3 bucket and copied to R2.</p><p>Note: Some large objects may take multiple requests to copy.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7ok5dS498ocJgCBRR1V5HU/683129c203b3343af7a4aa1c29e15b8a/image3-22.png" />
            
            </figure><p>That means after objects are copied, subsequent requests will be served from R2, and you’ll begin saving on egress fees immediately.</p>
    <div>
      <h2>Start incrementally migrating data from S3 to R2</h2>
      <a href="#start-incrementally-migrating-data-from-s3-to-r2">
        
      </a>
    </div>
    
    <div>
      <h3>Create an R2 bucket</h3>
      <a href="#create-an-r2-bucket">
        
      </a>
    </div>
    <p>To get started with incremental migration, you’ll first need to create an R2 bucket if you don’t already have one. To create a new R2 bucket from the Cloudflare dashboard:</p><ol><li><p>Log in to the <a href="https://dash.cloudflare.com/">Cloudflare dashboard</a> and select <b>R2</b>.</p></li><li><p>Select <b>Create bucket</b>.</p></li><li><p>Give your bucket a name and select <b>Create bucket</b>.</p></li></ol><p>​​To learn more about other ways to create R2 buckets refer to the documentation on <a href="https://developers.cloudflare.com/r2/buckets/create-buckets/">creating buckets</a>.</p>
    <div>
      <h3>Enable Sippy on your R2 bucket</h3>
      <a href="#enable-sippy-on-your-r2-bucket">
        
      </a>
    </div>
    <p>Next, you’ll enable Sippy for the R2 bucket you created. During the beta, you can do this by using the API. Here’s an example of how to enable Sippy for an R2 bucket with cURL:</p>
            <pre><code>curl -X PUT https://api.cloudflare.com/client/v4/accounts/{account_id}/r2/buckets/{bucket_name}/sippy \
--header "Authorization: Bearer &lt;API_TOKEN&gt;" \
--data '{"provider": "AWS", "bucket": "&lt;AWS_BUCKET_NAME&gt;", "zone": "&lt;AWS_REGION&gt;","key_id": "&lt;AWS_ACCESS_KEY_ID&gt;", "access_key":"&lt;AWS_SECRET_ACCESS_KEY&gt;", "r2_key_id": "&lt;R2_ACCESS_KEY_ID&gt;", "r2_access_key": "&lt;R2_SECRET_ACCESS_KEY&gt;"}'</code></pre>
            <p>For more information on getting started, please refer to the <a href="https://developers.cloudflare.com/r2/data-migration/sippy/">documentation</a>. Once enabled, requests to your bucket will now start copying data over from S3 if it’s not already present in your R2 bucket.</p>
    <div>
      <h3>Finish your migration with Super Slurper</h3>
      <a href="#finish-your-migration-with-super-slurper">
        
      </a>
    </div>
    <p>You can run your incremental migration for as long as you want, but eventually you may want to complete the migration to R2. To do this, you can pair Sippy with <a href="https://developers.cloudflare.com/r2/data-migration/super-slurper/">Super Slurper</a> to easily migrate your remaining data that hasn’t been accessed to R2.</p>
    <div>
      <h2>What’s next?</h2>
      <a href="#whats-next">
        
      </a>
    </div>
    <p>We’re excited about open beta, but it’s only the starting point. Next, we plan on making incremental migration configurable from the Cloudflare dashboard, complete with analytics that show you the progress of your migration and how much you are saving by not paying egress fees for objects that have been copied over so far.</p><p>If you are looking to start incrementally migrating your data to R2 and have any questions or feedback on what we should build next, we encourage you to join our <a href="https://discord.com/invite/cloudflaredev">Discord community</a> to share!</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5OxNi1UZsYR9ITa7KbaQ11/753b4c01ddbed65d637c55b0b91a47de/Kfb7dwYUUzfrLKPH_ukrJRTvRlfl4E8Uy00vwEQPCTiW0IQ--fxpikjv1p0afm4A5J3JfVjQiOVjN3RMNeMcu3vhnz97pEmENCkNIuwdW_m-aW7ABfZnmUpJB_jh.png" />
            
            </figure><p></p> ]]></content:encoded>
            <category><![CDATA[Birthday Week]]></category>
            <category><![CDATA[Product News]]></category>
            <category><![CDATA[Storage]]></category>
            <category><![CDATA[Developers]]></category>
            <category><![CDATA[Connectivity Cloud]]></category>
            <category><![CDATA[R2]]></category>
            <guid isPermaLink="false">4Oc5iRahgLMh31qeAxVZPt</guid>
            <dc:creator>Phillip Jones</dc:creator>
            <dc:creator>Vlad Krasnov</dc:creator>
        </item>
        <item>
            <title><![CDATA[Cloudflare R2 and MosaicML enable training LLMs on any compute, anywhere in the world, with zero switching costs]]></title>
            <link>https://blog.cloudflare.com/cloudflare-r2-mosaicml-train-llms-anywhere-faster-cheaper/</link>
            <pubDate>Tue, 16 May 2023 13:00:54 GMT</pubDate>
            <description><![CDATA[ Together, Cloudflare and MosaicML give customers the freedom to train LLMs on any compute, anywhere in the world, with zero switching costs. That means faster, cheaper training runs, and no vendor lock in. ]]></description>
            <content:encoded><![CDATA[ <p></p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/5BYHRApu97ZOlXvHf0cIMs/4f30b2009add920757a79e9f6c6ca1b5/111.png" />
            
            </figure><p>Building the large language models (LLMs) and diffusion models that power <a href="https://www.cloudflare.com/learning/ai/what-is-generative-ai/">generative AI</a> requires massive infrastructure. The most obvious component is compute – hundreds to thousands of GPUs – but an equally critical (and often overlooked) component is the <b>data storage infrastructure.</b> Training datasets can be terabytes to petabytes in size, and this data needs to be read in parallel by thousands of processes. In addition, model checkpoints need to be saved frequently throughout a training run, and for LLMs these checkpoints can each be hundreds of gigabytes!</p><p>To <a href="https://r2-calculator.cloudflare.com/">manage storage costs</a> and scalability, many machine learning teams have been moving to <a href="https://www.cloudflare.com/learning/cloud/what-is-object-storage/">object storage</a> to host their datasets and checkpoints. Unfortunately, most <a href="https://www.cloudflare.com/developer-platform/products/r2/">object store providers</a> use egress fees to “lock in” users to their platform. This makes it very difficult to leverage GPU capacity across multiple cloud providers, or take advantage of lower / dynamic pricing elsewhere, since the data and model checkpoints are too expensive to move. At a time when cloud GPUs are scarce, and new hardware options are entering the market, it’s more important than ever to stay flexible.</p><p>In addition to high egress fees, there is a technical barrier to object-store-centric machine learning training. Reading and writing data between object storage and compute clusters requires high throughput, efficient use of network bandwidth, determinism, and elasticity (the ability to train on different #s of GPUs). Building training software to handle all of this correctly and reliably is hard!</p><p>Today, we’re excited to show how MosaicML’s tools and Cloudflare R2 can be used together to address these challenges. First, with MosaicML’s open source <a href="https://github.com/mosaicml/streaming">StreamingDataset</a> and <a href="https://github.com/mosaicml/composer">Composer</a> libraries, you can easily stream in training data and read/write model checkpoints back to R2. All you need is an Internet connection. Second, thanks to R2’s zero-egress pricing, you can start/stop/move/resize jobs in response to GPU availability and prices across compute providers, without paying any data transfer fees. The MosaicML training platform makes it dead simple to orchestrate such training jobs across multiple clouds.</p><p>Together, Cloudflare and MosaicML give you the freedom to train LLMs on <i>any</i> compute, <i>anywhere</i> in the world, with zero switching costs. That means faster, cheaper training runs, and no vendor lock in :)</p><blockquote><p><i>“With the MosaicML training platform, customers can efficiently use R2 as the durable storage backend for training LLMs on any compute provider with zero egress fees. AI companies are facing outrageous cloud costs, and they are on the hunt for the tools that can provide them with the speed and flexibility to train their best model at the best price.”</i> – <b>Naveen Rao, CEO and co-founder, MosaicML</b></p></blockquote>
    <div>
      <h3>Reading data from R2 using StreamingDataset</h3>
      <a href="#reading-data-from-r2-using-streamingdataset">
        
      </a>
    </div>
    <p>To read data from R2 efficiently and deterministically, you can use the MosaicML <a href="https://github.com/mosaicml/streaming">StreamingDataset</a> library. First, write your training data (images, text, video, anything!) into <code>.mds</code> shard files using the provided Python API:</p>
            <pre><code>import numpy as np
from PIL import Image
from streaming import MDSWriter

# Local or remote directory in which to store the compressed output files
data_dir = 'path-to-dataset'

# A dictionary mapping input fields to their data types
columns = {
    'image': 'jpeg',
    'class': 'int'
}

# Shard compression, if any
compression = 'zstd'

# Save the samples as shards using MDSWriter
with MDSWriter(out=data_dir, columns=columns, compression=compression) as out:
    for i in range(10000):
        sample = {
            'image': Image.fromarray(np.random.randint(0, 256, (32, 32, 3), np.uint8)),
            'class': np.random.randint(10),
        }
        out.write(sample)</code></pre>
            <p>After your dataset has been converted, you can upload it to R2. Below we demonstrate this with the <code>awscli</code> command line tool, but you can also use `wrangler `or any <a href="https://www.cloudflare.com/developer-platform/solutions/s3-compatible-object-storage/">S3-compatible tool</a> of your choice. StreamingDataset will also support direct cloud writing to R2 soon!</p>
            <pre><code>$ aws s3 cp --recursive path-to-dataset s3://my-bucket/folder --endpoint-url $S3_ENDPOINT_URL</code></pre>
            <p>Finally, you can read the data into any device that has read access to your R2 bucket. You can fetch individual samples, loop over the dataset, and feed it into a standard PyTorch dataloader.</p>
            <pre><code>from torch.utils.data import DataLoader
from streaming import StreamingDataset

# Make sure that R2 credentials and $S3_ENDPOINT_URL are set in your environment    
# e.g. export S3_ENDPOINT_URL="https://[uid].r2.cloudflarestorage.com"

# Remote path where full dataset is persistently stored
remote = 's3://my-bucket/folder'

# Local working dir where dataset is cached during operation
local = '/tmp/path-to-dataset'

# Create streaming dataset
dataset = StreamingDataset(local=local, remote=remote, shuffle=True)

# Let's see what is in sample #1337...
sample = dataset[1337]
img = sample['image']
cls = sample['class']

# Create PyTorch DataLoader
dataloader = DataLoader(dataset)</code></pre>
            <p>StreamingDataset comes out of the box with high performance, elastic determinism, fast resumption, and multi-worker support. It also uses smart shuffling and distribution to ensure that download bandwidth is minimized. Across a variety of workloads such as LLMs and diffusion models, we find that there is no impact on training throughput (no dataloader bottleneck) when training from object stores like R2. For more information, check out the StreamingDataset <a href="https://www.mosaicml.com/blog/mosaicml-streamingdataset">announcement blog</a>!</p>
    <div>
      <h3>Reading/writing model checkpoints to R2 using Composer</h3>
      <a href="#reading-writing-model-checkpoints-to-r2-using-composer">
        
      </a>
    </div>
    <p>Streaming data into your training loop solves half of the problem, but how do you load/save your model checkpoints? Luckily, if you use a training library like <a href="https://github.com/mosaicml/composer">Composer</a>, it’s as easy as pointing at an R2 path!</p>
            <pre><code>from composer import Trainer
...

# Make sure that R2 credentials and $S3_ENDPOINT_URL are set in your environment
# e.g. export S3_ENDPOINT_URL="https://[uid].r2.cloudflarestorage.com"

trainer = Trainer(
        run_name='mpt-7b',
        model=model,
        train_dataloader=train_loader,
        ...
        save_folder=s3://my-bucket/mpt-7b/checkpoints,
        save_interval='1000ba',
        # load_path=s3://my-bucket/mpt-7b-prev/checkpoints/ep0-ba100-rank0.pt,
    )</code></pre>
            <p>Composer uses asynchronous uploads to minimize wait time as checkpoints are being saved during training. It also works out of the box with multi-GPU and multi-node training, and <b>does not require a shared file system.</b> This means you can skip setting up an expensive EFS/NFS system for your compute cluster, saving thousands of dollars or more per month on public clouds. All you need is an Internet connection and appropriate credentials – your checkpoints arrive safely in your R2 bucket giving you scalable and secure storage for your private models.</p>
    <div>
      <h3>Using MosaicML and R2 to train anywhere efficiently</h3>
      <a href="#using-mosaicml-and-r2-to-train-anywhere-efficiently">
        
      </a>
    </div>
    <p>Using the above tools together with Cloudflare R2 enables users to run training workloads on any compute provider, with total freedom and zero switching costs.</p><p>As a demonstration, in Figure X we use the MosaicML training platform to launch an LLM training job starting on Oracle Cloud Infrastructure, with data streaming in and checkpoints uploaded back to R2. Part way through, we pause the job and seamlessly resume on a different set of GPUs on Amazon Web Services. Composer loads the model weights from the last saved checkpoint in R2, and the streaming dataloader instantly resumes to the correct batch. Training continues deterministically. Finally, we move again to Google Cloud to finish the run.</p><p>As we train our LLM across three cloud providers, the only costs we pay are for GPU compute and data storage. No egress fees or lock in thanks to Cloudflare R2!</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/6d7rJLiQ1wI12thUIr792s/2eacae82cc201106faed1af1b079b4d2/image2-19.png" />
            
            </figure><p><i>Using the MosaicML training platform with Cloudflare R2 to run an LLM training job across three different cloud providers, with zero egress fees.</i></p>
            <pre><code>$ mcli get clusters
NAME            PROVIDER      GPU_TYPE   GPUS             INSTANCE                   NODES
mml-1            MosaicML   │  a100_80gb  8             │  mosaic.a100-80sxm.1        1    
                            │  none       0             │  cpu                        1    
gcp-1            GCP        │  t4         -             │  n1-standard-48-t4-4        -    
                            │  a100_40gb  -             │  a2-highgpu-8g              -    
                            │  none       0             │  cpu                        1    
aws-1            AWS        │  a100_40gb  ≤8,16,...,32  │  p4d.24xlarge               ≤4   
                            │  none       0             │  cpu                        1    
oci-1            OCI        │  a100_40gb  8,16,...,64   │  oci.bm.gpu.b4.8            ≤8  
                            │  none       0             │  cpu                        1    

$ mcli create secret s3 --name r2-creds --config-file path/to/config --credentials-file path/to/credentials
✔  Created s3 secret: r2-creds      

$ mcli create secret env S3_ENDPOINT_URL="https://[uid].r2.cloudflarestorage.com"
✔  Created environment secret: s3-endpoint-url      
               
$ mcli run -f mpt-125m-r2.yaml --follow
✔  Run mpt-125m-r2-X2k3Uq started                                                                                    
i  Following run logs. Press Ctrl+C to quit.                                                                            
                                                                                                                        
Cloning into 'llm-foundry'...</code></pre>
            <p><i>Using the MCLI command line tool to manage compute clusters, secrets, and submit runs.</i></p>
            <pre><code>### mpt-125m-r2.yaml ###
# set up secrets once with `mcli create secret ...`
# and they will be present in the environment in any subsequent run

integrations:
- integration_type: git_repo
  git_repo: mosaicml/llm-foundry
  git_branch: main
  pip_install: -e .[gpu]

image: mosaicml/pytorch:1.13.1_cu117-python3.10-ubuntu20.04

command: |
  cd llm-foundry/scripts
  composer train/train.py train/yamls/mpt/125m.yaml \
    data_remote=s3://bucket/path-to-data \
    max_duration=100ba \
    save_folder=s3://checkpoints/mpt-125m \
    save_interval=20ba

run_name: mpt-125m-r2

gpu_num: 8
gpu_type: a100_40gb
cluster: oci-1  # can be any compute cluster!</code></pre>
            <p><i>An MCLI job template. Specify a run name, a Docker image, a set of commands, and a compute cluster to run on.</i></p>
    <div>
      <h3>Get started today!</h3>
      <a href="#get-started-today">
        
      </a>
    </div>
    <p>The MosaicML platform is an invaluable tool to take your training to the next level, and in this post, we explored how Cloudflare R2 empowers you to train models on your own data, with any compute provider – or all of them. By eliminating egress fees, R2’s storage is an exceptionally cost-effective complement to MosaicML training, providing maximum autonomy and control. With this combination, you can switch between cloud service providers to fit your organization’s needs over time.</p><p>To learn more about using MosaicML to train custom state-of-the-art AI on your own data visit <a href="https://www.mosaicml.com/">here</a> or <a href="https://docs.google.com/forms/d/e/1FAIpQLSepW7QB3Xkv6T7GJRwrR9DmGAEjm5G2lBxJC7PUe3JXcBZYbw/viewform">get in touch</a>.</p>
    <div>
      <h3>Watch on Cloudflare TV</h3>
      <a href="#watch-on-cloudflare-tv">
        
      </a>
    </div>
    <div></div><p></p> ]]></content:encoded>
            <category><![CDATA[Developer Week]]></category>
            <category><![CDATA[Developers]]></category>
            <category><![CDATA[Partners]]></category>
            <category><![CDATA[Egress]]></category>
            <category><![CDATA[Connectivity Cloud]]></category>
            <category><![CDATA[R2]]></category>
            <category><![CDATA[LLM]]></category>
            <guid isPermaLink="false">4ETryNsT8L8QFX8tPNzeye</guid>
            <dc:creator>Abhinav Venigalla (Guest Author)</dc:creator>
            <dc:creator>Phillip Jones</dc:creator>
            <dc:creator>Abhi Das</dc:creator>
        </item>
        <item>
            <title><![CDATA[The S3 to R2 Super Slurper is now Generally Available]]></title>
            <link>https://blog.cloudflare.com/r2-super-slurper-ga/</link>
            <pubDate>Tue, 16 May 2023 13:00:50 GMT</pubDate>
            <description><![CDATA[ Use Super Slurper to quickly, securely, and easily migrate data from S3 to R2. ]]></description>
            <content:encoded><![CDATA[ <p></p><p>R2 is Cloudflare’s zero <a href="https://www.cloudflare.com/learning/cloud/what-are-data-egress-fees/">egress fee</a> <a href="https://www.cloudflare.com/developer-platform/products/r2/">object storage platform</a>. One of the things that developers love about R2 is how easy it is to get started. With R2’s <a href="https://www.cloudflare.com/developer-platform/solutions/s3-compatible-object-storage/">S3-compatible API</a>, integrating R2 into existing applications only requires changing a couple of lines of code.</p><p>However, migrating data from other <a href="https://www.cloudflare.com/learning/cloud/what-is-object-storage/">object storage</a> providers into R2 can still be a challenge. To address this issue, we introduced the beta of <a href="/cloudflare-r2-super-slurper/">R2 Super Slurper</a> late last year. During the beta period, we’ve been able to partner with early adopters on hundreds of successful migrations from S3 to <a href="www.cloudflare.com/developer-platform/r2/">Cloudflare R2</a>. We’ve made many improvements during the beta including speed (up to 5x increase in the number of objects copied per second!), reliability, and the ability to copy data between R2 buckets. Today, we’re proud to announce the general availability of Super Slurper for one-time migration, making <a href="https://www.cloudflare.com/learning/cloud/what-is-data-migration/">data migration</a> a breeze!</p>
    <div>
      <h2>Data migration that’s fast, reliable, and easy to use</h2>
      <a href="#data-migration-thats-fast-reliable-and-easy-to-use">
        
      </a>
    </div>
    <p>R2 Super Slurper one-time migration allows you to quickly and easily copy objects from S3 to an R2 bucket of your choice.</p>
    <div>
      <h3>Fast</h3>
      <a href="#fast">
        
      </a>
    </div>
    <p>Super Slurper copies objects from your S3 buckets in parallel and uses Cloudflare’s global network to tap into vast amounts of bandwidth to ensure migrations finish fast.</p><blockquote><p>This migration tool is impressively fast! We expected our migration to take a day to complete, but we were able to move all of our data in less than half an hour. - <b>Nick Inhofe</b>, Engineering Manager at <a href="https://www.pdq.com/">PDQ</a></p></blockquote>
    <div>
      <h3>Reliable</h3>
      <a href="#reliable">
        
      </a>
    </div>
    <p>Sending objects through the Internet can sometimes fail. R2 Super Slurper accounts for that, and is capable of driving multi-terabyte migrations to completion with robust retries of failed transfers. Additionally, larger objects are transferred in chunks, so if something goes wrong, it only retries the portion of the object that’s needed. This means faster migrations and <a href="https://r2-calculator.cloudflare.com/">lower cost</a>. And if for some reason an object just won’t transfer, it gets logged, so you can keep track and sort it out later.</p>
    <div>
      <h3>Easy to use</h3>
      <a href="#easy-to-use">
        
      </a>
    </div>
    <p>R2 Super Slurper simplifies the process of copying objects and their associated metadata from S3 to your R2 buckets. Point Super Slurper to your S3 buckets and an asynchronous task will handle the rest. While the migration is taking place, you can follow along from the dashboard.</p><blockquote><p>R2 has saved us both time and money. We migrated millions of images in a short period of time. It wouldn't have been possible for us to build a tool to migrate our data in this amount of time in a cost-effective way. - <b>Damien Capocchi</b>, Backend Engineering Manager at <a href="https://reelgood.com/">Reelgood</a></p></blockquote>
    <div>
      <h2>Migrate your S3 data into R2</h2>
      <a href="#migrate-your-s3-data-into-r2">
        
      </a>
    </div>
    <ol><li><p>From the Cloudflare dashboard, expand <b>R2</b> and select <b>Data Migration</b>.</p></li><li><p>Select <b>Migrate files</b>.</p></li><li><p>Enter your Amazon S3 bucket name, optional bucket prefix, and associated credentials and select <b>Next</b>.</p></li><li><p>Enter your R2 bucket name and associated credentials and select <b>Next</b>.</p></li><li><p>After you finish reviewing the details of your migration, select <b>Migrate files</b>.</p></li></ol>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/1qo4qeK1OqM0xTKm6RbBWy/0ac3f85a6833194a585a66a1d3880524/image1-32.png" />
            
            </figure><p>You can view the status of your migration job at any time on the dashboard. If you want to copy data from one R2 bucket to another R2 bucket, you can select Cloudflare R2 as the source bucket provider and follow the same process. For more information on how to use Super Slurper, please see the documentation <a href="https://developers.cloudflare.com/r2/r2-migrator/">here</a>.</p>
    <div>
      <h3>Next up: Incremental migration</h3>
      <a href="#next-up-incremental-migration">
        
      </a>
    </div>
    <p>For the majority of cases, a one-time migration of data from your previous object storage bucket to R2 is sufficient; complete the switch from S3 to R2 and immediately watch egress fees go to zero.</p><p>However, in some cases you may want to migrate data to R2 incrementally over time (sip by sip if you will). Enter incremental migration, allowing you to do just that.</p><p>The goal of incremental migration is to copy files from your origin bucket to R2 as they are requested. When a requested object is not already in the R2 bucket, it is downloaded - one last time - from your origin bucket then copied to R2. From now on, every request for this object will be served by R2, which means less egress fees!</p><p>Since data is migrated all within the flow of normal data access and application logic, this means zero cost overhead of unnecessary egress fees! Previously complicated migrations become as easy as replacing your S3 endpoint in your application.</p>
    <div>
      <h3>Join the private beta waitlist for incremental migration</h3>
      <a href="#join-the-private-beta-waitlist-for-incremental-migration">
        
      </a>
    </div>
    <p>We’re excited about our progress making data migration easier, but we’re just getting started. If you’re interested in participating in the private beta for Super Slurper incremental migration, let us know by joining the waitlist <a href="https://forms.gle/9xvDLR8LL1Pt8rF58">here</a>.</p><p>We encourage you to join our <a href="https://discord.cloudflare.com/">Discord community</a> to share your R2 experiences, questions, and feedback!</p>
    <div>
      <h3>Watch on Cloudflare TV</h3>
      <a href="#watch-on-cloudflare-tv">
        
      </a>
    </div>
    <div></div><p></p> ]]></content:encoded>
            <category><![CDATA[Developer Week]]></category>
            <category><![CDATA[R2]]></category>
            <category><![CDATA[R2 Super Slurper]]></category>
            <guid isPermaLink="false">5rDAs1l1glaZBHaVpPlbSu</guid>
            <dc:creator>Phillip Jones</dc:creator>
            <dc:creator>Jérôme Schneider</dc:creator>
        </item>
        <item>
            <title><![CDATA[Use Snowflake with R2 to extend your global data lake]]></title>
            <link>https://blog.cloudflare.com/snowflake-r2-global-data-lake/</link>
            <pubDate>Tue, 16 May 2023 13:00:42 GMT</pubDate>
            <description><![CDATA[ Joint customers can now use Snowflake with Cloudflare R2 to extend your global data lake without having to worry about egress fee ]]></description>
            <content:encoded><![CDATA[ <p></p><p>R2 is the ideal <a href="https://www.cloudflare.com/developer-platform/products/r2/">object storage platform</a> to build data lakes. It’s infinitely scalable, highly durable (eleven 9's of annual durability), and has no <a href="https://www.cloudflare.com/learning/cloud/what-are-data-egress-fees/">egress fees</a>. Zero egress fees mean zero <a href="https://www.cloudflare.com/learning/cloud/what-is-vendor-lock-in/">vendor lock-in</a>. You are free to use the tools you want to <a href="https://r2-calculator.cloudflare.com/">get the maximum value</a> from your data.</p><p>Today we’re excited to announce our partnership with Snowflake so that you can use <a href="https://www.snowflake.com/">Snowflake</a> to <a href="https://docs.snowflake.com/en/user-guide/querying-stage">query data</a> stored in your R2 data lake and <a href="https://docs.snowflake.com/en/user-guide/data-load-overview">load data</a> from R2 into Snowflake. Organizations use Snowflake's Data Cloud to unite siloed data, discover, and securely share data, and execute diverse analytic workloads across multiple clouds.</p><p>One challenge of loading data into Snowflake database tables and querying external data lakes is the cost of data transfer. If your data is coming from a different cloud or even different region within the same cloud, this typically means you are paying an additional tax for each byte going into Snowflake. Pairing R2 and Snowflake lets you focus on getting valuable insights from your data, <a href="https://www.cloudflare.com/the-net/cloud-egress-fees-challenge-future-ai/">without having to worry about egress fees piling up</a>.</p>
    <div>
      <h2>Getting started</h2>
      <a href="#getting-started">
        
      </a>
    </div>
    
    <div>
      <h3>Sign up for R2 and create an API token</h3>
      <a href="#sign-up-for-r2-and-create-an-api-token">
        
      </a>
    </div>
    <p>If you haven’t already, you’ll need to <a href="https://dash.cloudflare.com/sign-up">sign up</a> for R2 and <a href="https://developers.cloudflare.com/r2/buckets/create-buckets/">create a bucket</a>. You’ll also need to create R2 security credentials for Snowflake following the steps below.</p>
    <div>
      <h3>Generate an R2 token</h3>
      <a href="#generate-an-r2-token">
        
      </a>
    </div>
    <p>1. In the Cloudflare dashboard, select <b>R2</b>.</p><p>2. Select <b>Manage R2 API Tokens</b> on the right side of the dashboard.</p><p>3. Select <b>Create API token</b>.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2E7iZxChjSMK43LTcMx8r8/a8c039e842e45de4e98a93a94a98b430/image1-33.png" />
            
            </figure><p>4. Optionally select the pencil icon or <b>R2 Token</b> text to edit your API token name.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/EsbH4I6yGVnYigCps5zLT/81794bb9022eed5899a07bf0c0ed94b9/image4-9.png" />
            
            </figure><p>5. Under Permissions, select <b>Edit</b>.</p><p>6. Select <b>Create API Token</b>.</p>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/3o7B7Z2iSUFqDluD9NfJE3/731dd54187da8e892ba7d3c8f884d150/image2-18.png" />
            
            </figure><p>You’ll need the Secret <b>Access Key</b> and <b>Access Key ID</b> to create an external stage in Snowflake.</p>
    <div>
      <h3>Creating external stages in Snowflake</h3>
      <a href="#creating-external-stages-in-snowflake">
        
      </a>
    </div>
    <p>In Snowflake, stages refer to the location of data files in <a href="https://www.cloudflare.com/learning/cloud/what-is-object-storage/">object storage</a>. To create an <a href="https://docs.snowflake.com/en/user-guide/data-load-overview.html#label-data-load-overview-external-stages">external stage</a>, you’ll need your bucket name and R2 credentials. Find your <a href="https://developers.cloudflare.com/fundamentals/get-started/basic-tasks/find-account-and-zone-ids/">Cloudflare account ID in the dashboard</a>.</p>
            <pre><code>CREATE STAGE my_r2_stage
  URL = 's3compat://my_bucket/files/'
  ENDPOINT = 'cloudflare_account_id.r2.cloudflarestorage.com'
  CREDENTIALS = (AWS_KEY_ID = '1a2b3c...' AWS_SECRET_KEY = '4x5y6z...')</code></pre>
            <p>Note: You may need to contact your Snowflake account team to enable S3-compatible endpoints in Snowflake. Get more information <a href="https://docs.snowflake.com/en/user-guide/tables-external-s3-compatible">here</a>.</p>
    <div>
      <h3>Loading data into Snowflake</h3>
      <a href="#loading-data-into-snowflake">
        
      </a>
    </div>
    <p>To load data from your R2 data lake into Snowflake, use the <a href="https://docs.snowflake.com/en/sql-reference/sql/copy-into-table.html">COPY INTO </a> command.</p>
            <pre><code>COPY INTO t1
  FROM @my_r2_stage/load/;</code></pre>
            <p>You can flip the table and external stage parameters in the example above to unload data from Snowflake into R2.</p>
    <div>
      <h3>Querying data in R2 with Snowflake</h3>
      <a href="#querying-data-in-r2-with-snowflake">
        
      </a>
    </div>
    <p>You’ll first need to <a href="https://docs.snowflake.com/en/user-guide/tables-external-s3-compatible#creating-external-tables">create an external table</a> in Snowflake. Once you’ve done that you’ll be able to query your data stored in R2.</p>
            <pre><code>SELECT * FROM external_table;</code></pre>
            <p>For more information on how to use R2 and Snowflake together, refer to documentation <a href="https://docs.snowflake.com/en/user-guide/tables-external-s3-compatible">here</a>.</p><blockquote><p>“Data is becoming increasingly the center of every application, process, and business metrics, and is the cornerstone of digital transformation. Working with partners like Cloudflare, we are unlocking value for joint customers around the world by helping save costs and helping maximize customers data investments,” <b>– James Malone, Director of Product Management at Snowflake</b></p></blockquote>
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/4UDRzvX4xvqdqbrQarqqOz/2a0ef8335a691a40d3421299c7de001b/Screenshot-2023-05-16-at-12.57.57.png" />
            
            </figure>
    <div>
      <h2>Have any feedback?</h2>
      <a href="#have-any-feedback">
        
      </a>
    </div>
    <p>We want to hear from you! If you have any feedback on the integration between Cloudflare R2 and Snowflake, please let us know by filling <a href="https://forms.gle/vJc5yjCLEbT7ybWi9">this form</a>.</p><p>Be sure to check our <a href="https://discord.com/invite/cloudflaredev">Discord server</a> to discuss everything R2!</p>
    <div>
      <h3>Watch on Cloudflare TV</h3>
      <a href="#watch-on-cloudflare-tv">
        
      </a>
    </div>
    <div></div><p></p> ]]></content:encoded>
            <category><![CDATA[Developer Week]]></category>
            <category><![CDATA[Developers]]></category>
            <category><![CDATA[Connectivity Cloud]]></category>
            <category><![CDATA[R2]]></category>
            <guid isPermaLink="false">1nXEIJ7KGAZCaOBWo5mUYZ</guid>
            <dc:creator>Phillip Jones</dc:creator>
            <dc:creator>Abhi Das</dc:creator>
        </item>
        <item>
            <title><![CDATA[Introducing Object Lifecycle Management for Cloudflare R2]]></title>
            <link>https://blog.cloudflare.com/introducing-object-lifecycle-management-for-cloudflare-r2/</link>
            <pubDate>Wed, 10 May 2023 13:00:39 GMT</pubDate>
            <description><![CDATA[ We’re excited to announce that Object Lifecycle Management for R2 is generally available, allowing you to effectively manage object expiration, all from the R2 dashboard or via our API ]]></description>
            <content:encoded><![CDATA[ 
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2gYUTS0mGft4UNdyl6azxW/13b7fd11df446836b17c2060d637f36f/R21.png" />
            
            </figure><p>Last year, <a href="/r2-ga/">R2 made its debut</a>, providing developers with <a href="https://www.cloudflare.com/learning/cloud/what-is-object-storage/">object storage</a> while eliminating the burden of <a href="https://www.cloudflare.com/learning/cloud/what-are-data-egress-fees/">egress fees</a>. (For many, egress costs account for <a href="https://twitter.com/CloudflareDev/status/1639281667973033988?s=20">over half of their object storage bills</a>!) Since R2’s launch, tens of thousands of developers have chosen it to store data for many different types of applications.</p><p>But for some applications, data stored in <a href="https://www.cloudflare.com/developer-platform/products/r2/">R2</a> doesn’t need to be retained forever. Over time, as this data grows, it can <a href="https://r2-calculator.cloudflare.com/">unnecessarily lead to higher storage costs</a>. Today, we’re excited to announce that Object Lifecycle Management for R2 is generally available, allowing you to effectively manage object expiration, all from the R2 dashboard or via our API.</p>
    <div>
      <h3>Object Lifecycle Management</h3>
      <a href="#object-lifecycle-management">
        
      </a>
    </div>
    <p>Object lifecycles give you the ability to define rules (up to 1,000) that determine how long objects uploaded to your bucket are kept. For example, by implementing an object lifecycle rule that deletes objects after 30 days, you could automatically delete outdated logs or temporary files. You can also define rules to abort unfinished multipart uploads that are sitting around and contributing to storage costs.</p>
    <div>
      <h3>Getting started with object lifecycles in R2</h3>
      <a href="#getting-started-with-object-lifecycles-in-r2">
        
      </a>
    </div>
    
    <div>
      <h4>Cloudflare dashboard</h4>
      <a href="#cloudflare-dashboard">
        
      </a>
    </div>
    
            <figure>
            
            <img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/2NokpyjDvm1FLghbgfaXLs/48ce0dd4d55e12e942c1d9c3f7603f3a/R22.png" />
            
            </figure><ol><li><p>From the Cloudflare dashboard, select <b>R2</b>.</p></li><li><p>Select your R2 bucket.</p></li><li><p>Navigate to the <b>Settings</b> tab and find the <b>Object lifecycle rules</b> section.</p></li><li><p>Select <b>Add rule</b> to define the name, relevant prefix, and lifecycle actions: delete uploaded objects or abort incomplete multipart uploads.</p></li><li><p>Select <b>Add rule</b> to complete the process.</p></li></ol>
    <div>
      <h4>S3 Compatible API</h4>
      <a href="#s3-compatible-api">
        
      </a>
    </div>
    <p>With R2’s <a href="https://www.cloudflare.com/developer-platform/solutions/s3-compatible-object-storage/">S3-compatible</a> API, it’s easy to apply any existing object lifecycle rules to your R2 buckets.</p><p>Here’s an example of how to configure your R2 bucket’s lifecycle policy using the AWS SDK for JavaScript. To try this out, you’ll need to generate an <a href="https://developers.cloudflare.com/r2/api/s3/tokens/">Access Key</a>.</p>
            <pre><code>import S3 from "aws-sdk/clients/s3.js";

const client = new S3({
  endpoint: `https://${ACCOUNT_ID}.r2.cloudflarestorage.com`,
  credentials: {
    accessKeyId: ACCESS_KEY_ID, //  fill in your own
    secretAccessKey: SECRET_ACCESS_KEY, // fill in your own
  },
  region: "auto",
});

await client
  .putBucketLifecycleConfiguration({
    LifecycleConfiguration: {
      Bucket: "testBucket",
      Rules: [
        // Example: deleting objects by age
        // Delete logs older than 90 days
        {
          ID: "Delete logs after 90 days",
          Filter: {
            Prefix: "logs/",
          },
          Expiration: {
            Days: 90,
          },
        },
        // Example: abort all incomplete multipart uploads after a week
        {
          ID: "Abort incomplete multipart uploads",
          AbortIncompleteMultipartUpload: {
            DaysAfterInitiation: 7,
          },
        },
      ],
    },
  })
  .promise();</code></pre>
            <p>For more information on how object lifecycle policies work and how to configure them in the dashboard or API, see the documentation <a href="https://developers.cloudflare.com/r2/buckets/object-lifecycles/">here</a>.</p><p>Speaking of documentation, if you’d like to provide feedback for R2’s documentation, fill out our <a href="https://docs.google.com/forms/d/e/1FAIpQLScaVrdZh2PoZFvJGFPyMthuGVvKpQvoPfZ-BxIJ4Q5zsQebDA/viewform">documentation survey</a>!</p>
    <div>
      <h3>What’s next?</h3>
      <a href="#whats-next">
        
      </a>
    </div>
    <p>Creating object lifecycle rules to delete ephemeral objects is a great way to reduce storage costs, but what if you need to keep objects around to access in the future? We’re working on new, lower cost ways to store objects in R2 that aren’t frequently accessed, like long tail user-generated content, archive data, and more. If you’re interested in providing feedback and gaining early access, let us know by joining the waitlist <a href="https://forms.gle/JLLzQtqSuLAQNRPX7">here</a>.</p>
    <div>
      <h3>Join the conversation: share your feedback and experiences</h3>
      <a href="#join-the-conversation-share-your-feedback-and-experiences">
        
      </a>
    </div>
    <p>If you have any questions or feedback relating to R2, we encourage you to join our <a href="https://discord.gg/cloudflaredev">Discord community</a> to share! Stay tuned for more exciting R2 updates in the future.</p> ]]></content:encoded>
            <category><![CDATA[Storage]]></category>
            <category><![CDATA[Product News]]></category>
            <category><![CDATA[Developers]]></category>
            <category><![CDATA[R2]]></category>
            <guid isPermaLink="false">2toJKgkVGnaE3gFJUCqFbf</guid>
            <dc:creator>Harshal Brahmbhatt</dc:creator>
            <dc:creator>Phillip Jones</dc:creator>
        </item>
    </channel>
</rss>