This is an automated email from the ASF dual-hosted git repository.

github-bot pushed a commit to branch asf-site
in repository https://gitbox.apache.org/repos/asf/arrow-site.git


The following commit(s) were added to refs/heads/asf-site by this push:
     new 0add55fab87 Updating built site
0add55fab87 is described below

commit 0add55fab87b98a27742257d7744d9b6a76cc063
Author: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
AuthorDate: Thu Oct 23 18:31:48 2025 +0000

    Updating built site
---
 blog/2025/10/23/introducing-arrow-avro/index.html  | 562 +++++++++++++++++++++
 blog/index.html                                    |  20 +
 feed.xml                                           | 335 +++++++++---
 .../arrow-avro-architecture.svg                    |   1 +
 img/introducing-arrow-avro/read_violin_10k.svg     |  79 +++
 img/introducing-arrow-avro/read_violin_1m.svg      |  79 +++
 img/introducing-arrow-avro/write_violin_10k.svg    |  65 +++
 img/introducing-arrow-avro/write_violin_1m.svg     |  71 +++
 8 files changed, 1147 insertions(+), 65 deletions(-)

diff --git a/blog/2025/10/23/introducing-arrow-avro/index.html 
b/blog/2025/10/23/introducing-arrow-avro/index.html
new file mode 100644
index 00000000000..6b57a52a85e
--- /dev/null
+++ b/blog/2025/10/23/introducing-arrow-avro/index.html
@@ -0,0 +1,562 @@
+<!DOCTYPE html>
+<html lang="en-US">
+  <head>
+    <meta charset="UTF-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+    <!-- The above meta tags *must* come first in the head; any other head 
content must come *after* these tags -->
+    
+    <title>Announcing arrow-avro in Arrow Rust | Apache Arrow</title>
+    
+
+    <!-- Begin Jekyll SEO tag v2.8.0 -->
+<meta name="generator" content="Jekyll v4.4.1" />
+<meta property="og:title" content="Announcing arrow-avro in Arrow Rust" />
+<meta name="author" content="jecsand838" />
+<meta property="og:locale" content="en_US" />
+<meta name="description" content="A new native Rust vectorized reader/writer 
for Avro to Arrow, with OCF, Single‑Object, and Confluent wire format support." 
/>
+<meta property="og:description" content="A new native Rust vectorized 
reader/writer for Avro to Arrow, with OCF, Single‑Object, and Confluent wire 
format support." />
+<link rel="canonical" 
href="https://arrow.apache.org/blog/2025/10/23/introducing-arrow-avro/"; />
+<meta property="og:url" 
content="https://arrow.apache.org/blog/2025/10/23/introducing-arrow-avro/"; />
+<meta property="og:site_name" content="Apache Arrow" />
+<meta property="og:image" 
content="https://arrow.apache.org/img/arrow-logo_horizontal_black-txt_white-bg.png";
 />
+<meta property="og:type" content="article" />
+<meta property="article:published_time" content="2025-10-23T00:00:00-04:00" />
+<meta name="twitter:card" content="summary_large_image" />
+<meta property="twitter:image" 
content="https://arrow.apache.org/img/arrow-logo_horizontal_black-txt_white-bg.png";
 />
+<meta property="twitter:title" content="Announcing arrow-avro in Arrow Rust" />
+<script type="application/ld+json">
+{"@context":"https://schema.org","@type":"BlogPosting","author":{"@type":"Person","name":"jecsand838"},"dateModified":"2025-10-23T00:00:00-04:00","datePublished":"2025-10-23T00:00:00-04:00","description":"A
 new native Rust vectorized reader/writer for Avro to Arrow, with OCF, 
Single‑Object, and Confluent wire format support.","headline":"Announcing 
arrow-avro in Arrow 
Rust","image":"https://arrow.apache.org/img/arrow-logo_horizontal_black-txt_white-bg.png","mainEntityOfPage":{"@type":"We
 [...]
+<!-- End Jekyll SEO tag -->
+
+
+    <!-- favicons -->
+    <link rel="icon" type="image/png" sizes="16x16" 
href="/img/favicon-16x16.png" id="light1">
+    <link rel="icon" type="image/png" sizes="32x32" 
href="/img/favicon-32x32.png" id="light2">
+    <link rel="apple-touch-icon" type="image/png" sizes="180x180" 
href="/img/apple-touch-icon.png" id="light3">
+    <link rel="apple-touch-icon" type="image/png" sizes="120x120" 
href="/img/apple-touch-icon-120x120.png" id="light4">
+    <link rel="apple-touch-icon" type="image/png" sizes="76x76" 
href="/img/apple-touch-icon-76x76.png" id="light5">
+    <link rel="apple-touch-icon" type="image/png" sizes="60x60" 
href="/img/apple-touch-icon-60x60.png" id="light6">
+    <!-- dark mode favicons -->
+    <link rel="icon" type="image/png" sizes="16x16" 
href="/img/favicon-16x16-dark.png" id="dark1">
+    <link rel="icon" type="image/png" sizes="32x32" 
href="/img/favicon-32x32-dark.png" id="dark2">
+    <link rel="apple-touch-icon" type="image/png" sizes="180x180" 
href="/img/apple-touch-icon-dark.png" id="dark3">
+    <link rel="apple-touch-icon" type="image/png" sizes="120x120" 
href="/img/apple-touch-icon-120x120-dark.png" id="dark4">
+    <link rel="apple-touch-icon" type="image/png" sizes="76x76" 
href="/img/apple-touch-icon-76x76-dark.png" id="dark5">
+    <link rel="apple-touch-icon" type="image/png" sizes="60x60" 
href="/img/apple-touch-icon-60x60-dark.png" id="dark6">
+
+    <script>
+      // Switch to the dark-mode favicons if prefers-color-scheme: dark
+      function onUpdate() {
+        light1 = document.querySelector('link#light1');
+        light2 = document.querySelector('link#light2');
+        light3 = document.querySelector('link#light3');
+        light4 = document.querySelector('link#light4');
+        light5 = document.querySelector('link#light5');
+        light6 = document.querySelector('link#light6');
+
+        dark1 = document.querySelector('link#dark1');
+        dark2 = document.querySelector('link#dark2');
+        dark3 = document.querySelector('link#dark3');
+        dark4 = document.querySelector('link#dark4');
+        dark5 = document.querySelector('link#dark5');
+        dark6 = document.querySelector('link#dark6');
+
+        if (matcher.matches) {
+          light1.remove();
+          light2.remove();
+          light3.remove();
+          light4.remove();
+          light5.remove();
+          light6.remove();
+          document.head.append(dark1);
+          document.head.append(dark2);
+          document.head.append(dark3);
+          document.head.append(dark4);
+          document.head.append(dark5);
+          document.head.append(dark6);
+        } else {
+          dark1.remove();
+          dark2.remove();
+          dark3.remove();
+          dark4.remove();
+          dark5.remove();
+          dark6.remove();
+          document.head.append(light1);
+          document.head.append(light2);
+          document.head.append(light3);
+          document.head.append(light4);
+          document.head.append(light5);
+          document.head.append(light6);
+        }
+      }
+      matcher = window.matchMedia('(prefers-color-scheme: dark)');
+      matcher.addListener(onUpdate);
+      onUpdate();
+    </script>
+
+    <link href="/css/main.css" rel="stylesheet">
+    <link href="/css/syntax.css" rel="stylesheet">
+    <script src="/javascript/main.js"></script>
+    
+    <!-- Matomo -->
+<script>
+  var _paq = window._paq = window._paq || [];
+  /* tracker methods like "setCustomDimension" should be called before 
"trackPageView" */
+  /* We explicitly disable cookie tracking to avoid privacy issues */
+  _paq.push(['disableCookies']);
+  _paq.push(['trackPageView']);
+  _paq.push(['enableLinkTracking']);
+  (function() {
+    var u="https://analytics.apache.org/";;
+    _paq.push(['setTrackerUrl', u+'matomo.php']);
+    _paq.push(['setSiteId', '20']);
+    var d=document, g=d.createElement('script'), 
s=d.getElementsByTagName('script')[0];
+    g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
+  })();
+</script>
+<!-- End Matomo Code -->
+
+    
+    <link type="application/atom+xml" rel="alternate" 
href="https://arrow.apache.org/feed.xml"; title="Apache Arrow" />
+  </head>
+
+
+<body class="wrap">
+  <header>
+    <nav class="navbar navbar-expand-md navbar-dark bg-dark">
+  
+  <a class="navbar-brand no-padding" href="/"><img 
src="/img/arrow-inverse-300px.png" height="40px"></a>
+  
+   <button class="navbar-toggler ml-auto" type="button" data-toggle="collapse" 
data-target="#arrow-navbar" aria-controls="arrow-navbar" aria-expanded="false" 
aria-label="Toggle navigation">
+    <span class="navbar-toggler-icon"></span>
+  </button>
+
+    <!-- Collect the nav links, forms, and other content for toggling -->
+    <div class="collapse navbar-collapse justify-content-end" 
id="arrow-navbar">
+      <ul class="nav navbar-nav">
+        <li class="nav-item"><a class="nav-link" href="/overview/" 
role="button" aria-haspopup="true" aria-expanded="false">Overview</a></li>
+        <li class="nav-item"><a class="nav-link" href="/faq/" role="button" 
aria-haspopup="true" aria-expanded="false">FAQ</a></li>
+        <li class="nav-item"><a class="nav-link" href="/blog" role="button" 
aria-haspopup="true" aria-expanded="false">Blog</a></li>
+        <li class="nav-item dropdown">
+          <a class="nav-link dropdown-toggle" href="#" 
id="navbarDropdownGetArrow" role="button" data-toggle="dropdown" 
aria-haspopup="true" aria-expanded="false">
+             Get Arrow
+          </a>
+          <div class="dropdown-menu" aria-labelledby="navbarDropdownGetArrow">
+            <a class="dropdown-item" href="/install/">Install</a>
+            <a class="dropdown-item" href="/release/">Releases</a>
+          </div>
+        </li>
+        <li class="nav-item dropdown">
+          <a class="nav-link dropdown-toggle" href="#" 
id="navbarDropdownDocumentation" role="button" data-toggle="dropdown" 
aria-haspopup="true" aria-expanded="false">
+             Docs
+          </a>
+          <div class="dropdown-menu" 
aria-labelledby="navbarDropdownDocumentation">
+            <a class="dropdown-item" href="/docs">Project Docs</a>
+            <a class="dropdown-item" 
href="/docs/format/Columnar.html">Format</a>
+            <hr>
+            <a class="dropdown-item" href="/docs/c_glib">C GLib</a>
+            <a class="dropdown-item" href="/docs/cpp">C++</a>
+            <a class="dropdown-item" 
href="https://github.com/apache/arrow/blob/main/csharp/README.md"; 
target="_blank" rel="noopener">C#</a>
+            <a class="dropdown-item" 
href="https://godoc.org/github.com/apache/arrow/go/arrow"; target="_blank" 
rel="noopener">Go</a>
+            <a class="dropdown-item" href="/docs/java">Java</a>
+            <a class="dropdown-item" href="/docs/js">JavaScript</a>
+            <a class="dropdown-item" href="/julia/">Julia</a>
+            <a class="dropdown-item" 
href="https://github.com/apache/arrow/blob/main/matlab/README.md"; 
target="_blank" rel="noopener">MATLAB</a>
+            <a class="dropdown-item" href="/docs/python">Python</a>
+            <a class="dropdown-item" href="/docs/r">R</a>
+            <a class="dropdown-item" 
href="https://github.com/apache/arrow/blob/main/ruby/README.md"; target="_blank" 
rel="noopener">Ruby</a>
+            <a class="dropdown-item" href="https://docs.rs/arrow/latest"; 
target="_blank" rel="noopener">Rust</a>
+            <a class="dropdown-item" href="/swift">Swift</a>
+          </div>
+        </li>
+        <li class="nav-item dropdown">
+          <a class="nav-link dropdown-toggle" href="#" 
id="navbarDropdownSource" role="button" data-toggle="dropdown" 
aria-haspopup="true" aria-expanded="false">
+             Source
+          </a>
+          <div class="dropdown-menu" aria-labelledby="navbarDropdownSource">
+            <a class="dropdown-item" href="https://github.com/apache/arrow"; 
target="_blank" rel="noopener">Main Repo</a>
+            <hr>
+            <a class="dropdown-item" 
href="https://github.com/apache/arrow/tree/main/c_glib"; target="_blank" 
rel="noopener">C GLib</a>
+            <a class="dropdown-item" 
href="https://github.com/apache/arrow/tree/main/cpp"; target="_blank" 
rel="noopener">C++</a>
+            <a class="dropdown-item" 
href="https://github.com/apache/arrow/tree/main/csharp"; target="_blank" 
rel="noopener">C#</a>
+            <a class="dropdown-item" href="https://github.com/apache/arrow-go"; 
target="_blank" rel="noopener">Go</a>
+            <a class="dropdown-item" 
href="https://github.com/apache/arrow-java"; target="_blank" 
rel="noopener">Java</a>
+            <a class="dropdown-item" href="https://github.com/apache/arrow-js"; 
target="_blank" rel="noopener">JavaScript</a>
+            <a class="dropdown-item" 
href="https://github.com/apache/arrow-julia"; target="_blank" 
rel="noopener">Julia</a>
+            <a class="dropdown-item" 
href="https://github.com/apache/arrow/tree/main/matlab"; target="_blank" 
rel="noopener">MATLAB</a>
+            <a class="dropdown-item" 
href="https://github.com/apache/arrow/tree/main/python"; target="_blank" 
rel="noopener">Python</a>
+            <a class="dropdown-item" 
href="https://github.com/apache/arrow/tree/main/r"; target="_blank" 
rel="noopener">R</a>
+            <a class="dropdown-item" 
href="https://github.com/apache/arrow/tree/main/ruby"; target="_blank" 
rel="noopener">Ruby</a>
+            <a class="dropdown-item" href="https://github.com/apache/arrow-rs"; 
target="_blank" rel="noopener">Rust</a>
+            <a class="dropdown-item" 
href="https://github.com/apache/arrow-swift"; target="_blank" 
rel="noopener">Swift</a>
+          </div>
+        </li>
+        <li class="nav-item dropdown">
+          <a class="nav-link dropdown-toggle" href="#" 
id="navbarDropdownSubprojects" role="button" data-toggle="dropdown" 
aria-haspopup="true" aria-expanded="false">
+             Subprojects
+          </a>
+          <div class="dropdown-menu" 
aria-labelledby="navbarDropdownSubprojects">
+            <a class="dropdown-item" href="/adbc">ADBC</a>
+            <a class="dropdown-item" href="/docs/format/Flight.html">Arrow 
Flight</a>
+            <a class="dropdown-item" href="/docs/format/FlightSql.html">Arrow 
Flight SQL</a>
+            <a class="dropdown-item" href="https://datafusion.apache.org"; 
target="_blank" rel="noopener">DataFusion</a>
+            <a class="dropdown-item" href="/nanoarrow">nanoarrow</a>
+          </div>
+        </li>
+        <li class="nav-item dropdown">
+          <a class="nav-link dropdown-toggle" href="#" 
id="navbarDropdownCommunity" role="button" data-toggle="dropdown" 
aria-haspopup="true" aria-expanded="false">
+             Community
+          </a>
+          <div class="dropdown-menu" aria-labelledby="navbarDropdownCommunity">
+            <a class="dropdown-item" href="/community/">Communication</a>
+            <a class="dropdown-item" 
href="/docs/developers/index.html">Contributing</a>
+            <a class="dropdown-item" 
href="https://github.com/apache/arrow/issues"; target="_blank" 
rel="noopener">Issue Tracker</a>
+            <a class="dropdown-item" href="/committers/">Governance</a>
+            <a class="dropdown-item" href="/use_cases/">Use Cases</a>
+            <a class="dropdown-item" href="/powered_by/">Powered By</a>
+            <a class="dropdown-item" href="/visual_identity/">Visual 
Identity</a>
+            <a class="dropdown-item" href="/security/">Security</a>
+            <a class="dropdown-item" 
href="https://www.apache.org/foundation/policies/conduct.html"; target="_blank" 
rel="noopener">Code of Conduct</a>
+          </div>
+        </li>
+        <li class="nav-item dropdown">
+          <a class="nav-link dropdown-toggle" href="#" id="navbarDropdownASF" 
role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+             ASF Links
+          </a>
+          <div class="dropdown-menu dropdown-menu-right" 
aria-labelledby="navbarDropdownASF">
+            <a class="dropdown-item" href="https://www.apache.org/"; 
target="_blank" rel="noopener">ASF Website</a>
+            <a class="dropdown-item" href="https://www.apache.org/licenses/"; 
target="_blank" rel="noopener">License</a>
+            <a class="dropdown-item" 
href="https://www.apache.org/foundation/sponsorship.html"; target="_blank" 
rel="noopener">Donate</a>
+            <a class="dropdown-item" 
href="https://www.apache.org/foundation/thanks.html"; target="_blank" 
rel="noopener">Thanks</a>
+            <a class="dropdown-item" href="https://www.apache.org/security/"; 
target="_blank" rel="noopener">Security</a>
+          </div>
+        </li>
+      </ul>
+    </div>
+<!-- /.navbar-collapse -->
+  </nav>
+
+  </header>
+
+  <div class="container p-4 pt-5">
+    <div class="col-md-8 mx-auto">
+      <main role="main" class="pb-5">
+        
+<h1>
+  Announcing arrow-avro in Arrow Rust
+</h1>
+<hr class="mt-4 mb-3">
+
+
+
+<p class="mb-4 pb-1">
+  <span class="badge badge-secondary">Published</span>
+  <span class="published mr-3">
+    23 Oct 2025
+  </span>
+  <br>
+  <span class="badge badge-secondary">By</span>
+  
+    <a class="mr-3" href="https://github.com/jecsand838"; target="_blank" 
rel="noopener">Connor Sanders (jecsand838) </a>
+  
+
+  
+</p>
+
+
+        <!--
+
+-->
+<p><a href="https://crates.io/crates/arrow-avro"; target="_blank" 
rel="noopener"><code>arrow-avro</code></a>, a newly rewritten Rust crate that 
reads and writes <a href="https://avro.apache.org/"; target="_blank" 
rel="noopener">Apache Avro</a> data directly as Arrow 
<code>RecordBatch</code>es, is now available. It supports <a 
href="https://avro.apache.org/docs/1.11.1/specification/#object-container-files";
 target="_blank" rel="noopener">Avro Object Container Files</a> (OCF), <a 
href="https: [...]
+<h2>Motivation</h2>
+<p>Apache Avro’s row‑oriented design is effective for encoding one record at a 
time, while Apache Arrow’s columnar layout is optimized for vectorized 
analytics. A major challenge lies in converting between these formats without 
reintroducing row‑wise overhead. Decoding Avro a row at a time and then 
building Arrow arrays incurs extra allocations and cache‑unfriendly access (the 
very costs Arrow is designed to avoid). In the real world, this overhead 
commonly shows up in analytical hot pat [...]
+<h3>Why not use the existing <code>apache-avro</code> crate?</h3>
+<p>Rust already has a mature, general‑purpose Avro crate, <a 
href="https://crates.io/crates/apache-avro"; target="_blank" 
rel="noopener">apache-avro</a>. It reads and writes Avro records as Avro value 
types and provides Object Container File readers and writers. What it does not 
do is decode directly into Arrow arrays, so any Arrow integration must 
materialize rows and then build columns.</p>
+<p>What’s needed is a complementary approach that decodes column‑by‑column 
straight into Arrow builders and emits <code>RecordBatch</code>es. This would 
enable projection pushdown while keeping execution vectorized end to end. For 
projects such as <a href="https://datafusion.apache.org/"; target="_blank" 
rel="noopener">Apache DataFusion</a>, access to a mature, upstream Arrow‑native 
reader and writer would help simplify the code path and reduce duplication.</p>
+<p>Modern pipelines heighten this need because <a 
href="https://www.confluent.io/blog/avro-kafka-data/"; target="_blank" 
rel="noopener">Avro is also used on the wire</a>, not just in files. Kafka 
ecosystems commonly use Confluent’s Schema Registry framing, and many services 
adopt the Avro Single‑Object Encoding format. An approach that enables decoding 
straight into Arrow batches (rather than through per‑row values) would let 
downstream compute remain vectorized at streaming rates.</p>
+<h3>Why this matters</h3>
+<p>Apache Avro is a first‑class format across stream processors and cloud 
services:</p>
+<ul>
+<li>Confluent Schema Registry supports <a 
href="https://docs.confluent.io/platform/current/schema-registry/fundamentals/serdes-develop/serdes-avro.html";
 target="_blank" rel="noopener">Avro across multiple languages and 
tooling</a>.</li>
+<li>Apache Flink exposes an <a 
href="https://nightlies.apache.org/flink/flink-docs-release-1.19/docs/connectors/table/formats/avro-confluent/";
 target="_blank" rel="noopener"><code>avro-confluent</code> format for 
Kafka</a>.</li>
+<li>AWS Lambda <a 
href="https://aws.amazon.com/about-aws/whats-new/2025/06/aws-lambda-native-support-avro-protobuf-kafka-events/";
 target="_blank" rel="noopener">(June 2025) added native handling for 
Avro‑formatted Kafka events</a> with Glue and Confluent Schema Registry 
integrations.</li>
+<li>Azure Event Hubs provides a <a 
href="https://learn.microsoft.com/en-us/azure/event-hubs/schema-registry-overview";
 target="_blank" rel="noopener">Schema Registry with Avro support</a> for 
Kafka‑compatible clients.</li>
+</ul>
+<p>In short: Arrow users encounter Avro both on disk (OCF) and on the wire 
(SOE). An Arrow‑first, vectorized reader/writer for OCF, SOE, and Confluent 
framing removes a pervasive bottleneck and keeps pipelines columnar 
end‑to‑end.</p>
+<h2>Introducing <code>arrow-avro</code>
+</h2>
+<p><a href="https://github.com/apache/arrow-rs/tree/main/arrow-avro"; 
target="_blank" rel="noopener"><code>arrow-avro</code></a> is a 
high-performance Rust crate that converts between Avro and Arrow with a 
column‑first, batch‑oriented design. On the read side, it decodes Avro Object 
Container Files (OCF), Single‑Object Encoding (SOE), and the Confluent Schema 
Registry wire format directly into Arrow <code>RecordBatch</code>es. Meanwhile, 
the write path provides formats for encoding to OCF [...]
+<p>The crate exposes two primary read APIs: a high-level <code>Reader</code> 
for OCF inputs and a low-level <code>Decoder</code> for streaming SOE frames. 
For SOE and Confluent/Apicurio frames, a <code>SchemaStore</code> is provided 
that resolves fingerprints or schema IDs to full Avro writer schemas, enabling 
schema evolution while keeping the decode path vectorized.</p>
+<p>On the write side, <code>AvroWriter</code> produces OCF (including 
container‑level compression), while <code>AvroStreamWriter</code> produces 
framed Avro messages for Single‑Object or Confluent/Apicurio encodings, as 
configured via the <code>WriterBuilder::with_fingerprint_strategy(...)</code> 
knob.</p>
+<p>Configuration is intentionally minimal but practical. For instance, the 
<code>ReaderBuilder</code> exposes knobs covering both batch file ingestion and 
streaming systems without forcing format‑specific code paths.</p>
+<h3>How this mirrors Parquet in Arrow‑rs</h3>
+<p>If you have used Parquet with Arrow‑rs, you already know the pattern. The 
<code>parquet</code> crate exposes a <a 
href="https://docs.rs/parquet/latest/parquet/arrow/index.html"; target="_blank" 
rel="noopener">parquet::arrow module</a> that reads and writes Arrow 
<code>RecordBatch</code>es directly. Most users reach for 
<code>ParquetRecordBatchReaderBuilder</code> when reading and 
<code>ArrowWriter</code> when writing. You choose columns up front, set a batch 
size, and the reader gives  [...]
+<p><code>arrow‑avro</code> brings that same bridge to Avro. You get a single 
<code>ReaderBuilder</code> that can produce a <code>Reader</code> for OCF, or a 
streaming <code>Decoder</code> for on‑the‑wire frames. Both return Arrow 
<code>RecordBatch</code>es, which means engines can keep projection and 
filtering close to the reader and avoid building rows only to reassemble them 
back into columns later. For evolving streams, a small <code>SchemaStore</code> 
resolves fingerprints or ids bef [...]
+<p>The reason this pattern matters is straightforward. Arrow’s columnar format 
is designed for vectorized work and good cache locality. When a format reader 
produces Arrow batches directly, copies and branchy per‑row work are minimized, 
keeping downstream operators fast. That is the same story that made 
<code>parquet::arrow</code> popular in Rust, and it is what 
<code>arrow‑avro</code> now enables for Avro.</p>
+<h2>Architecture &amp; Technical Overview</h2>
+<div style="display: flex; gap: 16px; justify-content: center; align-items: 
flex-start; padding: 20px 15px;">
+<img src="/img/introducing-arrow-avro/arrow-avro-architecture.svg" 
width="100%" alt="High-level `arrow-avro` architecture" style="background:#fff">
+</div>
+<p>At a high level, <a 
href="https://arrow.apache.org/rust/arrow_avro/index.html";>arrow-avro</a> 
splits cleanly into read and write paths built around Arrow 
<code>RecordBatch</code>es. The read side turns Avro (OCF files or framed byte 
streams) into batched Arrow arrays, while the write side takes Arrow batches 
and produces OCF files or streaming frames. When using an 
<code>AvroStreamWriter</code>, the framing (SOE or Confluent) is part of the 
stream output based on the configured finger [...]
+<p>On the <a 
href="https://arrow.apache.org/rust/arrow_avro/reader/index.html";>read</a> 
path, everything starts with the <a 
href="https://arrow.apache.org/rust/arrow_avro/reader/struct.ReaderBuilder.html";>ReaderBuilder</a>.
 A single builder can create a <a 
href="https://arrow.apache.org/rust/arrow_avro/reader/struct.Reader.html";>Reader</a>
 for Object Container Files (OCF) or a streaming <a 
href="https://arrow.apache.org/rust/arrow_avro/reader/struct.Decoder.html";>Decoder</a>
 for SOE/Conf [...]
+<p>When reading an OCF, the <code>Reader</code> parses a header and then 
iterates over blocks of encoded data. The header contains a metadata map with 
the embedded Avro schema and optional compression (i.e., <code>deflate</code>, 
<code>snappy</code>, <code>zstd</code>, <code>bzip2</code>, <code>xz</code>), 
plus a 16‑byte sync marker used to delimit blocks. Each subsequent OCF block 
then carries a row count and the encoded payload. The parsed OCF header and 
block structures are also encod [...]
+<p>On the <a 
href="https://arrow.apache.org/rust/arrow_avro/writer/index.html";>write</a> 
path, the <a 
href="https://arrow.apache.org/rust/arrow_avro/writer/struct.WriterBuilder.html";>WriterBuilder</a>
 produces either an <a 
href="https://arrow.apache.org/rust/arrow_avro/writer/type.AvroWriter.html";>AvroWriter</a>
 (OCF) or an <a 
href="https://arrow.apache.org/rust/arrow_avro/writer/type.AvroStreamWriter.html";>AvroStreamWriter</a>
 (SOE/Message). The <code>with_compression(...)</code> knob i [...]
+<p>Schema handling is centralized in the <a 
href="https://arrow.apache.org/rust/arrow_avro/schema/index.html";>schema</a> 
module. <a 
href="https://arrow.apache.org/rust/arrow_avro/schema/struct.AvroSchema.html";>AvroSchema</a>
 wraps a valid Avro Schema JSON string, supports computing a 
<code>Fingerprint</code>, and can be loaded into a <a 
href="https://arrow.apache.org/rust/arrow_avro/schema/struct.SchemaStore.html";>SchemaStore</a>
 as a writer schema. At runtime, the <code>Reader</code>/<c [...]
+<p>At the heart of <code>arrow-avro</code> is a type‑mapping 
<code>Codec</code> that the library uses to construct both encoders and 
decoders. The <code>Codec</code> captures, for every Avro field, how it maps to 
Arrow and how it should be encoded or decoded. The <code>Reader</code> logic 
builds a <code>Codec</code> per <em>(writer, reader)</em> schema pair, which 
the decoder later uses to vectorize parsing of Avro values directly into the 
correct Arrow builders. The <code>Writer</code>  [...]
+<p>Finally, by keeping container and stream framing (OCF vs. SOE) separate 
from encoding and decoding, the crate composes naturally with the rest of 
Arrow‑rs: you read or write Arrow <code>RecordBatch</code>es, pick OCF or SOE 
streams as needed, and wire up fingerprints only when you're on a streaming 
path. This results in a compact API surface that covers both batch files and 
high‑throughput streams without sacrificing columnar, vectorized execution.</p>
+<h2>Examples</h2>
+<h3>Decoding a Confluent-framed Kafka Stream</h3>
+<div class="language-rust highlighter-rouge"><div class="highlight"><pre 
class="highlight"><code data-lang="rust"><span class="k">use</span> <span 
class="nn">arrow_avro</span><span class="p">::</span><span 
class="nn">reader</span><span class="p">::</span><span 
class="n">ReaderBuilder</span><span class="p">;</span>
+<span class="k">use</span> <span class="nn">arrow_avro</span><span 
class="p">::</span><span class="nn">schema</span><span class="p">::{</span>
+    <span class="n">SchemaStore</span><span class="p">,</span> <span 
class="n">AvroSchema</span><span class="p">,</span> <span 
class="n">Fingerprint</span><span class="p">,</span> <span 
class="n">FingerprintAlgorithm</span><span class="p">,</span> <span 
class="n">CONFLUENT_MAGIC</span>
+<span class="p">};</span>
+
+<span class="k">fn</span> <span class="nf">main</span><span 
class="p">()</span> <span class="k">-&gt;</span> <span 
class="nb">Result</span><span class="o">&lt;</span><span class="p">(),</span> 
<span class="nb">Box</span><span class="o">&lt;</span><span 
class="k">dyn</span> <span class="nn">std</span><span class="p">::</span><span 
class="nn">error</span><span class="p">::</span><span 
class="n">Error</span><span class="o">&gt;&gt;</span> <span class="p">{</span>
+    <span class="c1">// Register writer schema under Confluent id=1.</span>
+    <span class="k">let</span> <span class="k">mut</span> <span 
class="n">store</span> <span class="o">=</span> <span 
class="nn">SchemaStore</span><span class="p">::</span><span 
class="nf">new_with_type</span><span class="p">(</span><span 
class="nn">FingerprintAlgorithm</span><span class="p">::</span><span 
class="n">Id</span><span class="p">);</span>
+    <span class="n">store</span><span class="nf">.set</span><span 
class="p">(</span>
+        <span class="nn">Fingerprint</span><span class="p">::</span><span 
class="nf">Id</span><span class="p">(</span><span class="mi">1</span><span 
class="p">),</span>
+        <span class="nn">AvroSchema</span><span class="p">::</span><span 
class="nf">new</span><span class="p">(</span><span 
class="s">r#"{"type":"record","name":"T","fields":[{"name":"x","type":"long"}]}"#</span><span
 class="nf">.into</span><span class="p">()),</span>
+    <span class="p">)</span><span class="o">?</span><span class="p">;</span>
+
+    <span class="c1">// Define reader schema to enable projection/schema 
evolution.</span>
+    <span class="k">let</span> <span class="n">reader_schema</span> <span 
class="o">=</span> <span class="nn">AvroSchema</span><span 
class="p">::</span><span class="nf">new</span><span class="p">(</span><span 
class="s">r#"{"type":"record","name":"T","fields":[{"name":"x","type":"long"}]}"#</span><span
 class="nf">.into</span><span class="p">());</span>
+
+    <span class="c1">// Build Decoder using reader and writer schemas</span>
+    <span class="k">let</span> <span class="k">mut</span> <span 
class="n">decoder</span> <span class="o">=</span> <span 
class="nn">ReaderBuilder</span><span class="p">::</span><span 
class="nf">new</span><span class="p">()</span>
+        <span class="nf">.with_reader_schema</span><span 
class="p">(</span><span class="n">reader_schema</span><span class="p">)</span>
+        <span class="nf">.with_writer_schema_store</span><span 
class="p">(</span><span class="n">store</span><span class="p">)</span>
+        <span class="nf">.build_decoder</span><span class="p">()</span><span 
class="o">?</span><span class="p">;</span>
+
+    <span class="c1">// Simulate one frame: magic 0x00 + 4‑byte big‑endian 
schema ID + Avro body (x=1 encoded as zig‑zag/VLQ).</span>
+    <span class="k">let</span> <span class="k">mut</span> <span 
class="n">frame</span> <span class="o">=</span> <span 
class="nn">Vec</span><span class="p">::</span><span class="nf">from</span><span 
class="p">(</span><span class="n">CONFLUENT_MAGIC</span><span 
class="p">);</span> <span class="n">frame</span><span 
class="nf">.extend_from_slice</span><span class="p">(</span><span 
class="o">&amp;</span><span class="mi">1u32</span><span 
class="nf">.to_be_bytes</span><span class="p">());</span [...]
+
+    <span class="c1">// Consume from decoder</span>
+    <span class="k">let</span> <span class="n">_consumed</span> <span 
class="o">=</span> <span class="n">decoder</span><span 
class="nf">.decode</span><span class="p">(</span><span 
class="o">&amp;</span><span class="n">frame</span><span class="p">)</span><span 
class="o">?</span><span class="p">;</span>
+    <span class="k">while</span> <span class="k">let</span> <span 
class="nf">Some</span><span class="p">(</span><span class="n">batch</span><span 
class="p">)</span> <span class="o">=</span> <span class="n">decoder</span><span 
class="nf">.flush</span><span class="p">()</span><span class="o">?</span> <span 
class="p">{</span>
+        <span class="nd">println!</span><span class="p">(</span><span 
class="s">"rows={}, cols={}"</span><span class="p">,</span> <span 
class="n">batch</span><span class="nf">.num_rows</span><span 
class="p">(),</span> <span class="n">batch</span><span 
class="nf">.num_columns</span><span class="p">());</span>
+    <span class="p">}</span>
+    <span class="nf">Ok</span><span class="p">(())</span>
+<span class="p">}</span>
+</code></pre></div></div>
+<p>The <code>SchemaStore</code> maps the incoming schema ID to the correct 
Avro writer schema so the decoder can perform projection/evolution against the 
reader schema. Confluent's wire format prefixes each message with a magic byte 
<code>0x00</code> followed by a big‑endian 4‑byte schema ID. After decoding 
Avro messages, the <code>Decoder::flush()</code> method yields Arrow 
<code>RecordBatch</code>es suitable for vectorized processing.</p>
+<p>A more advanced example can be found <a 
href="https://github.com/apache/arrow-rs/blob/main/arrow-avro/examples/decode_kafka_stream.rs";
 target="_blank" rel="noopener">here</a>.</p>
+<h3>Writing a Snappy Compressed Avro OCF file</h3>
+<div class="language-rust highlighter-rouge"><div class="highlight"><pre 
class="highlight"><code data-lang="rust"><span class="k">use</span> <span 
class="nn">arrow_array</span><span class="p">::{</span><span 
class="n">Int64Array</span><span class="p">,</span> <span 
class="n">RecordBatch</span><span class="p">};</span>
+<span class="k">use</span> <span class="nn">arrow_schema</span><span 
class="p">::{</span><span class="n">Schema</span><span class="p">,</span> <span 
class="n">Field</span><span class="p">,</span> <span 
class="n">DataType</span><span class="p">};</span>
+<span class="k">use</span> <span class="nn">arrow_avro</span><span 
class="p">::</span><span class="nn">writer</span><span 
class="p">::{</span><span class="n">Writer</span><span class="p">,</span> <span 
class="n">WriterBuilder</span><span class="p">};</span>
+<span class="k">use</span> <span class="nn">arrow_avro</span><span 
class="p">::</span><span class="nn">writer</span><span class="p">::</span><span 
class="nn">format</span><span class="p">::</span><span 
class="n">AvroOcfFormat</span><span class="p">;</span>
+<span class="k">use</span> <span class="nn">arrow_avro</span><span 
class="p">::</span><span class="nn">compression</span><span 
class="p">::</span><span class="n">CompressionCodec</span><span 
class="p">;</span>
+<span class="k">use</span> <span class="nn">std</span><span 
class="p">::{</span><span class="nn">sync</span><span class="p">::</span><span 
class="nb">Arc</span><span class="p">,</span> <span class="nn">fs</span><span 
class="p">::</span><span class="n">File</span><span class="p">,</span> <span 
class="nn">io</span><span class="p">::</span><span 
class="n">BufWriter</span><span class="p">};</span>
+
+<span class="k">fn</span> <span class="nf">main</span><span 
class="p">()</span> <span class="k">-&gt;</span> <span 
class="nb">Result</span><span class="o">&lt;</span><span class="p">(),</span> 
<span class="nb">Box</span><span class="o">&lt;</span><span 
class="k">dyn</span> <span class="nn">std</span><span class="p">::</span><span 
class="nn">error</span><span class="p">::</span><span 
class="n">Error</span><span class="o">&gt;&gt;</span> <span class="p">{</span>
+  <span class="k">let</span> <span class="n">schema</span> <span 
class="o">=</span> <span class="nn">Schema</span><span class="p">::</span><span 
class="nf">new</span><span class="p">(</span><span class="nd">vec!</span><span 
class="p">[</span><span class="nn">Field</span><span class="p">::</span><span 
class="nf">new</span><span class="p">(</span><span class="s">"id"</span><span 
class="p">,</span> <span class="nn">DataType</span><span 
class="p">::</span><span class="n">Int64</span><span cl [...]
+  <span class="k">let</span> <span class="n">batch</span> <span 
class="o">=</span> <span class="nn">RecordBatch</span><span 
class="p">::</span><span class="nf">try_new</span><span class="p">(</span>
+    <span class="nn">Arc</span><span class="p">::</span><span 
class="nf">new</span><span class="p">(</span><span class="n">schema</span><span 
class="nf">.clone</span><span class="p">()),</span>
+    <span class="nd">vec!</span><span class="p">[</span><span 
class="nn">Arc</span><span class="p">::</span><span class="nf">new</span><span 
class="p">(</span><span class="nn">Int64Array</span><span 
class="p">::</span><span class="nf">from</span><span class="p">(</span><span 
class="nd">vec!</span><span class="p">[</span><span class="mi">1</span><span 
class="p">,</span><span class="mi">2</span><span class="p">,</span><span 
class="mi">3</span><span class="p">]))],</span>
+  <span class="p">)</span><span class="o">?</span><span class="p">;</span>
+  <span class="k">let</span> <span class="n">file</span> <span 
class="o">=</span> <span class="nn">File</span><span class="p">::</span><span 
class="nf">create</span><span class="p">(</span><span 
class="s">"target/example.avro"</span><span class="p">)</span><span 
class="o">?</span><span class="p">;</span>
+
+  <span class="c1">// Choose OCF block compression (e.g., None, Deflate, 
Snappy, Zstd)</span>
+  <span class="k">let</span> <span class="k">mut</span> <span 
class="n">writer</span><span class="p">:</span> <span 
class="n">Writer</span><span class="o">&lt;</span><span class="n">_</span><span 
class="p">,</span> <span class="n">AvroOcfFormat</span><span 
class="o">&gt;</span> <span class="o">=</span> <span 
class="nn">WriterBuilder</span><span class="p">::</span><span 
class="nf">new</span><span class="p">(</span><span class="n">schema</span><span 
class="p">)</span>
+      <span class="nf">.with_compression</span><span class="p">(</span><span 
class="nf">Some</span><span class="p">(</span><span 
class="nn">CompressionCodec</span><span class="p">::</span><span 
class="n">Snappy</span><span class="p">))</span>
+      <span class="nf">.build</span><span class="p">(</span><span 
class="nn">BufWriter</span><span class="p">::</span><span 
class="nf">new</span><span class="p">(</span><span class="n">file</span><span 
class="p">))</span><span class="o">?</span><span class="p">;</span>
+  <span class="n">writer</span><span class="nf">.write</span><span 
class="p">(</span><span class="o">&amp;</span><span class="n">batch</span><span 
class="p">)</span><span class="o">?</span><span class="p">;</span>
+  <span class="n">writer</span><span class="nf">.finish</span><span 
class="p">()</span><span class="o">?</span><span class="p">;</span>
+  <span class="nf">Ok</span><span class="p">(())</span>
+<span class="p">}</span>
+</code></pre></div></div>
+<p>The example above configures an Avro OCF <code>Writer</code>. It constructs 
a <code>Writer&lt;_, AvroOcfFormat&gt;</code> using 
<code>WriterBuilder::new(schema)</code> and wraps a <code>File</code> in a 
<code>BufWriter</code> for efficient I/O. The call to 
<code>.with_compression(Some(CompressionCodec::Snappy))</code> enables 
block‑level snappy compression. Finally, <code>writer.write(&amp;batch)?</code> 
serializes the batch as an Avro encoded block, and 
<code>writer.finish()?</code>  [...]
+<h2>Alternatives &amp; Benchmarks</h2>
+<p>There are fundamentally two different approaches for bringing Avro into 
Arrow:</p>
+<ol>
+<li>Row‑centric approach, typical of general Avro libraries such as 
<code>apache-avro</code>, deserializes one record at a time into native Rust 
values (i.e., <code>Value</code> or Serde types) and then builds Arrow arrays 
from those values.</li>
+<li>Vectorized approach, what <code>arrow-avro</code> provides, decodes 
directly into Arrow builders/arrays and emits <code>RecordBatch</code>es, 
avoiding most per‑row overhead.</li>
+</ol>
+<p>This section compares the performance of both approaches using these <a 
href="https://github.com/jecsand838/arrow-rs/tree/blog-benches/arrow-avro/benches";
 target="_blank" rel="noopener">Criterion benchmarks</a>.</p>
+<h3>Read performance (1M)</h3>
+<div style="display: flex; gap: 16px; justify-content: center; align-items: 
flex-start; padding: 5px 5px;">
+<img src="/img/introducing-arrow-avro/read_violin_1m.svg" width="100%" alt="1M 
Row Read Violin Plot" style="background:#fff">
+</div>
+<h3>Read performance (10K)</h3>
+<div style="display: flex; gap: 16px; justify-content: center; align-items: 
flex-start; padding: 5px 5px;">
+<img src="/img/introducing-arrow-avro/read_violin_10k.svg" width="100%" 
alt="10K Row Read Violin Plot" style="background:#fff">
+</div>
+<h3>Write performance (1M)</h3>
+<div style="display: flex; gap: 16px; justify-content: center; align-items: 
flex-start; padding: 5px 5px;">
+<img src="/img/introducing-arrow-avro/write_violin_1m.svg" width="100%" 
alt="1M Row Write Violin Plot" style="background:#fff">
+</div>
+<h3>Write performance (10K)</h3>
+<div style="display: flex; gap: 16px; justify-content: center; align-items: 
flex-start; padding: 5px 5px;">
+<img src="/img/introducing-arrow-avro/write_violin_10k.svg" width="100%" 
alt="10K Row Write Violin Plot" style="background:#fff">
+</div>
+<p>Across benchmarks, the violin plots show lower medians and tighter spreads 
for <code>arrow-avro</code> on both read and write paths. The gap widens when 
per‑row work dominates (i.e., 10K‑row scenarios). At 1M rows, the distributions 
remain favorable to <code>arrow-avro</code>, reflecting better cache locality 
and fewer copies once decoding goes straight to Arrow arrays. The general 
behavior is consistent with <code>apache-avro</code>'s record‑by‑record 
iteration and <code>arrow-avro</ [...]
+<p>The table below lists the cases we report in the figures:</p>
+<ul>
+<li>10K vs 1M rows for multiple data shapes.</li>
+<li>
+<strong>Read cases:</strong>
+<ul>
+<li>
+<code>f8</code>: <em>Full schema, 8K batch size.</em>
+Decode all four columns with batch_size = 8192.</li>
+<li>
+<code>f1</code>: <em>Full schema, 1K batch size.</em>
+Decode all four columns with batch_size = 1024.</li>
+<li>
+<code>p8</code>: <em>Projected <code>{id,name}</code>, 8K batch size 
(pushdown).</em>
+Decode only <code>id</code> and <code>name</code> with batch_size = 8192`.
+<em>How projection is applied:</em>
+<ul>
+<li>
+<code>arrow-avro/p8</code>: projection via reader schema 
(<code>ReaderBuilder::with_reader_schema(...)</code>) so decoding is 
column‑pushed down in the Arrow‑first reader.</li>
+<li>
+<code>apache-avro/p8</code>: projection via Avro reader schema 
(<code>AvroReader::with_schema(...)</code>) so the Avro library decodes only 
the projected fields.</li>
+</ul>
+</li>
+<li>
+<code>np</code>: <em>Projected <code>{id,name}</code>, no pushdown, 8K batch 
size.</em>
+Both readers decode the full record (all four columns), materialize all 
arrays, then project down to <code>{id,name}</code> after decode. This models 
systems that can't push projection into the file/codec reader.</li>
+</ul>
+</li>
+<li>
+<strong>Write cases:</strong>
+<ul>
+<li>
+<code>c</code> (cold): <em>Schema conversion each iteration.</em>
+</li>
+<li>
+<code>h</code> (hot): <em>Avro JSON "hot" path.</em>
+</li>
+</ul>
+</li>
+<li>The resulting Apache‑Avro vs Arrow‑Avro medians with the computed 
speedup.</li>
+</ul>
+<h3>Benchmark Median Time Results (Apple Silicon Mac)</h3>
+<table>
+<thead>
+<tr>
+<th>Case</th>
+<th align="right">apache-avro median</th>
+<th align="right">arrow-avro median</th>
+<th align="right">speedup</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>R/f8/10K</td>
+<td align="right">2.60 ms</td>
+<td align="right">0.24 ms</td>
+<td align="right">10.83x</td>
+</tr>
+<tr>
+<td>R/p8/10K</td>
+<td align="right">7.91 ms</td>
+<td align="right">0.24 ms</td>
+<td align="right">32.95x</td>
+</tr>
+<tr>
+<td>R/f1/10K</td>
+<td align="right">2.65 ms</td>
+<td align="right">0.25 ms</td>
+<td align="right">10.60x</td>
+</tr>
+<tr>
+<td>R/np/10K</td>
+<td align="right">2.62 ms</td>
+<td align="right">0.25 ms</td>
+<td align="right">10.48x</td>
+</tr>
+<tr>
+<td>R/f8/1M</td>
+<td align="right">267.21 ms</td>
+<td align="right">27.91 ms</td>
+<td align="right">9.57x</td>
+</tr>
+<tr>
+<td>R/p8/1M</td>
+<td align="right">791.79 ms</td>
+<td align="right">26.28 ms</td>
+<td align="right">30.13x</td>
+</tr>
+<tr>
+<td>R/f1/1M</td>
+<td align="right">262.93 ms</td>
+<td align="right">28.25 ms</td>
+<td align="right">9.31x</td>
+</tr>
+<tr>
+<td>R/np/1M</td>
+<td align="right">268.79 ms</td>
+<td align="right">27.69 ms</td>
+<td align="right">9.71x</td>
+</tr>
+<tr>
+<td>W/c/10K</td>
+<td align="right">4.78 ms</td>
+<td align="right">0.27 ms</td>
+<td align="right">17.70x</td>
+</tr>
+<tr>
+<td>W/h/10K</td>
+<td align="right">0.82 ms</td>
+<td align="right">0.28 ms</td>
+<td align="right">2.93x</td>
+</tr>
+<tr>
+<td>W/c/1M</td>
+<td align="right">485.58 ms</td>
+<td align="right">36.97 ms</td>
+<td align="right">13.13x</td>
+</tr>
+<tr>
+<td>W/h/1M</td>
+<td align="right">83.58 ms</td>
+<td align="right">36.75 ms</td>
+<td align="right">2.27x</td>
+</tr>
+</tbody>
+</table>
+<h2>Closing</h2>
+<p><code>arrow-avro</code> brings a purpose‑built, vectorized bridge 
connecting Arrow-rs and Avro that covers Object Container Files (OCF), 
Single‑Object Encoding (SOE), and the Confluent/Apicurio Schema Registry wire 
formats. This means you can now keep your ingestion paths columnar for both 
batch files and streaming systems. The reader and writer APIs shown above are 
now available for you to use with the v57.0.0 release of 
<code>arrow-rs</code>.</p>
+<p>This work is part of the ongoing Arrow‑rs effort to implement first-class 
Avro support in Rust. We'd love your feedback on real‑world use-cases, 
workloads, and integrations. We also welcome contributions, whether that's 
issues, benchmarks, or PRs. To follow along or help, open an <a 
href="https://github.com/apache/arrow-rs/issues"; target="_blank" 
rel="noopener">issue on GitHub</a> and/or track <a 
href="https://github.com/apache/arrow-rs/issues/4886"; target="_blank" 
rel="noopener">Add  [...]
+<h3>Acknowledgments</h3>
+<p>Special thanks to:</p>
+<ul>
+<li>
+<a href="https://github.com/tustvold"; target="_blank" 
rel="noopener">tustvold</a> for laying an incredible zero-copy foundation.</li>
+<li>
+<a href="https://github.com/nathaniel-d-ef"; target="_blank" 
rel="noopener">nathaniel-d-ef</a> and <a href="https://github.com/elastiflow"; 
target="_blank" rel="noopener">ElastiFlow</a> for their numerous and invaluable 
project-wide contributions.</li>
+<li>
+<a href="https://github.com/veronica-m-ef"; target="_blank" 
rel="noopener">veronica-m-ef</a> for making Impala‑related contributions to the 
<code>Reader</code>.</li>
+<li>
+<a href="https://github.com/Supermetal-Inc"; target="_blank" 
rel="noopener">Supermetal</a> for contributions related to Apicurio Registry 
and Run-End Encoding type support.</li>
+<li>
+<a href="https://github.com/kumarlokesh"; target="_blank" 
rel="noopener">kumarlokesh</a> for contributing <code>Utf8View</code> 
support.</li>
+<li>
+<a href="https://github.com/alamb"; target="_blank" rel="noopener">alamb</a>, 
<a href="https://github.com/scovich"; target="_blank" 
rel="noopener">scovich</a>, <a href="https://github.com/mbrobbel"; 
target="_blank" rel="noopener">mbrobbel</a>, and <a 
href="https://github.com/klion26"; target="_blank" rel="noopener">klion26</a> 
for their thoughtful reviews, detailed feedback, and support throughout the 
development of <code>arrow-avro</code>.</li>
+</ul>
+<p>If you have any questions about this blog post, please feel free to contact 
the author, <a href="mailto:[email protected]";>Connor Sanders</a>.</p>
+
+      </main>
+    </div>
+
+    <hr>
+<footer class="footer">
+  <div class="row">
+    <div class="col-md-9">
+      <p>Apache Arrow, Arrow, Apache, the Apache logo, and the Apache Arrow 
project logo are either registered trademarks or trademarks of The Apache 
Software Foundation in the United States and other countries.</p>
+      <p>© 2016-2025 The Apache Software Foundation</p>
+    </div>
+    <div class="col-md-3">
+      <a class="d-sm-none d-md-inline pr-2" 
href="https://www.apache.org/events/current-event.html"; target="_blank" 
rel="noopener">
+        <img src="https://www.apache.org/events/current-event-234x60.png";>
+      </a>
+    </div>
+  </div>
+</footer>
+
+  </div>
+</body>
+</html>
diff --git a/blog/index.html b/blog/index.html
index 153a7eb0326..a9b19cb5481 100644
--- a/blog/index.html
+++ b/blog/index.html
@@ -273,6 +273,26 @@ faster than previous versions thanks to a ne...
   
 
   
+  <p>
+    </p>
+<h3>
+      <a href="/blog/2025/10/23/introducing-arrow-avro/">Announcing arrow-avro 
in Arrow Rust</a>
+    </h3>
+    
+    <p>
+    <span class="blog-list-date">
+      23 October 2025
+    </span>
+    </p>
+    
+arrow-avro, a newly rewritten Rust crate that reads and writes Apache Avro 
data directly as Arrow RecordBatches, is now available. It supports Avro Object 
Container Files (OCF), Single‑Object Encoding (SOE), the Confluent Schema 
Registry wire format, and the Apicurio Registry wire format, with 
projection/evolution, tunable batch sizing, and opt...
+     
+    <a href="/blog/2025/10/23/introducing-arrow-avro/">Read More →</a>
+
+  
+  
+
+  
   <p>
     </p>
 <h3>
diff --git a/feed.xml b/feed.xml
index 080eb8b8f86..ce0eac04ada 100644
--- a/feed.xml
+++ b/feed.xml
@@ -1,4 +1,272 @@
-<?xml version="1.0" encoding="utf-8"?><feed 
xmlns="http://www.w3.org/2005/Atom"; ><generator uri="https://jekyllrb.com/"; 
version="4.4.1">Jekyll</generator><link 
href="https://arrow.apache.org/feed.xml"; rel="self" type="application/atom+xml" 
/><link href="https://arrow.apache.org/"; rel="alternate" type="text/html" 
/><updated>2025-10-23T12:22:18-04:00</updated><id>https://arrow.apache.org/feed.xml</id><title
 type="html">Apache Arrow</title><subtitle>Apache Arrow is the universal 
columnar fo [...]
+<?xml version="1.0" encoding="utf-8"?><feed 
xmlns="http://www.w3.org/2005/Atom"; ><generator uri="https://jekyllrb.com/"; 
version="4.4.1">Jekyll</generator><link 
href="https://arrow.apache.org/feed.xml"; rel="self" type="application/atom+xml" 
/><link href="https://arrow.apache.org/"; rel="alternate" type="text/html" 
/><updated>2025-10-23T14:27:54-04:00</updated><id>https://arrow.apache.org/feed.xml</id><title
 type="html">Apache Arrow</title><subtitle>Apache Arrow is the universal 
columnar fo [...]
+
+-->
+<p><a href="https://crates.io/crates/arrow-avro";><code>arrow-avro</code></a>, 
a newly rewritten Rust crate that reads and writes <a 
href="https://avro.apache.org/";>Apache Avro</a> data directly as Arrow 
<code>RecordBatch</code>es, is now available. It supports <a 
href="https://avro.apache.org/docs/1.11.1/specification/#object-container-files";>Avro
 Object Container Files</a> (OCF), <a 
href="https://avro.apache.org/docs/1.11.1/specification/#single-object-encoding";>Single‑Object
 Encoding</ [...]
+<h2>Motivation</h2>
+<p>Apache Avro’s row‑oriented design is effective for encoding one record at a 
time, while Apache Arrow’s columnar layout is optimized for vectorized 
analytics. A major challenge lies in converting between these formats without 
reintroducing row‑wise overhead. Decoding Avro a row at a time and then 
building Arrow arrays incurs extra allocations and cache‑unfriendly access (the 
very costs Arrow is designed to avoid). In the real world, this overhead 
commonly shows up in analytical hot pat [...]
+<h3>Why not use the existing <code>apache-avro</code> crate?</h3>
+<p>Rust already has a mature, general‑purpose Avro crate, <a 
href="https://crates.io/crates/apache-avro";>apache-avro</a>. It reads and 
writes Avro records as Avro value types and provides Object Container File 
readers and writers. What it does not do is decode directly into Arrow arrays, 
so any Arrow integration must materialize rows and then build columns.</p>
+<p>What’s needed is a complementary approach that decodes column‑by‑column 
straight into Arrow builders and emits <code>RecordBatch</code>es. This would 
enable projection pushdown while keeping execution vectorized end to end. For 
projects such as <a href="https://datafusion.apache.org/";>Apache 
DataFusion</a>, access to a mature, upstream Arrow‑native reader and writer 
would help simplify the code path and reduce duplication.</p>
+<p>Modern pipelines heighten this need because <a 
href="https://www.confluent.io/blog/avro-kafka-data/";>Avro is also used on the 
wire</a>, not just in files. Kafka ecosystems commonly use Confluent’s Schema 
Registry framing, and many services adopt the Avro Single‑Object Encoding 
format. An approach that enables decoding straight into Arrow batches (rather 
than through per‑row values) would let downstream compute remain vectorized at 
streaming rates.</p>
+<h3>Why this matters</h3>
+<p>Apache Avro is a first‑class format across stream processors and cloud 
services:</p>
+<ul>
+<li>Confluent Schema Registry supports <a 
href="https://docs.confluent.io/platform/current/schema-registry/fundamentals/serdes-develop/serdes-avro.html";>Avro
 across multiple languages and tooling</a>.</li>
+<li>Apache Flink exposes an <a 
href="https://nightlies.apache.org/flink/flink-docs-release-1.19/docs/connectors/table/formats/avro-confluent/";><code>avro-confluent</code>
 format for Kafka</a>.</li>
+<li>AWS Lambda <a 
href="https://aws.amazon.com/about-aws/whats-new/2025/06/aws-lambda-native-support-avro-protobuf-kafka-events/";>(June
 2025) added native handling for Avro‑formatted Kafka events</a> with Glue and 
Confluent Schema Registry integrations.</li>
+<li>Azure Event Hubs provides a <a 
href="https://learn.microsoft.com/en-us/azure/event-hubs/schema-registry-overview";>Schema
 Registry with Avro support</a> for Kafka‑compatible clients.</li>
+</ul>
+<p>In short: Arrow users encounter Avro both on disk (OCF) and on the wire 
(SOE). An Arrow‑first, vectorized reader/writer for OCF, SOE, and Confluent 
framing removes a pervasive bottleneck and keeps pipelines columnar 
end‑to‑end.</p>
+<h2>Introducing <code>arrow-avro</code></h2>
+<p><a 
href="https://github.com/apache/arrow-rs/tree/main/arrow-avro";><code>arrow-avro</code></a>
 is a high-performance Rust crate that converts between Avro and Arrow with a 
column‑first, batch‑oriented design. On the read side, it decodes Avro Object 
Container Files (OCF), Single‑Object Encoding (SOE), and the Confluent Schema 
Registry wire format directly into Arrow <code>RecordBatch</code>es. Meanwhile, 
the write path provides formats for encoding to OCF and SOE as well.</p>
+<p>The crate exposes two primary read APIs: a high-level <code>Reader</code> 
for OCF inputs and a low-level <code>Decoder</code> for streaming SOE frames. 
For SOE and Confluent/Apicurio frames, a <code>SchemaStore</code> is provided 
that resolves fingerprints or schema IDs to full Avro writer schemas, enabling 
schema evolution while keeping the decode path vectorized.</p>
+<p>On the write side, <code>AvroWriter</code> produces OCF (including 
container‑level compression), while <code>AvroStreamWriter</code> produces 
framed Avro messages for Single‑Object or Confluent/Apicurio encodings, as 
configured via the <code>WriterBuilder::with_fingerprint_strategy(...)</code> 
knob.</p>
+<p>Configuration is intentionally minimal but practical. For instance, the 
<code>ReaderBuilder</code> exposes knobs covering both batch file ingestion and 
streaming systems without forcing format‑specific code paths.</p>
+<h3>How this mirrors Parquet in Arrow‑rs</h3>
+<p>If you have used Parquet with Arrow‑rs, you already know the pattern. The 
<code>parquet</code> crate exposes a <a 
href="https://docs.rs/parquet/latest/parquet/arrow/index.html";>parquet::arrow 
module</a> that reads and writes Arrow <code>RecordBatch</code>es directly. 
Most users reach for <code>ParquetRecordBatchReaderBuilder</code> when reading 
and <code>ArrowWriter</code> when writing. You choose columns up front, set a 
batch size, and the reader gives you Arrow batches that flow str [...]
+<p><code>arrow‑avro</code> brings that same bridge to Avro. You get a single 
<code>ReaderBuilder</code> that can produce a <code>Reader</code> for OCF, or a 
streaming <code>Decoder</code> for on‑the‑wire frames. Both return Arrow 
<code>RecordBatch</code>es, which means engines can keep projection and 
filtering close to the reader and avoid building rows only to reassemble them 
back into columns later. For evolving streams, a small <code>SchemaStore</code> 
resolves fingerprints or ids bef [...]
+<p>The reason this pattern matters is straightforward. Arrow’s columnar format 
is designed for vectorized work and good cache locality. When a format reader 
produces Arrow batches directly, copies and branchy per‑row work are minimized, 
keeping downstream operators fast. That is the same story that made 
<code>parquet::arrow</code> popular in Rust, and it is what 
<code>arrow‑avro</code> now enables for Avro.</p>
+<h2>Architecture &amp; Technical Overview</h2>
+<div style="display: flex; gap: 16px; justify-content: center; align-items: 
flex-start; padding: 20px 15px;">
+<img src="/img/introducing-arrow-avro/arrow-avro-architecture.svg"
+        width="100%"
+        alt="High-level `arrow-avro` architecture"
+        style="background:#fff">
+</div>
+<p>At a high level, <a 
href="https://arrow.apache.org/rust/arrow_avro/index.html";>arrow-avro</a> 
splits cleanly into read and write paths built around Arrow 
<code>RecordBatch</code>es. The read side turns Avro (OCF files or framed byte 
streams) into batched Arrow arrays, while the write side takes Arrow batches 
and produces OCF files or streaming frames. When using an 
<code>AvroStreamWriter</code>, the framing (SOE or Confluent) is part of the 
stream output based on the configured finger [...]
+<p>On the <a 
href="https://arrow.apache.org/rust/arrow_avro/reader/index.html";>read</a> 
path, everything starts with the <a 
href="https://arrow.apache.org/rust/arrow_avro/reader/struct.ReaderBuilder.html";>ReaderBuilder</a>.
 A single builder can create a <a 
href="https://arrow.apache.org/rust/arrow_avro/reader/struct.Reader.html";>Reader</a>
 for Object Container Files (OCF) or a streaming <a 
href="https://arrow.apache.org/rust/arrow_avro/reader/struct.Decoder.html";>Decoder</a>
 for SOE/Conf [...]
+<p>When reading an OCF, the <code>Reader</code> parses a header and then 
iterates over blocks of encoded data. The header contains a metadata map with 
the embedded Avro schema and optional compression (i.e., <code>deflate</code>, 
<code>snappy</code>, <code>zstd</code>, <code>bzip2</code>, <code>xz</code>), 
plus a 16‑byte sync marker used to delimit blocks. Each subsequent OCF block 
then carries a row count and the encoded payload. The parsed OCF header and 
block structures are also encod [...]
+<p>On the <a 
href="https://arrow.apache.org/rust/arrow_avro/writer/index.html";>write</a> 
path, the <a 
href="https://arrow.apache.org/rust/arrow_avro/writer/struct.WriterBuilder.html";>WriterBuilder</a>
 produces either an <a 
href="https://arrow.apache.org/rust/arrow_avro/writer/type.AvroWriter.html";>AvroWriter</a>
 (OCF) or an <a 
href="https://arrow.apache.org/rust/arrow_avro/writer/type.AvroStreamWriter.html";>AvroStreamWriter</a>
 (SOE/Message). The <code>with_compression(...)</code> knob i [...]
+<p>Schema handling is centralized in the <a 
href="https://arrow.apache.org/rust/arrow_avro/schema/index.html";>schema</a> 
module. <a 
href="https://arrow.apache.org/rust/arrow_avro/schema/struct.AvroSchema.html";>AvroSchema</a>
 wraps a valid Avro Schema JSON string, supports computing a 
<code>Fingerprint</code>, and can be loaded into a <a 
href="https://arrow.apache.org/rust/arrow_avro/schema/struct.SchemaStore.html";>SchemaStore</a>
 as a writer schema. At runtime, the <code>Reader</code>/<c [...]
+<p>At the heart of <code>arrow-avro</code> is a type‑mapping 
<code>Codec</code> that the library uses to construct both encoders and 
decoders. The <code>Codec</code> captures, for every Avro field, how it maps to 
Arrow and how it should be encoded or decoded. The <code>Reader</code> logic 
builds a <code>Codec</code> per <em>(writer, reader)</em> schema pair, which 
the decoder later uses to vectorize parsing of Avro values directly into the 
correct Arrow builders. The <code>Writer</code>  [...]
+<p>Finally, by keeping container and stream framing (OCF vs. SOE) separate 
from encoding and decoding, the crate composes naturally with the rest of 
Arrow‑rs: you read or write Arrow <code>RecordBatch</code>es, pick OCF or SOE 
streams as needed, and wire up fingerprints only when you're on a streaming 
path. This results in a compact API surface that covers both batch files and 
high‑throughput streams without sacrificing columnar, vectorized execution.</p>
+<h2>Examples</h2>
+<h3>Decoding a Confluent-framed Kafka Stream</h3>
+<div class="language-rust highlighter-rouge"><div class="highlight"><pre 
class="highlight"><code data-lang="rust"><span class="k">use</span> <span 
class="nn">arrow_avro</span><span class="p">::</span><span 
class="nn">reader</span><span class="p">::</span><span 
class="n">ReaderBuilder</span><span class="p">;</span>
+<span class="k">use</span> <span class="nn">arrow_avro</span><span 
class="p">::</span><span class="nn">schema</span><span class="p">::{</span>
+    <span class="n">SchemaStore</span><span class="p">,</span> <span 
class="n">AvroSchema</span><span class="p">,</span> <span 
class="n">Fingerprint</span><span class="p">,</span> <span 
class="n">FingerprintAlgorithm</span><span class="p">,</span> <span 
class="n">CONFLUENT_MAGIC</span>
+<span class="p">};</span>
+
+<span class="k">fn</span> <span class="nf">main</span><span 
class="p">()</span> <span class="k">-&gt;</span> <span 
class="nb">Result</span><span class="o">&lt;</span><span class="p">(),</span> 
<span class="nb">Box</span><span class="o">&lt;</span><span 
class="k">dyn</span> <span class="nn">std</span><span class="p">::</span><span 
class="nn">error</span><span class="p">::</span><span 
class="n">Error</span><span class="o">&gt;&gt;</span> <span class="p">{</span>
+    <span class="c1">// Register writer schema under Confluent id=1.</span>
+    <span class="k">let</span> <span class="k">mut</span> <span 
class="n">store</span> <span class="o">=</span> <span 
class="nn">SchemaStore</span><span class="p">::</span><span 
class="nf">new_with_type</span><span class="p">(</span><span 
class="nn">FingerprintAlgorithm</span><span class="p">::</span><span 
class="n">Id</span><span class="p">);</span>
+    <span class="n">store</span><span class="nf">.set</span><span 
class="p">(</span>
+        <span class="nn">Fingerprint</span><span class="p">::</span><span 
class="nf">Id</span><span class="p">(</span><span class="mi">1</span><span 
class="p">),</span>
+        <span class="nn">AvroSchema</span><span class="p">::</span><span 
class="nf">new</span><span class="p">(</span><span 
class="s">r#"{"type":"record","name":"T","fields":[{"name":"x","type":"long"}]}"#</span><span
 class="nf">.into</span><span class="p">()),</span>
+    <span class="p">)</span><span class="o">?</span><span class="p">;</span>
+
+    <span class="c1">// Define reader schema to enable projection/schema 
evolution.</span>
+    <span class="k">let</span> <span class="n">reader_schema</span> <span 
class="o">=</span> <span class="nn">AvroSchema</span><span 
class="p">::</span><span class="nf">new</span><span class="p">(</span><span 
class="s">r#"{"type":"record","name":"T","fields":[{"name":"x","type":"long"}]}"#</span><span
 class="nf">.into</span><span class="p">());</span>
+
+    <span class="c1">// Build Decoder using reader and writer schemas</span>
+    <span class="k">let</span> <span class="k">mut</span> <span 
class="n">decoder</span> <span class="o">=</span> <span 
class="nn">ReaderBuilder</span><span class="p">::</span><span 
class="nf">new</span><span class="p">()</span>
+        <span class="nf">.with_reader_schema</span><span 
class="p">(</span><span class="n">reader_schema</span><span class="p">)</span>
+        <span class="nf">.with_writer_schema_store</span><span 
class="p">(</span><span class="n">store</span><span class="p">)</span>
+        <span class="nf">.build_decoder</span><span class="p">()</span><span 
class="o">?</span><span class="p">;</span>
+
+    <span class="c1">// Simulate one frame: magic 0x00 + 4‑byte big‑endian 
schema ID + Avro body (x=1 encoded as zig‑zag/VLQ).</span>
+    <span class="k">let</span> <span class="k">mut</span> <span 
class="n">frame</span> <span class="o">=</span> <span 
class="nn">Vec</span><span class="p">::</span><span class="nf">from</span><span 
class="p">(</span><span class="n">CONFLUENT_MAGIC</span><span 
class="p">);</span> <span class="n">frame</span><span 
class="nf">.extend_from_slice</span><span class="p">(</span><span 
class="o">&amp;</span><span class="mi">1u32</span><span 
class="nf">.to_be_bytes</span><span class="p">());</span [...]
+
+    <span class="c1">// Consume from decoder</span>
+    <span class="k">let</span> <span class="n">_consumed</span> <span 
class="o">=</span> <span class="n">decoder</span><span 
class="nf">.decode</span><span class="p">(</span><span 
class="o">&amp;</span><span class="n">frame</span><span class="p">)</span><span 
class="o">?</span><span class="p">;</span>
+    <span class="k">while</span> <span class="k">let</span> <span 
class="nf">Some</span><span class="p">(</span><span class="n">batch</span><span 
class="p">)</span> <span class="o">=</span> <span class="n">decoder</span><span 
class="nf">.flush</span><span class="p">()</span><span class="o">?</span> <span 
class="p">{</span>
+        <span class="nd">println!</span><span class="p">(</span><span 
class="s">"rows={}, cols={}"</span><span class="p">,</span> <span 
class="n">batch</span><span class="nf">.num_rows</span><span 
class="p">(),</span> <span class="n">batch</span><span 
class="nf">.num_columns</span><span class="p">());</span>
+    <span class="p">}</span>
+    <span class="nf">Ok</span><span class="p">(())</span>
+<span class="p">}</span>
+</code></pre></div></div>
+<p>The <code>SchemaStore</code> maps the incoming schema ID to the correct 
Avro writer schema so the decoder can perform projection/evolution against the 
reader schema. Confluent's wire format prefixes each message with a magic byte 
<code>0x00</code> followed by a big‑endian 4‑byte schema ID. After decoding 
Avro messages, the <code>Decoder::flush()</code> method yields Arrow 
<code>RecordBatch</code>es suitable for vectorized processing.</p>
+<p>A more advanced example can be found <a 
href="https://github.com/apache/arrow-rs/blob/main/arrow-avro/examples/decode_kafka_stream.rs";>here</a>.</p>
+<h3>Writing a Snappy Compressed Avro OCF file</h3>
+<div class="language-rust highlighter-rouge"><div class="highlight"><pre 
class="highlight"><code data-lang="rust"><span class="k">use</span> <span 
class="nn">arrow_array</span><span class="p">::{</span><span 
class="n">Int64Array</span><span class="p">,</span> <span 
class="n">RecordBatch</span><span class="p">};</span>
+<span class="k">use</span> <span class="nn">arrow_schema</span><span 
class="p">::{</span><span class="n">Schema</span><span class="p">,</span> <span 
class="n">Field</span><span class="p">,</span> <span 
class="n">DataType</span><span class="p">};</span>
+<span class="k">use</span> <span class="nn">arrow_avro</span><span 
class="p">::</span><span class="nn">writer</span><span 
class="p">::{</span><span class="n">Writer</span><span class="p">,</span> <span 
class="n">WriterBuilder</span><span class="p">};</span>
+<span class="k">use</span> <span class="nn">arrow_avro</span><span 
class="p">::</span><span class="nn">writer</span><span class="p">::</span><span 
class="nn">format</span><span class="p">::</span><span 
class="n">AvroOcfFormat</span><span class="p">;</span>
+<span class="k">use</span> <span class="nn">arrow_avro</span><span 
class="p">::</span><span class="nn">compression</span><span 
class="p">::</span><span class="n">CompressionCodec</span><span 
class="p">;</span>
+<span class="k">use</span> <span class="nn">std</span><span 
class="p">::{</span><span class="nn">sync</span><span class="p">::</span><span 
class="nb">Arc</span><span class="p">,</span> <span class="nn">fs</span><span 
class="p">::</span><span class="n">File</span><span class="p">,</span> <span 
class="nn">io</span><span class="p">::</span><span 
class="n">BufWriter</span><span class="p">};</span>
+
+<span class="k">fn</span> <span class="nf">main</span><span 
class="p">()</span> <span class="k">-&gt;</span> <span 
class="nb">Result</span><span class="o">&lt;</span><span class="p">(),</span> 
<span class="nb">Box</span><span class="o">&lt;</span><span 
class="k">dyn</span> <span class="nn">std</span><span class="p">::</span><span 
class="nn">error</span><span class="p">::</span><span 
class="n">Error</span><span class="o">&gt;&gt;</span> <span class="p">{</span>
+  <span class="k">let</span> <span class="n">schema</span> <span 
class="o">=</span> <span class="nn">Schema</span><span class="p">::</span><span 
class="nf">new</span><span class="p">(</span><span class="nd">vec!</span><span 
class="p">[</span><span class="nn">Field</span><span class="p">::</span><span 
class="nf">new</span><span class="p">(</span><span class="s">"id"</span><span 
class="p">,</span> <span class="nn">DataType</span><span 
class="p">::</span><span class="n">Int64</span><span cl [...]
+  <span class="k">let</span> <span class="n">batch</span> <span 
class="o">=</span> <span class="nn">RecordBatch</span><span 
class="p">::</span><span class="nf">try_new</span><span class="p">(</span>
+    <span class="nn">Arc</span><span class="p">::</span><span 
class="nf">new</span><span class="p">(</span><span class="n">schema</span><span 
class="nf">.clone</span><span class="p">()),</span>
+    <span class="nd">vec!</span><span class="p">[</span><span 
class="nn">Arc</span><span class="p">::</span><span class="nf">new</span><span 
class="p">(</span><span class="nn">Int64Array</span><span 
class="p">::</span><span class="nf">from</span><span class="p">(</span><span 
class="nd">vec!</span><span class="p">[</span><span class="mi">1</span><span 
class="p">,</span><span class="mi">2</span><span class="p">,</span><span 
class="mi">3</span><span class="p">]))],</span>
+  <span class="p">)</span><span class="o">?</span><span class="p">;</span>
+  <span class="k">let</span> <span class="n">file</span> <span 
class="o">=</span> <span class="nn">File</span><span class="p">::</span><span 
class="nf">create</span><span class="p">(</span><span 
class="s">"target/example.avro"</span><span class="p">)</span><span 
class="o">?</span><span class="p">;</span>
+
+  <span class="c1">// Choose OCF block compression (e.g., None, Deflate, 
Snappy, Zstd)</span>
+  <span class="k">let</span> <span class="k">mut</span> <span 
class="n">writer</span><span class="p">:</span> <span 
class="n">Writer</span><span class="o">&lt;</span><span class="n">_</span><span 
class="p">,</span> <span class="n">AvroOcfFormat</span><span 
class="o">&gt;</span> <span class="o">=</span> <span 
class="nn">WriterBuilder</span><span class="p">::</span><span 
class="nf">new</span><span class="p">(</span><span class="n">schema</span><span 
class="p">)</span>
+      <span class="nf">.with_compression</span><span class="p">(</span><span 
class="nf">Some</span><span class="p">(</span><span 
class="nn">CompressionCodec</span><span class="p">::</span><span 
class="n">Snappy</span><span class="p">))</span>
+      <span class="nf">.build</span><span class="p">(</span><span 
class="nn">BufWriter</span><span class="p">::</span><span 
class="nf">new</span><span class="p">(</span><span class="n">file</span><span 
class="p">))</span><span class="o">?</span><span class="p">;</span>
+  <span class="n">writer</span><span class="nf">.write</span><span 
class="p">(</span><span class="o">&amp;</span><span class="n">batch</span><span 
class="p">)</span><span class="o">?</span><span class="p">;</span>
+  <span class="n">writer</span><span class="nf">.finish</span><span 
class="p">()</span><span class="o">?</span><span class="p">;</span>
+  <span class="nf">Ok</span><span class="p">(())</span>
+<span class="p">}</span>
+</code></pre></div></div>
+<p>The example above configures an Avro OCF <code>Writer</code>. It constructs 
a <code>Writer&lt;_, AvroOcfFormat&gt;</code> using 
<code>WriterBuilder::new(schema)</code> and wraps a <code>File</code> in a 
<code>BufWriter</code> for efficient I/O. The call to 
<code>.with_compression(Some(CompressionCodec::Snappy))</code> enables 
block‑level snappy compression. Finally, <code>writer.write(&amp;batch)?</code> 
serializes the batch as an Avro encoded block, and 
<code>writer.finish()?</code>  [...]
+<h2>Alternatives &amp; Benchmarks</h2>
+<p>There are fundamentally two different approaches for bringing Avro into 
Arrow:</p>
+<ol>
+<li>Row‑centric approach, typical of general Avro libraries such as 
<code>apache-avro</code>, deserializes one record at a time into native Rust 
values (i.e., <code>Value</code> or Serde types) and then builds Arrow arrays 
from those values.</li>
+<li>Vectorized approach, what <code>arrow-avro</code> provides, decodes 
directly into Arrow builders/arrays and emits <code>RecordBatch</code>es, 
avoiding most per‑row overhead.</li>
+</ol>
+<p>This section compares the performance of both approaches using these <a 
href="https://github.com/jecsand838/arrow-rs/tree/blog-benches/arrow-avro/benches";>Criterion
 benchmarks</a>.</p>
+<h3>Read performance (1M)</h3>
+<div style="display: flex; gap: 16px; justify-content: center; align-items: 
flex-start; padding: 5px 5px;">
+<img src="/img/introducing-arrow-avro/read_violin_1m.svg"
+        width="100%"
+        alt="1M Row Read Violin Plot"
+        style="background:#fff">
+</div>
+<h3>Read performance (10K)</h3>
+<div style="display: flex; gap: 16px; justify-content: center; align-items: 
flex-start; padding: 5px 5px;">
+<img src="/img/introducing-arrow-avro/read_violin_10k.svg"
+        width="100%"
+        alt="10K Row Read Violin Plot"
+        style="background:#fff">
+</div>
+<h3>Write performance (1M)</h3>
+<div style="display: flex; gap: 16px; justify-content: center; align-items: 
flex-start; padding: 5px 5px;">
+<img src="/img/introducing-arrow-avro/write_violin_1m.svg"
+        width="100%"
+        alt="1M Row Write Violin Plot"
+        style="background:#fff">
+</div>
+<h3>Write performance (10K)</h3>
+<div style="display: flex; gap: 16px; justify-content: center; align-items: 
flex-start; padding: 5px 5px;">
+<img src="/img/introducing-arrow-avro/write_violin_10k.svg"
+        width="100%"
+        alt="10K Row Write Violin Plot"
+        style="background:#fff">
+</div>
+<p>Across benchmarks, the violin plots show lower medians and tighter spreads 
for <code>arrow-avro</code> on both read and write paths. The gap widens when 
per‑row work dominates (i.e., 10K‑row scenarios). At 1M rows, the distributions 
remain favorable to <code>arrow-avro</code>, reflecting better cache locality 
and fewer copies once decoding goes straight to Arrow arrays. The general 
behavior is consistent with <code>apache-avro</code>'s record‑by‑record 
iteration and <code>arrow-avro</ [...]
+<p>The table below lists the cases we report in the figures:</p>
+<ul>
+<li>10K vs 1M rows for multiple data shapes.</li>
+<li><strong>Read cases:</strong>
+<ul>
+<li><code>f8</code>: <em>Full schema, 8K batch size.</em>
+Decode all four columns with batch_size = 8192.</li>
+<li><code>f1</code>: <em>Full schema, 1K batch size.</em>
+Decode all four columns with batch_size = 1024.</li>
+<li><code>p8</code>: <em>Projected <code>{id,name}</code>, 8K batch size 
(pushdown).</em>
+Decode only <code>id</code> and <code>name</code> with batch_size = 8192`.
+<em>How projection is applied:</em>
+<ul>
+<li><code>arrow-avro/p8</code>: projection via reader schema 
(<code>ReaderBuilder::with_reader_schema(...)</code>) so decoding is 
column‑pushed down in the Arrow‑first reader.</li>
+<li><code>apache-avro/p8</code>: projection via Avro reader schema 
(<code>AvroReader::with_schema(...)</code>) so the Avro library decodes only 
the projected fields.</li>
+</ul>
+</li>
+<li><code>np</code>: <em>Projected <code>{id,name}</code>, no pushdown, 8K 
batch size.</em>
+Both readers decode the full record (all four columns), materialize all 
arrays, then project down to <code>{id,name}</code> after decode. This models 
systems that can't push projection into the file/codec reader.</li>
+</ul>
+</li>
+<li><strong>Write cases:</strong>
+<ul>
+<li><code>c</code> (cold): <em>Schema conversion each iteration.</em></li>
+<li><code>h</code> (hot): <em>Avro JSON &quot;hot&quot; path.</em></li>
+</ul>
+</li>
+<li>The resulting Apache‑Avro vs Arrow‑Avro medians with the computed 
speedup.</li>
+</ul>
+<h3>Benchmark Median Time Results (Apple Silicon Mac)</h3>
+<table>
+<thead>
+<tr>
+<th>Case</th>
+<th align="right">apache-avro median</th>
+<th align="right">arrow-avro median</th>
+<th align="right">speedup</th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td>R/f8/10K</td>
+<td align="right">2.60 ms</td>
+<td align="right">0.24 ms</td>
+<td align="right">10.83x</td>
+</tr>
+<tr>
+<td>R/p8/10K</td>
+<td align="right">7.91 ms</td>
+<td align="right">0.24 ms</td>
+<td align="right">32.95x</td>
+</tr>
+<tr>
+<td>R/f1/10K</td>
+<td align="right">2.65 ms</td>
+<td align="right">0.25 ms</td>
+<td align="right">10.60x</td>
+</tr>
+<tr>
+<td>R/np/10K</td>
+<td align="right">2.62 ms</td>
+<td align="right">0.25 ms</td>
+<td align="right">10.48x</td>
+</tr>
+<tr>
+<td>R/f8/1M</td>
+<td align="right">267.21 ms</td>
+<td align="right">27.91 ms</td>
+<td align="right">9.57x</td>
+</tr>
+<tr>
+<td>R/p8/1M</td>
+<td align="right">791.79 ms</td>
+<td align="right">26.28 ms</td>
+<td align="right">30.13x</td>
+</tr>
+<tr>
+<td>R/f1/1M</td>
+<td align="right">262.93 ms</td>
+<td align="right">28.25 ms</td>
+<td align="right">9.31x</td>
+</tr>
+<tr>
+<td>R/np/1M</td>
+<td align="right">268.79 ms</td>
+<td align="right">27.69 ms</td>
+<td align="right">9.71x</td>
+</tr>
+<tr>
+<td>W/c/10K</td>
+<td align="right">4.78 ms</td>
+<td align="right">0.27 ms</td>
+<td align="right">17.70x</td>
+</tr>
+<tr>
+<td>W/h/10K</td>
+<td align="right">0.82 ms</td>
+<td align="right">0.28 ms</td>
+<td align="right">2.93x</td>
+</tr>
+<tr>
+<td>W/c/1M</td>
+<td align="right">485.58 ms</td>
+<td align="right">36.97 ms</td>
+<td align="right">13.13x</td>
+</tr>
+<tr>
+<td>W/h/1M</td>
+<td align="right">83.58 ms</td>
+<td align="right">36.75 ms</td>
+<td align="right">2.27x</td>
+</tr>
+</tbody>
+</table>
+<h2>Closing</h2>
+<p><code>arrow-avro</code> brings a purpose‑built, vectorized bridge 
connecting Arrow-rs and Avro that covers Object Container Files (OCF), 
Single‑Object Encoding (SOE), and the Confluent/Apicurio Schema Registry wire 
formats. This means you can now keep your ingestion paths columnar for both 
batch files and streaming systems. The reader and writer APIs shown above are 
now available for you to use with the v57.0.0 release of 
<code>arrow-rs</code>.</p>
+<p>This work is part of the ongoing Arrow‑rs effort to implement first-class 
Avro support in Rust. We'd love your feedback on real‑world use-cases, 
workloads, and integrations. We also welcome contributions, whether that's 
issues, benchmarks, or PRs. To follow along or help, open an <a 
href="https://github.com/apache/arrow-rs/issues";>issue on GitHub</a> and/or 
track <a href="https://github.com/apache/arrow-rs/issues/4886";>Add Avro 
Support</a> in <code>apache/arrow-rs</code>.</p>
+<h3>Acknowledgments</h3>
+<p>Special thanks to:</p>
+<ul>
+<li><a href="https://github.com/tustvold";>tustvold</a> for laying an 
incredible zero-copy foundation.</li>
+<li><a href="https://github.com/nathaniel-d-ef";>nathaniel-d-ef</a> and <a 
href="https://github.com/elastiflow";>ElastiFlow</a> for their numerous and 
invaluable project-wide contributions.</li>
+<li><a href="https://github.com/veronica-m-ef";>veronica-m-ef</a> for making 
Impala‑related contributions to the <code>Reader</code>.</li>
+<li><a href="https://github.com/Supermetal-Inc";>Supermetal</a> for 
contributions related to Apicurio Registry and Run-End Encoding type 
support.</li>
+<li><a href="https://github.com/kumarlokesh";>kumarlokesh</a> for contributing 
<code>Utf8View</code> support.</li>
+<li><a href="https://github.com/alamb";>alamb</a>, <a 
href="https://github.com/scovich";>scovich</a>, <a 
href="https://github.com/mbrobbel";>mbrobbel</a>, and <a 
href="https://github.com/klion26";>klion26</a> for their thoughtful reviews, 
detailed feedback, and support throughout the development of 
<code>arrow-avro</code>.</li>
+</ul>
+<p>If you have any questions about this blog post, please feel free to contact 
the author, <a href="mailto:[email protected]";>Connor 
Sanders</a>.</p>]]></content><author><name>jecsand838</name></author><category 
term="application" /><summary type="html"><![CDATA[A new native Rust vectorized 
reader/writer for Avro to Arrow, with OCF, Single‑Object, and Confluent wire 
format support.]]></summary><media:thumbnail 
xmlns:media="http://search.yahoo.com/mrss/"; url="https://arrow.apache.org/img/ 
[...]
 
 -->
 <p><em>Editor’s Note: While <a href="https://arrow.apache.org/";>Apache 
Arrow</a> and <a href="https://parquet.apache.org/";>Apache Parquet</a> are 
separate projects,
@@ -1075,67 +1343,4 @@ This is a minor release since the last release <a 
href="https://github.com/apach
 <li>GH-463: Improve TZ support for JDBC driver by @aiguofer in <a 
href="https://github.com/apache/arrow-java/pull/464";>#464</a></li>
 <li>GH-729: [JDBC] Fix BinaryConsumer consuming null value by @hnwyllmm in <a 
href="https://github.com/apache/arrow-java/pull/730";>#730</a></li>
 </ul>
-<p><strong>Full Changelog</strong>: <a 
href="https://github.com/apache/arrow-java/commits/v18.3.0";>changelog</a></p>]]></content><author><name>pmc</name></author><category
 term="release" /><summary type="html"><![CDATA[The Apache Arrow team is 
pleased to announce the v18.3.0 release of Apache Arrow Java. This is a minor 
release since the last release v18.2.0. Changelog New Features and Enhancements 
MINOR: ZstdCompressionCodec should use decompressedSize to get error name by 
@libenchao in [...]
-
--->
-<p>The Apache Arrow team is pleased to announce the v18.3.0 release of Apache 
Arrow Go.
-This minor release covers 21 commits from 8 distinct contributors.</p>
-<h2>Contributors</h2>
-<div class="language-console highlighter-rouge"><div class="highlight"><pre 
class="highlight"><code data-lang="console"><span class="gp">$</span><span 
class="w"> </span>git shortlog <span class="nt">-sn</span> v18.2.0..v18.3.0
-<span class="go">    13        Matt Topol
-     2 Chris Pahl
-     1 Ashish Negi
-     1 David Li
-     1 Jeroen Demeyer
-     1 Mateusz Rzeszutek
-     1 Raúl Cumplido
-     1 Saurabh Singh
-</span></code></pre></div></div>
-<h2>Highlights</h2>
-<ul>
-<li>Fix alignment of atomic refcount handling for ARM <a 
href="https://github.com/apache/arrow-go/pull/323";>#323</a></li>
-</ul>
-<h3>Arrow</h3>
-<ul>
-<li>Functions to convert RecordReader to Go iter.Seq and vice versa <a 
href="https://github.com/apache/arrow-go/pull/314";>#314</a></li>
-<li>New &quot;is_in&quot; function for Arrow compute package</li>
-<li>Allow returning column remarks for FlightSQL CommandGetTables <a 
href="https://github.com/apache/arrow-go/pull/361";>#361</a></li>
-</ul>
-<h3>Parquet</h3>
-<ul>
-<li>Added new <code>SeekToRow</code> function for pqarrow.RecordReader <a 
href="https://github.com/apache/arrow-go/pull/321";>#321</a></li>
-<li>Bloom filters can now be read and written, then utilized for skipping <a 
href="https://github.com/apache/arrow-go/pull/341";>#341</a> <a 
href="https://github.com/apache/arrow-go/pull/336";>#336</a></li>
-<li>Fix a panic when <code>WriteDataPage</code> fails <a 
href="https://github.com/apache/arrow-go/pull/366";>#366</a></li>
-</ul>
-<h2>Changelog</h2>
-<h3>What's Changed</h3>
-<ul>
-<li>feat(arrow/array): convert RecordReader and iterators by @zeroshade in <a 
href="https://github.com/apache/arrow-go/pull/314";>#314</a></li>
-<li>refactor(arrow/array): replace some codegen with generics by @zeroshade in 
<a href="https://github.com/apache/arrow-go/pull/315";>#315</a></li>
-<li>feat(parquet/pqarrow): Add SeekToRow for RecordReader by @zeroshade in <a 
href="https://github.com/apache/arrow-go/pull/321";>#321</a></li>
-<li>fix: go's atomic operations require 64bit alignment in structs on ARM by 
@sahib in <a href="https://github.com/apache/arrow-go/pull/323";>#323</a></li>
-<li>feat(arrow/compute): implement &quot;is_in&quot; function by @zeroshade in 
<a href="https://github.com/apache/arrow-go/pull/319";>#319</a></li>
-<li>fix(parquet/pqarrow): fix propagation of FieldIds for nested fields by 
@zeroshade in <a 
href="https://github.com/apache/arrow-go/pull/324";>#324</a></li>
-<li>Fix: Handle null values in PlainFixedLenByteArrayEncoder gracefully by 
@singh1203 in <a 
href="https://github.com/apache/arrow-go/pull/320";>#320</a></li>
-<li>fix(parquet/pqarrow): fix definition levels with non-nullable lists by 
@zeroshade in <a 
href="https://github.com/apache/arrow-go/pull/325";>#325</a></li>
-<li>chore: fix macOS Go 1.24 CI by @lidavidm in <a 
href="https://github.com/apache/arrow-go/pull/334";>#334</a></li>
-<li>feat(parquet/metadata): bloom filter implementation by @zeroshade in <a 
href="https://github.com/apache/arrow-go/pull/336";>#336</a></li>
-<li>feat(parquet): Write/Read bloom filters from files by @zeroshade in <a 
href="https://github.com/apache/arrow-go/pull/341";>#341</a></li>
-<li>fix: move from atomic.(Add|Load|Store) to atomic.Int64{} by @sahib in <a 
href="https://github.com/apache/arrow-go/pull/326";>#326</a></li>
-<li>fix(parquet/file): restore goroutine safety for reader by @zeroshade in <a 
href="https://github.com/apache/arrow-go/pull/343";>#343</a></li>
-<li>chore: Enable GitHub discussions on arrow-go repository by @raulcd in <a 
href="https://github.com/apache/arrow-go/pull/353";>#353</a></li>
-<li>Compress: add MarshalText and UnmarshalText by @jdemeyer in <a 
href="https://github.com/apache/arrow-go/pull/357";>#357</a></li>
-<li>fix(arrow/array): optional struct array with required field by @zeroshade 
in <a href="https://github.com/apache/arrow-go/pull/359";>#359</a></li>
-<li>feat(parquet/schema): initial variant logical type by @zeroshade in <a 
href="https://github.com/apache/arrow-go/pull/352";>#352</a></li>
-<li>chore(arrow): remove most lock copies by @zeroshade in <a 
href="https://github.com/apache/arrow-go/pull/362";>#362</a></li>
-<li>Fix panic when WriteDataPage fails by @ashishnegi in <a 
href="https://github.com/apache/arrow-go/pull/366";>#366</a></li>
-<li>GH-46087: [FlightSQL] Allow returning column remarks in FlightSQL's 
CommandGetTables by @mateuszrzeszutek in <a 
href="https://github.com/apache/arrow-go/pull/361";>#361</a></li>
-</ul>
-<h3>New Contributors</h3>
-<ul>
-<li>@sahib made their first contribution in <a 
href="https://github.com/apache/arrow-go/pull/323";>#323</a></li>
-<li>@jdemeyer made their first contribution in <a 
href="https://github.com/apache/arrow-go/pull/357";>#357</a></li>
-<li>@ashishnegi made their first contribution in <a 
href="https://github.com/apache/arrow-go/pull/366";>#366</a></li>
-<li>@mateuszrzeszutek made their first contribution in <a 
href="https://github.com/apache/arrow-go/pull/361";>#361</a></li>
-</ul>
-<p><strong>Full Changelog</strong>: <a 
href="https://github.com/apache/arrow-go/compare/v18.2.0...v18.3.0";>https://github.com/apache/arrow-go/compare/v18.2.0...v18.3.0</a></p>]]></content><author><name>pmc</name></author><category
 term="release" /><summary type="html"><![CDATA[The Apache Arrow team is 
pleased to announce the v18.3.0 release of Apache Arrow Go. This minor release 
covers 21 commits from 8 distinct contributors. Contributors $ git shortlog -sn 
v18.2.0..v18.3.0 13 Matt Topol [...]
\ No newline at end of file
+<p><strong>Full Changelog</strong>: <a 
href="https://github.com/apache/arrow-java/commits/v18.3.0";>changelog</a></p>]]></content><author><name>pmc</name></author><category
 term="release" /><summary type="html"><![CDATA[The Apache Arrow team is 
pleased to announce the v18.3.0 release of Apache Arrow Java. This is a minor 
release since the last release v18.2.0. Changelog New Features and Enhancements 
MINOR: ZstdCompressionCodec should use decompressedSize to get error name by 
@libenchao in [...]
\ No newline at end of file
diff --git a/img/introducing-arrow-avro/arrow-avro-architecture.svg 
b/img/introducing-arrow-avro/arrow-avro-architecture.svg
new file mode 100644
index 00000000000..f1f8feb1653
--- /dev/null
+++ b/img/introducing-arrow-avro/arrow-avro-architecture.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg"; 
xmlns:xlink="http://www.w3.org/1999/xlink"; xmlns:lucid="lucid" width="1462" 
height="742"><g transform="translate(521 361)" lucid:page-tab-id="0_0"><path 
d="M-220-354a6 6 0 0 1 6-6h848a6 6 0 0 1 6 6v728a6 6 0 0 1-6 6h-848a6 6 0 0 
1-6-6z" stroke="#000" stroke-width="2" fill-opacity="0"/><path d="M110-314a6 6 
0 0 1 6-6h188a6 6 0 0 1 6 6v208a6 6 0 0 1-6 6H116a6 6 0 0 1-6-6z" stroke="#000" 
stroke-width="2" fill="#fff"/><use xlink:href="#a" transform="ma [...]
\ No newline at end of file
diff --git a/img/introducing-arrow-avro/read_violin_10k.svg 
b/img/introducing-arrow-avro/read_violin_10k.svg
new file mode 100644
index 00000000000..6e63143ddf5
--- /dev/null
+++ b/img/introducing-arrow-avro/read_violin_10k.svg
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg width="960" height="294" viewBox="0 0 960 294" 
xmlns="http://www.w3.org/2000/svg";>
+  <text x="480" y="5" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="16.129032258064516" opacity="1" 
fill="#000000" style="white-space: pre;">
+R/10K: Violin plot
+</text>
+  <text x="528" y="281" dy="-0.5ex" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+Average time (ms)
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="108,39 108,232 "/>
+  <text style="font-size: 10.0645px; font-weight: 700; text-anchor: end; 
white-space: pre;" x="99" y="220" dy="0.5ex" transform="matrix(1, 0, 0, 1, 
1.781357, -6.893451)"><tspan x="99" dy="1em">​</tspan>apache-avro/np/10K<tspan 
x="99" dy="1em">​</tspan></text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="103,220 108,220 "/>
+  <text style="font-size: 10.0645px; font-weight: 700; text-anchor: end; 
white-space: pre;" x="99" y="196" dy="0.5ex" transform="matrix(1, 0, 0, 1, 
1.565131, -6.823285)"><tspan x="99" dy="1em">​</tspan>arrow-avro/np/10K<tspan 
x="99" dy="1em">​</tspan></text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="103,196 108,196 "/>
+  <text style="font-size: 10.0645px; font-weight: 700; text-anchor: end; 
white-space: pre;" x="99" y="172" dy="0.5ex" transform="matrix(1, 0, 0, 1, 
2.263927, -6.230454)"><tspan x="99" dy="1em">​</tspan>apache-avro/f1/10K<tspan 
x="99" dy="1em">​</tspan></text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="103,172 108,172 "/>
+  <text style="font-size: 10.0645px; font-weight: 700; text-anchor: end; 
white-space: pre;" x="99" y="148" dy="0.5ex" transform="matrix(1, 0, 0, 1, 
0.532689, -6.343578)"><tspan x="99" dy="1em">​</tspan>arrow-avro/f1/10K<tspan 
x="99" dy="1em">​</tspan></text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="103,148 108,148 "/>
+  <text style="font-size: 10.1px; font-weight: 700; text-anchor: end; 
white-space: pre;" x="103.644" y="124.462" dy="0.5ex" transform="matrix(1, 0, 
0, 1, -2.03527, -7.556549)"><tspan x="103.64399719238281" 
dy="1em">​</tspan>apache-avro/p8/10K<tspan x="103.64399719238281" 
dy="1em">​</tspan></text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="103,124 108,124 "/>
+  <text style="font-size: 10.1px; font-weight: 700; text-anchor: end; 
white-space: pre;" x="103.859" y="99.717" dy="0.5ex" transform="matrix(1, 0, 0, 
1, -3.691591, -7.534968)"><tspan x="103.85900115966797" 
dy="1em">​</tspan>arrow-avro/p8/10K<tspan x="103.85900115966797" 
dy="1em">​</tspan></text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="103,100 108,100 "/>
+  <text style="font-size: 10.1px; font-weight: 700; text-anchor: end; 
white-space: pre;" x="105.131" y="76" dy="0.5ex" transform="matrix(1, 0, 0, 1, 
-4.725465, -6.99512)"><tspan x="105.13099670410156" 
dy="1em">​</tspan>apache-avro/f8/10K<tspan x="105.13099670410156" 
dy="1em">​</tspan></text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="103,76 108,76 "/>
+  <text style="font-size: 10.1px; font-weight: 700; text-anchor: end; 
white-space: pre;" x="102.216" y="52.331" dy="0.5ex" transform="matrix(1, 0, 0, 
1, -1.914529, -7.648093)"><tspan x="102.21600341796875" 
dy="1em">​</tspan>arrow-avro/f8/10K<tspan x="102.21600341796875" 
dy="1em">​</tspan></text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="103,52 108,52 "/>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="109,233 946,233 "/>
+  <text x="109" y="243" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+0.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="109,233 109,238 "/>
+  <text x="207" y="243" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+1.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="207,233 207,238 "/>
+  <text x="306" y="243" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+2.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="306,233 306,238 "/>
+  <text x="405" y="243" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+3.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="405,233 405,238 "/>
+  <text x="504" y="243" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+4.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="504,233 504,238 "/>
+  <text x="603" y="243" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+5.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="603,233 603,238 "/>
+  <text x="702" y="243" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+6.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="702,233 702,238 "/>
+  <text x="801" y="243" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+7.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="801,233 801,238 "/>
+  <text x="900" y="243" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+8.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="900,233 900,238 "/>
+  <polygon opacity="1" fill="#1F78B4" points="358,220 358,220 358,220 358,220 
358,220 358,220 358,220 359,220 359,220 359,220 359,220 359,220 359,220 359,220 
359,220 359,220 359,220 359,220 359,220 359,220 359,220 359,220 359,220 359,220 
359,220 359,220 360,220 360,220 360,220 360,220 360,220 360,220 360,220 360,220 
360,220 360,220 360,220 360,220 360,220 360,220 360,220 360,220 360,220 360,220 
360,220 361,220 361,220 361,220 361,220 361,220 361,220 361,220 361,220 361,220 
361,220 361,22 [...]
+  <polygon opacity="1" fill="#1F78B4" points="358,220 358,220 358,220 358,220 
358,220 358,220 358,220 359,220 359,220 359,220 359,220 359,220 359,220 359,220 
359,220 359,220 359,220 359,220 359,220 359,220 359,220 359,220 359,220 359,220 
359,220 359,221 360,221 360,221 360,221 360,221 360,221 360,221 360,221 360,221 
360,221 360,221 360,221 360,221 360,221 360,221 360,221 360,221 360,221 360,221 
360,221 361,221 361,221 361,221 361,221 361,221 361,221 361,221 361,221 361,221 
361,221 361,22 [...]
+  <polygon opacity="1" fill="#1F78B4" points="132,196 132,196 132,196 132,196 
132,196 132,196 132,196 132,196 132,196 132,196 132,196 132,196 132,196 132,196 
132,196 132,196 132,196 132,196 132,196 132,196 132,196 132,196 132,196 132,196 
132,196 132,196 132,196 132,196 132,196 132,196 132,196 132,196 132,196 132,196 
132,196 132,196 132,196 132,196 132,196 132,196 132,196 132,196 132,196 132,196 
132,196 132,196 132,196 132,196 132,196 132,196 132,196 132,196 132,196 132,196 
132,196 132,19 [...]
+  <polygon opacity="1" fill="#1F78B4" points="132,196 132,196 132,196 132,196 
132,196 132,196 132,196 132,196 132,196 132,196 132,196 132,196 132,196 132,196 
132,196 132,196 132,196 132,196 132,196 132,196 132,196 132,196 132,196 132,196 
132,196 132,196 132,196 132,196 132,196 132,196 132,196 132,196 132,196 132,196 
132,197 132,197 132,197 132,197 132,197 132,197 132,197 132,197 132,197 132,197 
132,197 132,197 132,197 132,197 132,197 132,197 132,197 132,197 132,197 132,197 
132,197 132,19 [...]
+  <polygon opacity="1" fill="#1F78B4" points="359,172 359,172 359,172 359,172 
359,172 359,172 359,172 359,172 360,172 360,172 360,172 360,172 360,172 360,172 
360,172 360,172 360,172 360,172 360,172 360,172 360,172 360,172 360,172 360,172 
361,172 361,172 361,172 361,172 361,172 361,172 361,172 361,172 361,172 361,172 
361,172 361,172 361,172 361,172 361,172 361,172 362,172 362,172 362,172 362,171 
362,171 362,171 362,171 362,171 362,171 362,171 362,171 362,171 362,171 362,171 
362,171 362,17 [...]
+  <polygon opacity="1" fill="#1F78B4" points="359,172 359,172 359,172 359,172 
359,172 359,172 359,172 359,172 360,172 360,172 360,172 360,172 360,172 360,172 
360,172 360,172 360,172 360,172 360,172 360,172 360,172 360,172 360,172 360,172 
361,172 361,172 361,172 361,172 361,172 361,172 361,172 361,172 361,173 361,173 
361,173 361,173 361,173 361,173 361,173 361,173 362,173 362,173 362,173 362,173 
362,173 362,173 362,173 362,173 362,173 362,173 362,173 362,173 362,173 362,173 
362,174 362,17 [...]
+  <polygon opacity="1" fill="#1F78B4" points="132,148 132,148 132,148 132,148 
132,148 132,148 132,148 132,148 132,148 132,148 132,148 132,148 132,148 132,148 
132,148 132,148 132,148 132,148 132,148 132,148 132,148 132,148 132,148 132,148 
132,148 132,148 132,148 132,148 132,148 132,148 132,148 132,148 132,148 132,148 
132,148 132,148 132,148 132,148 132,148 132,148 132,148 132,148 132,148 132,148 
132,148 132,148 132,148 132,148 132,148 132,148 132,148 132,148 132,148 132,147 
132,147 132,14 [...]
+  <polygon opacity="1" fill="#1F78B4" points="132,148 132,148 132,148 132,148 
132,148 132,148 132,148 132,148 132,148 132,148 132,148 132,148 132,148 132,148 
132,148 132,148 132,148 132,148 132,148 132,148 132,148 132,148 132,148 132,148 
132,148 132,148 132,148 132,148 132,148 132,148 132,148 132,148 132,148 132,148 
132,148 132,148 132,148 132,148 132,148 132,148 132,148 132,148 132,148 132,148 
132,148 132,148 132,148 132,148 132,149 132,149 132,149 132,149 132,149 132,149 
132,149 132,14 [...]
+  <polygon opacity="1" fill="#1F78B4" points="853,124 853,124 853,124 854,124 
854,124 854,124 854,124 854,124 854,124 855,124 855,124 855,124 855,124 855,124 
856,124 856,124 856,124 856,124 856,124 856,124 857,124 857,124 857,124 857,124 
857,124 858,124 858,124 858,124 858,124 858,124 859,124 859,124 859,124 859,124 
859,124 859,124 860,124 860,124 860,124 860,124 860,124 861,124 861,124 861,123 
861,123 861,123 861,123 862,123 862,123 862,123 862,123 862,123 863,123 863,123 
863,123 863,12 [...]
+  <polygon opacity="1" fill="#1F78B4" points="853,124 853,124 853,124 854,124 
854,124 854,124 854,124 854,124 854,124 855,124 855,124 855,124 855,124 855,124 
856,124 856,124 856,124 856,124 856,124 856,124 857,124 857,124 857,124 857,124 
857,124 858,124 858,124 858,124 858,124 858,124 859,124 859,124 859,124 859,124 
859,124 859,124 860,124 860,124 860,124 860,124 860,124 861,124 861,124 861,124 
861,124 861,124 861,124 862,124 862,125 862,125 862,125 862,125 863,125 863,125 
863,125 863,12 [...]
+  <polygon opacity="1" fill="#1F78B4" points="131,100 131,100 131,100 131,100 
131,100 131,100 131,100 131,100 131,100 131,100 131,100 131,100 131,100 131,100 
131,100 131,100 131,100 131,100 131,100 131,100 131,100 131,100 131,100 131,100 
131,100 131,100 131,100 131,100 131,100 131,100 131,100 131,100 131,100 131,100 
131,100 131,100 131,100 131,100 131,100 131,100 131,100 131,99 131,99 131,99 
131,99 131,99 131,99 131,99 131,99 131,99 131,99 131,99 131,99 131,99 131,99 
131,99 131,99 131,99 [...]
+  <polygon opacity="1" fill="#1F78B4" points="131,100 131,100 131,100 131,100 
131,100 131,100 131,100 131,100 131,100 131,100 131,100 131,100 131,100 131,100 
131,100 131,100 131,100 131,100 131,100 131,100 131,100 131,100 131,100 131,100 
131,100 131,100 131,100 131,100 131,100 131,100 131,100 131,100 131,100 131,100 
131,100 131,100 131,100 131,100 131,100 131,100 131,100 131,100 131,100 131,100 
131,100 131,100 131,100 131,100 131,100 131,100 131,100 131,100 131,100 131,100 
131,100 131,10 [...]
+  <polygon opacity="1" fill="#1F78B4" points="355,76 355,76 355,76 355,76 
355,76 355,76 355,76 355,76 355,76 355,76 355,76 355,76 355,76 355,76 356,76 
356,76 356,76 356,76 356,76 356,76 356,76 356,76 356,76 356,76 356,76 356,76 
356,76 356,76 356,76 356,76 356,76 356,76 356,76 356,76 356,76 357,76 357,76 
357,76 357,75 357,75 357,75 357,75 357,75 357,75 357,75 357,75 357,75 357,75 
357,75 357,75 357,75 357,75 357,75 357,75 357,75 357,75 358,75 358,75 358,75 
358,75 358,75 358,75 358,75 358,7 [...]
+  <polygon opacity="1" fill="#1F78B4" points="355,76 355,76 355,76 355,76 
355,76 355,76 355,76 355,76 355,76 355,76 355,76 355,76 355,76 355,76 356,76 
356,76 356,76 356,76 356,76 356,76 356,76 356,76 356,76 356,76 356,76 356,76 
356,76 356,76 356,76 356,76 356,76 356,76 356,76 356,76 356,76 357,76 357,76 
357,76 357,76 357,76 357,76 357,76 357,76 357,76 357,76 357,76 357,76 357,76 
357,76 357,76 357,76 357,76 357,76 357,76 357,76 357,76 358,76 358,76 358,76 
358,76 358,76 358,76 358,76 358,7 [...]
+  <polygon opacity="1" fill="#1F78B4" points="131,52 131,52 131,52 131,52 
131,52 131,52 131,52 131,52 131,52 131,52 131,51 131,51 131,51 131,51 131,51 
131,51 131,51 131,51 131,51 131,51 131,51 131,51 131,51 131,51 131,51 131,51 
131,51 131,51 131,51 131,51 131,51 131,51 131,51 131,51 131,51 131,51 131,51 
131,51 131,51 131,51 131,51 131,51 131,51 131,51 131,51 131,51 131,51 131,51 
131,51 131,51 131,51 131,51 131,51 131,51 131,51 131,51 131,51 131,50 131,50 
131,50 131,50 131,50 131,50 131,5 [...]
+  <polygon opacity="1" fill="#1F78B4" points="131,52 131,52 131,52 131,52 
131,52 131,52 131,52 131,52 131,52 131,52 131,52 131,52 131,52 131,52 131,52 
131,52 131,52 131,52 131,52 131,52 131,52 131,52 131,52 131,52 131,52 131,52 
131,52 131,52 131,52 131,52 131,52 131,52 131,52 131,52 131,52 131,52 131,52 
131,52 131,52 131,52 131,52 131,52 131,52 131,52 131,52 131,52 131,52 131,52 
131,52 131,52 131,52 131,52 131,52 131,52 131,52 131,53 131,53 131,53 131,53 
131,53 131,53 131,53 131,53 131,5 [...]
+</svg>
\ No newline at end of file
diff --git a/img/introducing-arrow-avro/read_violin_1m.svg 
b/img/introducing-arrow-avro/read_violin_1m.svg
new file mode 100644
index 00000000000..e536377239a
--- /dev/null
+++ b/img/introducing-arrow-avro/read_violin_1m.svg
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg width="960" height="294" viewBox="0 0 960 294" 
xmlns="http://www.w3.org/2000/svg";>
+  <text x="480" y="5" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="16.129032258064516" opacity="1" 
fill="#000000" style="white-space: pre;">
+R/1M: Violin plot
+</text>
+  <text x="528" y="281" dy="-0.5ex" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+Average time (ms)
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="108,39 108,232 "/>
+  <text style="font-size: 10.1px; font-weight: 700; text-anchor: end; 
white-space: pre;" x="104.868" y="220.23" dy="0.5ex" transform="matrix(1, 0, 0, 
1, -5.214254, -7.526795)"><tspan x="104.86799621582031" 
dy="1em">​</tspan>apache-avro/np/1M<tspan x="104.86799621582031" 
dy="1em">​</tspan></text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="103,220 108,220 "/>
+  <text style="font-size: 10.1px; font-weight: 700; text-anchor: end; 
white-space: pre;" x="103.068" y="196.209" dy="0.5ex" transform="matrix(1, 0, 
0, 1, -3.655307, -7.130969)"><tspan x="103.06800079345703" 
dy="1em">​</tspan>arrow-avro/np/1M<tspan x="103.06800079345703" 
dy="1em">​</tspan></text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="103,196 108,196 "/>
+  <text style="font-size: 10.1px; font-weight: 700; text-anchor: end; 
white-space: pre;" x="102.661" y="172.183" dy="0.5ex" transform="matrix(1, 0, 
0, 1, -2.367347, -6.89804)"><tspan x="102.66100311279297" 
dy="1em">​</tspan>apache-avro/f1/1M<tspan x="102.66100311279297" 
dy="1em">​</tspan></text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="103,172 108,172 "/>
+  <text style="font-size: 10.1px; font-weight: 700; text-anchor: end; 
white-space: pre;" x="103.534" y="148.106" dy="0.5ex" transform="matrix(1, 0, 
0, 1, -4.069402, -6.547885)"><tspan x="103.53399658203125" 
dy="1em">​</tspan>arrow-avro/f1/1M<tspan x="103.53399658203125" 
dy="1em">​</tspan></text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="103,148 108,148 "/>
+  <text style="font-size: 10.1px; font-weight: 700; text-anchor: end; 
white-space: pre;" x="104.286" y="124.244" dy="0.5ex" transform="matrix(1, 0, 
0, 1, -4.305376, -7.264941)"><tspan x="104.28600311279297" 
dy="1em">​</tspan>apache-avro/p8/1M<tspan x="104.28600311279297" 
dy="1em">​</tspan></text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="103,124 108,124 "/>
+  <text style="font-size: 10.1px; font-weight: 700; text-anchor: end; 
white-space: pre;" x="102.929" y="99.633" dy="0.5ex" transform="matrix(1, 0, 0, 
1, -3.624858, -6.596602)"><tspan x="102.92900085449219" 
dy="1em">​</tspan>arrow-avro/p8/1M<tspan x="102.92900085449219" 
dy="1em">​</tspan></text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="103,100 108,100 "/>
+  <text style="font-size: 10.1px; font-weight: 700; text-anchor: end; 
white-space: pre;" x="102.402" y="76.161" dy="0.5ex" transform="matrix(1, 0, 0, 
1, -3.836473, -7.281687)"><tspan x="102.4020004272461" 
dy="1em">​</tspan>apache-avro/f8/1M<tspan x="102.4020004272461" 
dy="1em">​</tspan></text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="103,76 108,76 "/>
+  <text style="font-size: 10.1px; font-weight: 700; text-anchor: end; 
white-space: pre;" x="102.521" y="52.218" dy="0.5ex" transform="matrix(1, 0, 0, 
1, -3.620291, -7.214701)"><tspan x="102.52100372314453" 
dy="1em">​</tspan>arrow-avro/f8/1M<tspan x="102.52100372314453" 
dy="1em">​</tspan></text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="103,52 108,52 "/>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="109,233 946,233 "/>
+  <text x="109" y="243" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+0.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="109,233 109,238 "/>
+  <text x="209" y="243" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+100.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="209,233 209,238 "/>
+  <text x="309" y="243" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+200.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="309,233 309,238 "/>
+  <text x="410" y="243" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+300.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="410,233 410,238 "/>
+  <text x="510" y="243" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+400.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="510,233 510,238 "/>
+  <text x="611" y="243" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+500.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="611,233 611,238 "/>
+  <text x="711" y="243" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+600.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="711,233 711,238 "/>
+  <text x="812" y="243" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+700.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="812,233 812,238 "/>
+  <text x="912" y="243" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+800.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="912,233 912,238 "/>
+  <polygon opacity="1" fill="#1F78B4" points="371,220 372,220 372,220 372,220 
372,220 372,220 372,220 372,220 372,220 372,220 372,220 372,220 372,220 372,220 
372,220 372,220 372,220 372,220 372,220 372,220 372,220 372,220 372,220 372,220 
372,220 372,220 372,220 372,220 372,220 372,220 372,220 372,220 372,220 372,220 
372,220 372,220 372,220 372,220 373,220 373,220 373,220 373,220 373,220 373,220 
373,220 373,220 373,220 373,220 373,220 373,220 373,220 373,220 373,220 373,220 
373,220 373,22 [...]
+  <polygon opacity="1" fill="#1F78B4" points="371,220 372,220 372,220 372,220 
372,220 372,220 372,220 372,220 372,220 372,220 372,220 372,220 372,220 372,220 
372,220 372,220 372,220 372,220 372,221 372,221 372,221 372,221 372,221 372,221 
372,221 372,221 372,221 372,221 372,221 372,221 372,221 372,221 372,221 372,221 
372,221 372,221 372,221 372,221 373,221 373,221 373,221 373,221 373,221 373,221 
373,221 373,221 373,221 373,221 373,221 373,221 373,221 373,221 373,221 373,221 
373,221 373,22 [...]
+  <polygon opacity="1" fill="#1F78B4" points="136,196 136,196 136,196 136,196 
136,196 136,196 136,196 136,196 136,196 136,196 136,196 136,196 136,196 136,196 
136,196 136,196 136,196 136,196 136,196 136,196 136,196 136,196 136,196 136,196 
136,196 136,196 136,196 136,196 136,196 136,196 136,196 136,196 136,196 136,196 
136,196 136,196 136,196 136,196 136,196 136,196 136,196 136,196 136,196 136,196 
136,196 136,196 136,196 136,196 136,196 136,196 136,196 136,195 136,195 136,195 
136,195 136,19 [...]
+  <polygon opacity="1" fill="#1F78B4" points="136,196 136,196 136,196 136,196 
136,196 136,196 136,196 136,196 136,196 136,196 136,196 136,196 136,196 136,196 
136,196 136,196 136,196 136,196 136,196 136,196 136,196 136,196 136,196 136,196 
136,197 136,197 136,197 136,197 136,197 136,197 136,197 136,197 136,197 136,197 
136,197 136,197 136,197 136,197 136,197 136,197 136,197 136,197 136,197 136,197 
136,197 136,197 136,197 136,197 136,197 136,197 136,197 136,197 136,197 136,197 
136,197 136,19 [...]
+  <polygon opacity="1" fill="#1F78B4" points="366,172 366,172 366,172 366,172 
366,172 366,172 366,172 366,172 366,172 366,172 366,172 366,172 366,172 366,172 
366,172 366,172 366,172 366,172 366,172 366,172 366,172 366,172 367,172 367,172 
367,172 367,172 367,172 367,172 367,172 367,172 367,172 367,172 367,172 367,172 
367,172 367,172 367,172 367,172 367,172 367,172 367,172 367,172 367,172 367,172 
367,172 367,172 367,172 367,172 367,172 367,172 367,172 367,172 368,172 368,172 
368,171 368,17 [...]
+  <polygon opacity="1" fill="#1F78B4" points="366,172 366,172 366,172 366,172 
366,172 366,172 366,172 366,172 366,172 366,172 366,172 366,172 366,172 366,172 
366,172 366,172 366,172 366,172 366,172 366,172 366,172 366,172 367,172 367,172 
367,172 367,172 367,172 367,172 367,172 367,172 367,172 367,172 367,172 367,172 
367,172 367,172 367,172 367,172 367,172 367,172 367,173 367,173 367,173 367,173 
367,173 367,173 367,173 367,173 367,173 367,173 367,173 367,173 368,173 368,173 
368,173 368,17 [...]
+  <polygon opacity="1" fill="#1F78B4" points="136,148 136,148 136,148 136,148 
136,148 136,148 136,148 136,148 136,148 136,148 136,148 136,148 136,148 136,148 
136,148 136,148 136,148 136,148 136,148 136,148 136,148 136,148 136,148 136,148 
136,148 136,148 136,148 136,148 136,148 136,148 136,148 136,148 136,148 136,148 
136,148 136,148 136,148 136,148 136,148 136,148 136,148 136,148 136,148 136,147 
136,147 136,147 136,147 136,147 136,147 136,147 136,147 136,147 136,147 136,147 
136,147 136,14 [...]
+  <polygon opacity="1" fill="#1F78B4" points="136,148 136,148 136,148 136,148 
136,148 136,148 136,148 136,148 136,148 136,148 136,148 136,148 136,148 136,148 
136,148 136,148 136,148 136,148 136,148 136,148 136,148 136,148 136,148 136,148 
136,148 136,148 136,148 136,148 136,148 136,148 136,148 136,148 136,148 136,148 
136,148 136,148 136,148 136,148 136,148 136,149 136,149 136,149 136,149 136,149 
136,149 136,149 136,149 136,149 136,149 136,149 136,149 136,149 136,149 136,149 
136,149 136,14 [...]
+  <polygon opacity="1" fill="#1F78B4" points="882,124 882,124 882,124 882,124 
882,124 882,124 883,124 883,124 883,124 883,124 883,124 883,124 883,124 883,124 
884,124 884,124 884,124 884,124 884,124 884,124 884,124 884,124 885,124 885,124 
885,124 885,124 885,124 885,124 885,124 885,124 886,124 886,124 886,124 886,124 
886,124 886,124 886,124 886,124 887,124 887,124 887,124 887,124 887,124 887,124 
887,124 887,124 888,124 888,124 888,124 888,124 888,124 888,123 888,123 889,123 
889,123 889,12 [...]
+  <polygon opacity="1" fill="#1F78B4" points="882,124 882,124 882,124 882,124 
882,124 882,124 883,124 883,124 883,124 883,124 883,124 883,124 883,124 883,124 
884,124 884,124 884,124 884,124 884,124 884,124 884,124 884,124 885,124 885,124 
885,124 885,124 885,124 885,124 885,124 885,124 886,124 886,124 886,124 886,124 
886,124 886,124 886,124 886,124 887,124 887,124 887,124 887,124 887,124 887,124 
887,124 887,124 888,124 888,124 888,124 888,124 888,124 888,124 888,124 889,124 
889,124 889,12 [...]
+  <polygon opacity="1" fill="#1F78B4" points="134,100 134,100 134,100 134,100 
134,100 134,100 134,100 134,100 134,100 134,100 134,100 134,100 134,100 134,100 
134,100 134,100 134,100 134,100 134,100 134,100 134,100 134,100 134,100 134,100 
134,100 134,100 134,100 134,100 134,100 134,100 134,99 134,99 134,99 134,99 
134,99 134,99 134,99 134,99 134,99 134,99 134,99 134,99 134,99 134,99 134,99 
134,99 134,99 134,99 134,99 134,99 134,99 134,99 134,99 134,99 134,99 134,99 
134,99 134,99 134,98 134 [...]
+  <polygon opacity="1" fill="#1F78B4" points="134,100 134,100 134,100 134,100 
134,100 134,100 134,100 134,100 134,100 134,100 134,100 134,100 134,100 134,100 
134,100 134,100 134,100 134,100 134,100 134,100 134,100 134,100 134,100 134,100 
134,100 134,100 134,100 134,100 134,100 134,100 134,100 134,100 134,100 134,100 
134,100 134,100 134,100 134,100 134,100 134,100 134,100 134,100 134,100 134,100 
134,100 134,101 134,101 134,101 134,101 134,101 134,101 134,101 134,101 134,101 
134,101 134,10 [...]
+  <polygon opacity="1" fill="#1F78B4" points="373,76 373,76 373,76 373,76 
373,76 373,76 373,76 373,76 373,76 373,76 373,76 373,76 373,76 373,76 373,76 
373,76 374,76 374,76 374,76 374,76 374,76 374,76 374,76 374,76 374,76 374,76 
374,76 374,76 374,76 374,76 374,76 374,76 374,76 374,76 374,76 374,76 374,76 
374,76 374,76 374,76 374,75 374,75 374,75 374,75 374,75 374,75 374,75 374,75 
374,75 374,75 374,75 374,75 374,75 374,75 374,75 374,75 374,75 374,75 374,75 
374,75 374,75 374,75 374,75 374,7 [...]
+  <polygon opacity="1" fill="#1F78B4" points="373,76 373,76 373,76 373,76 
373,76 373,76 373,76 373,76 373,76 373,76 373,76 373,76 373,76 373,76 373,76 
373,76 374,76 374,76 374,76 374,76 374,76 374,76 374,76 374,76 374,76 374,76 
374,76 374,76 374,76 374,76 374,76 374,76 374,76 374,76 374,76 374,76 374,76 
374,76 374,76 374,76 374,76 374,76 374,76 374,76 374,76 374,76 374,76 374,76 
374,76 374,76 374,76 374,76 374,76 374,76 374,76 374,76 374,76 374,76 374,76 
374,76 374,76 374,76 374,76 374,7 [...]
+  <polygon opacity="1" fill="#1F78B4" points="136,52 136,52 136,52 136,52 
136,52 136,52 136,52 136,52 136,52 136,52 136,52 136,51 136,51 136,51 136,51 
136,51 136,51 136,51 136,51 136,51 136,51 136,51 136,51 136,51 136,51 136,51 
136,51 136,51 136,51 136,51 136,51 136,51 136,51 136,51 136,51 136,51 136,51 
136,51 136,51 136,51 136,51 136,51 136,51 136,51 136,51 136,51 136,51 136,51 
136,51 136,51 136,51 136,51 136,51 136,51 136,51 136,51 136,51 136,51 136,51 
136,51 136,51 136,50 136,50 136,5 [...]
+  <polygon opacity="1" fill="#1F78B4" points="136,52 136,52 136,52 136,52 
136,52 136,52 136,52 136,52 136,52 136,52 136,52 136,52 136,52 136,52 136,52 
136,52 136,52 136,52 136,52 136,52 136,52 136,52 136,52 136,52 136,52 136,52 
136,52 136,52 136,52 136,52 136,52 136,52 136,52 136,52 136,52 136,52 136,52 
136,52 136,52 136,52 136,52 136,52 136,52 136,52 136,52 136,52 136,52 136,52 
136,52 136,52 136,52 136,52 136,52 136,52 136,52 136,52 136,52 136,52 136,53 
136,53 136,53 136,53 136,53 136,5 [...]
+</svg>
\ No newline at end of file
diff --git a/img/introducing-arrow-avro/write_violin_10k.svg 
b/img/introducing-arrow-avro/write_violin_10k.svg
new file mode 100644
index 00000000000..ac8acd06cf9
--- /dev/null
+++ b/img/introducing-arrow-avro/write_violin_10k.svg
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg width="960" height="222" viewBox="0 0 960 222" 
xmlns="http://www.w3.org/2000/svg";>
+  <text x="480" y="5" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="16.129032258064516" opacity="1" 
fill="#000000" style="white-space: pre;" transform="matrix(1, 0, 0, 1, 0, 
-1.163632)"><tspan x="480" dy="1em">​</tspan>W/10K: Violin plot<tspan x="480" 
dy="1em">​</tspan></text>
+  <text x="528" y="212" dy="-0.5ex" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+Average time (ms)
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="105,36 105,163 "/>
+  <text style="font-size: 10.0645px; font-weight: 700; text-anchor: end; 
white-space: pre;" x="96" y="148" dy="0.5ex" transform="matrix(1, 0, 0, 1, 
1.149304, -7.594823)"><tspan x="96" dy="1em">​</tspan>apache-avro/h/10K<tspan 
x="96" dy="1em">​</tspan></text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="100,148 105,148 "/>
+  <text style="font-size: 10.0645px; font-weight: 700; text-anchor: end; 
white-space: pre;" x="96" y="116" dy="0.5ex" transform="matrix(1, 0, 0, 1, 
0.75781, -7.240954)"><tspan x="96" dy="1em">​</tspan>arrow-avro/h/10K<tspan 
x="96" dy="1em">​</tspan></text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="100,116 105,116 "/>
+  <text style="font-size: 10.0645px; font-weight: 700; text-anchor: end; 
white-space: pre;" x="96" y="84" dy="0.5ex" transform="matrix(1, 0, 0, 1, 
1.209105, -7.29784)"><tspan x="96" dy="1em">​</tspan>apache-avro/c/10K<tspan 
x="96" dy="1em">​</tspan></text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="100,84 105,84 "/>
+  <text style="font-size: 10.0645px; font-weight: 700; text-anchor: end; 
white-space: pre;" x="96" y="52" dy="0.5ex" transform="matrix(1, 0, 0, 1, 
0.932029, -7.066851)"><tspan x="96" dy="1em">​</tspan>arrow-avro/c/10K<tspan 
x="96" dy="1em">​</tspan></text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="100,52 105,52 "/>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="106,164 949,164 "/>
+  <text x="106" y="174" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+0.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="106,164 106,169 "/>
+  <text x="192" y="174" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+0.5
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="192,164 192,169 "/>
+  <text x="279" y="174" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+1.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="279,164 279,169 "/>
+  <text x="366" y="174" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+1.5
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="366,164 366,169 "/>
+  <text x="453" y="174" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+2.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="453,164 453,169 "/>
+  <text x="539" y="174" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+2.5
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="539,164 539,169 "/>
+  <text x="626" y="174" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+3.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="626,164 626,169 "/>
+  <text x="713" y="174" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+3.5
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="713,164 713,169 "/>
+  <text x="800" y="174" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+4.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="800,164 800,169 "/>
+  <text x="886" y="174" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+4.5
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="886,164 886,169 "/>
+  <polygon opacity="1" fill="#1F78B4" points="241,148 241,148 241,148 241,148 
241,148 241,148 241,148 241,148 241,148 241,148 241,148 241,148 241,148 241,148 
241,148 241,148 241,148 242,148 242,148 242,148 242,148 242,148 242,148 242,148 
242,148 242,148 242,148 242,148 242,148 242,148 242,147 242,147 242,147 242,147 
242,147 242,147 242,147 242,147 242,147 242,147 242,147 242,147 242,147 242,147 
242,147 242,147 242,147 242,147 242,147 242,147 242,147 242,147 242,147 242,147 
242,147 242,14 [...]
+  <polygon opacity="1" fill="#1F78B4" points="241,148 241,148 241,148 241,148 
241,148 241,148 241,148 241,148 241,148 241,148 241,148 241,148 241,148 241,148 
241,148 241,148 241,148 242,148 242,148 242,148 242,148 242,148 242,148 242,148 
242,148 242,148 242,148 242,148 242,148 242,148 242,148 242,148 242,148 242,148 
242,148 242,148 242,148 242,148 242,148 242,148 242,148 242,148 242,148 242,148 
242,148 242,148 242,148 242,148 242,148 242,148 242,148 242,148 242,148 242,148 
242,148 242,14 [...]
+  <polygon opacity="1" fill="#1F78B4" points="150,116 150,116 150,116 150,116 
150,116 150,116 150,116 150,116 150,116 150,116 150,116 150,116 151,116 151,116 
151,116 151,116 151,116 151,116 151,116 151,116 151,116 151,116 151,116 151,116 
151,116 151,116 151,116 151,116 151,116 151,116 151,116 151,116 151,116 151,116 
151,116 151,116 151,116 151,116 151,116 151,116 151,116 151,116 151,116 151,116 
151,116 151,116 151,116 151,116 151,116 151,116 151,116 151,115 151,115 151,115 
151,115 151,11 [...]
+  <polygon opacity="1" fill="#1F78B4" points="150,116 150,116 150,116 150,116 
150,116 150,116 150,116 150,116 150,116 150,116 150,116 150,116 151,116 151,116 
151,116 151,116 151,116 151,116 151,116 151,116 151,116 151,116 151,116 151,116 
151,116 151,116 151,116 151,116 151,116 151,116 151,116 151,116 151,116 151,116 
151,116 151,116 151,116 151,116 151,116 151,116 151,116 151,116 151,116 151,116 
151,116 151,116 151,116 151,116 151,116 151,116 151,116 151,116 151,116 151,116 
151,116 151,11 [...]
+  <polygon opacity="1" fill="#1F78B4" points="920,84 920,84 920,84 920,84 
920,84 920,84 921,84 921,84 921,84 921,84 921,84 921,84 921,84 921,84 921,84 
921,84 921,84 921,84 921,84 921,84 921,84 921,84 921,84 921,84 922,84 922,84 
922,84 922,84 922,84 922,84 922,84 922,84 922,84 922,84 922,84 922,84 922,84 
922,84 922,84 922,84 922,84 922,84 923,84 923,84 923,84 923,84 923,83 923,83 
923,83 923,83 923,83 923,83 923,83 923,83 923,83 923,83 923,83 923,83 923,83 
924,83 924,83 924,83 924,83 924,8 [...]
+  <polygon opacity="1" fill="#1F78B4" points="920,84 920,84 920,84 920,84 
920,84 920,84 921,84 921,84 921,84 921,84 921,84 921,84 921,84 921,84 921,84 
921,84 921,84 921,84 921,84 921,84 921,84 921,84 921,84 921,84 922,84 922,84 
922,84 922,84 922,84 922,84 922,84 922,84 922,84 922,84 922,84 922,84 922,84 
922,85 922,85 922,85 922,85 922,85 923,85 923,85 923,85 923,85 923,85 923,85 
923,85 923,85 923,85 923,85 923,85 923,85 923,85 923,85 923,85 923,85 923,85 
924,85 924,85 924,85 924,85 924,8 [...]
+  <polygon opacity="1" fill="#1F78B4" points="149,52 149,52 149,52 149,52 
150,52 150,52 150,52 150,52 150,52 150,52 150,52 150,52 150,52 150,52 150,52 
150,52 150,52 150,52 150,52 150,52 150,52 150,52 150,52 150,52 150,52 150,52 
150,52 150,52 150,52 150,52 150,52 150,52 150,52 150,52 150,52 150,52 150,52 
150,52 150,52 150,52 150,52 150,52 150,52 150,52 150,52 150,52 150,52 150,52 
150,52 150,52 150,52 150,52 150,52 150,52 150,52 150,52 150,52 150,52 150,52 
150,52 150,52 150,52 150,52 151,5 [...]
+  <polygon opacity="1" fill="#1F78B4" points="149,52 149,52 149,52 149,52 
150,52 150,52 150,52 150,52 150,52 150,52 150,52 150,52 150,52 150,52 150,52 
150,52 150,52 150,52 150,52 150,52 150,52 150,52 150,52 150,52 150,52 150,52 
150,52 150,52 150,52 150,52 150,52 150,52 150,53 150,53 150,53 150,53 150,53 
150,53 150,53 150,53 150,53 150,53 150,53 150,53 150,53 150,53 150,53 150,53 
150,53 150,53 150,53 150,53 150,53 150,53 150,53 150,53 150,53 150,53 150,53 
150,53 150,53 150,53 150,53 151,5 [...]
+</svg>
\ No newline at end of file
diff --git a/img/introducing-arrow-avro/write_violin_1m.svg 
b/img/introducing-arrow-avro/write_violin_1m.svg
new file mode 100644
index 00000000000..6b895b5965d
--- /dev/null
+++ b/img/introducing-arrow-avro/write_violin_1m.svg
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg width="960" height="222" viewBox="0 0 960 222" 
xmlns="http://www.w3.org/2000/svg";>
+  <text x="480" y="5" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="16.129032258064516" opacity="1" 
fill="#000000" style="white-space: pre;">
+W/1M: Violin plot
+</text>
+  <text x="528" y="212" dy="-0.5ex" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+Average time (ms)
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="105,36 105,163 "/>
+  <text style="font-size: 10.0645px; font-weight: 700; text-anchor: end; 
white-space: pre;" x="96" y="148" dy="0.5ex" transform="matrix(1, 0, 0, 1, 
1.006252, -6.945251)"><tspan x="96" dy="1em">​</tspan>apache-avro/h/1M<tspan 
x="96" dy="1em">​</tspan></text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="100,148 105,148 "/>
+  <text style="font-size: 10.0645px; font-weight: 700; text-anchor: end; 
white-space: pre;" x="96" y="116" dy="0.5ex" transform="matrix(1, 0, 0, 1, 
0.389366, -6.730631)"><tspan x="96" dy="1em">​</tspan>arrow-avro/h/1M<tspan 
x="96" dy="1em">​</tspan></text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="100,116 105,116 "/>
+  <text style="font-size: 10.0645px; font-weight: 700; text-anchor: end; 
white-space: pre;" x="96" y="84" dy="0.5ex" transform="matrix(1, 0, 0, 1, 
0.198201, -6.720076)"><tspan x="96" dy="1em">​</tspan>apache-avro/c/1M<tspan 
x="96" dy="1em">​</tspan></text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="100,84 105,84 "/>
+  <text style="font-size: 10.0645px; font-weight: 700; text-anchor: end; 
white-space: pre;" x="96" y="52" dy="0.5ex" transform="matrix(1, 0, 0, 1, 0, 
-6.752914)"><tspan x="96" dy="1em">​</tspan>arrow-avro/c/1M<tspan x="96" 
dy="1em">​</tspan></text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="100,52 105,52 "/>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="106,164 949,164 "/>
+  <text x="106" y="174" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+0.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="106,164 106,169 "/>
+  <text x="188" y="174" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+50.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="188,164 188,169 "/>
+  <text x="270" y="174" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+100.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="270,164 270,169 "/>
+  <text x="352" y="174" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+150.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="352,164 352,169 "/>
+  <text x="434" y="174" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+200.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="434,164 434,169 "/>
+  <text x="516" y="174" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+250.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="516,164 516,169 "/>
+  <text x="598" y="174" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+300.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="598,164 598,169 "/>
+  <text x="680" y="174" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+350.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="680,164 680,169 "/>
+  <text x="762" y="174" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+400.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="762,164 762,169 "/>
+  <text x="844" y="174" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+450.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="844,164 844,169 "/>
+  <text x="926" y="174" dy="0.76em" text-anchor="middle" 
font-family="sans-serif" font-size="9.67741935483871" opacity="1" 
fill="#000000" style="white-space: pre;">
+500.0
+</text>
+  <polyline fill="none" opacity="1" stroke="#000000" stroke-width="1" 
points="926,164 926,169 "/>
+  <polygon opacity="1" fill="#1F78B4" points="239,148 239,148 239,148 239,148 
239,148 239,148 239,148 239,148 239,148 239,148 239,148 239,148 239,147 239,147 
239,147 239,147 239,147 239,147 239,147 239,147 239,147 239,147 239,147 239,147 
239,147 239,147 239,147 239,147 239,147 239,147 239,147 239,147 240,147 240,147 
240,147 240,147 240,147 240,147 240,147 240,147 240,147 240,147 240,147 240,146 
240,146 240,146 240,146 240,146 240,146 240,146 240,146 240,146 240,146 240,146 
240,146 240,14 [...]
+  <polygon opacity="1" fill="#1F78B4" points="239,148 239,148 239,148 239,148 
239,148 239,148 239,148 239,148 239,148 239,148 239,148 239,148 239,148 239,148 
239,148 239,148 239,148 239,148 239,148 239,148 239,148 239,148 239,148 239,148 
239,148 239,148 239,148 239,148 239,148 239,148 239,148 239,148 240,148 240,148 
240,148 240,148 240,148 240,148 240,148 240,149 240,149 240,149 240,149 240,149 
240,149 240,149 240,149 240,149 240,149 240,149 240,149 240,149 240,149 240,150 
240,150 240,15 [...]
+  <polygon opacity="1" fill="#1F78B4" points="162,116 162,116 162,116 162,116 
162,116 162,116 162,116 162,116 162,116 162,116 163,116 163,116 163,116 163,116 
163,116 163,116 163,116 163,116 163,116 163,116 163,116 163,116 163,116 163,116 
163,116 163,116 163,116 163,116 163,116 163,116 163,115 163,115 163,115 163,115 
163,115 163,115 163,115 163,115 163,115 163,115 163,115 163,115 163,115 163,115 
163,115 163,115 163,115 163,115 163,115 163,115 163,115 163,115 163,114 163,114 
163,114 163,11 [...]
+  <polygon opacity="1" fill="#1F78B4" points="162,116 162,116 162,116 162,116 
162,116 162,116 162,116 162,116 162,116 162,116 163,116 163,116 163,116 163,116 
163,116 163,116 163,116 163,116 163,116 163,116 163,116 163,116 163,116 163,116 
163,116 163,116 163,116 163,116 163,116 163,116 163,116 163,116 163,116 163,116 
163,116 163,116 163,116 163,116 163,117 163,117 163,117 163,117 163,117 163,117 
163,117 163,117 163,117 163,117 163,117 163,117 163,117 163,117 163,117 163,117 
163,117 163,11 [...]
+  <polygon opacity="1" fill="#1F78B4" points="877,84 877,84 878,84 878,84 
878,84 878,84 878,84 878,84 878,84 879,84 879,84 879,84 879,84 879,84 879,84 
879,84 880,84 880,84 880,84 880,84 880,84 880,84 880,84 881,84 881,84 881,84 
881,84 881,84 881,84 881,84 882,84 882,84 882,84 882,84 882,84 882,84 882,84 
883,83 883,83 883,83 883,83 883,83 883,83 883,83 884,83 884,83 884,83 884,83 
884,83 884,83 884,83 885,83 885,83 885,83 885,83 885,82 885,82 885,82 886,82 
886,82 886,82 886,82 886,82 886,8 [...]
+  <polygon opacity="1" fill="#1F78B4" points="877,84 877,84 878,84 878,84 
878,84 878,84 878,84 878,84 878,84 879,84 879,84 879,84 879,84 879,84 879,84 
879,84 880,84 880,84 880,84 880,84 880,84 880,84 880,84 881,84 881,84 881,84 
881,84 881,84 881,84 881,85 882,85 882,85 882,85 882,85 882,85 882,85 882,85 
883,85 883,85 883,85 883,85 883,85 883,85 883,85 884,85 884,85 884,85 884,85 
884,85 884,85 884,85 885,85 885,86 885,86 885,86 885,86 885,86 885,86 886,86 
886,86 886,86 886,86 886,86 886,8 [...]
+  <polygon opacity="1" fill="#1F78B4" points="164,52 164,52 164,52 164,52 
164,52 164,52 164,52 164,52 164,52 164,52 164,52 164,52 164,52 164,52 164,52 
164,52 164,52 164,52 164,52 164,52 164,52 164,52 164,52 164,52 164,52 164,52 
164,52 164,52 164,52 164,52 164,52 164,52 164,52 164,52 164,52 164,52 164,52 
164,52 164,52 164,52 164,52 164,52 164,52 164,52 164,52 164,52 164,52 164,52 
164,52 164,52 164,52 164,52 164,52 164,52 164,51 164,51 164,51 164,51 164,51 
164,51 164,51 164,51 165,51 165,5 [...]
+  <polygon opacity="1" fill="#1F78B4" points="164,52 164,52 164,52 164,52 
164,52 164,52 164,52 164,52 164,52 164,52 164,52 164,52 164,52 164,52 164,52 
164,52 164,52 164,52 164,52 164,52 164,52 164,52 164,52 164,52 164,53 164,53 
164,53 164,53 164,53 164,53 164,53 164,53 164,53 164,53 164,53 164,53 164,53 
164,53 164,53 164,53 164,53 164,53 164,53 164,53 164,53 164,53 164,53 164,53 
164,53 164,53 164,53 164,53 164,53 164,53 164,53 164,53 164,53 164,53 164,53 
164,54 164,54 164,54 165,54 165,5 [...]
+</svg>
\ No newline at end of file

Reply via email to