<!--
   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at
      http://www.apache.org/licenses/LICENSE-2.0
   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
   -->
<script>
  <!--#include virtual="../js/templateData.js" -->
</script>
<script id="streams-template" type="text/x-handlebars-template">
  <h1>Kafka Streams</h1>
       <div class="sub-nav-sticky">
          <div class="sticky-top">
             <div style="height:35px">
                <a  class="active-menu-item" href="/{{version}}/documentation/streams/">Introduction</a>
                <a href="/{{version}}/documentation/streams/quickstart">Run Demo App</a>
                <a href="/{{version}}/documentation/streams/tutorial">Tutorial: Write App</a>
                <a href="/{{version}}/documentation/streams/core-concepts">Concepts</a>
                <a href="/{{version}}/documentation/streams/architecture">Architecture</a>
                <a href="/{{version}}/documentation/streams/developer-guide/">Developer Guide</a>
                <a href="/{{version}}/documentation/streams/upgrade-guide">Upgrade</a>
            </div>
        </div>
    </div>
    <h3 class="streams_intro">The easiest way to write mission-critical real-time applications and microservices</h3>
       <p class="streams__description">Kafka Streams is a client library for building applications and microservices, where the input and output data are stored in Kafka clusters. It combines the simplicity of writing and deploying standard Java and Scala applications on the client side with the benefits of Kafka's server-side cluster technology.</p>
       <div class="video__series__grid">
          <div class="yt__video__block">
            <div class="yt__video__inner__block">
                <iframe  class="yt_series video_1 active" style="display:block" src="https://www.youtube.com/embed/ni3XPsYC5cQ?rel=0&showinfo=0&end=602" frameborder="0" allowfullscreen></iframe>
                <iframe  class="yt_series video_2" src="https://www.youtube.com/embed/9ZhsnXM2OVM?rel=0&showinfo=0&end=622" frameborder="0" allowfullscreen></iframe>
                <iframe  class="yt_series video_3" src="https://www.youtube.com/embed/SYmqwvE8umM?rel=0&showinfo=0end=557" frameborder="0" allowfullscreen></iframe>
                <iframe  class="yt_series video_4" src="https://www.youtube.com/embed/Vk55Kl9x_Fw?rel=0&showinfo=0&end=564" frameborder="0" allowfullscreen></iframe>
             </div>
            </div>
            <div class="video__block">
                <h3>TOUR OF THE STREAMS API</h3>
                <div class="video__list">
                   <p class="video__item video_list_1 active" onclick="$('.video__item').removeClass('active'); $(this).addClass('active');$('.yt_series').hide();$('.video_1').show();">
                       <span class="video-number">1</span><span class="video__text">Intro to Streams</span>
                   </p>
                   <p class="video__item video_list_2" onclick="$('.video__item').removeClass('active'); $(this).addClass('active');$('.yt_series').hide();$('.video_2').show();">
                       <span class="video-number">2</span><span class="video__text">Creating a Streams Application</span>
                   </p>
                   <p class="video__item video_list_3" onclick="$('.video__item').removeClass('active'); $(this).addClass('active');$('.yt_series').hide();$('.video_3').show();">
                       <span class="video-number">3</span><span class="video__text">Transforming Data Pt. 1</span>
                   </p>
                   <p class="video__item video_list_4" onclick="$('.video__item').removeClass('active'); $(this).addClass('active');$('.yt_series').hide();$('.video_4').show();">
                      <span class="video-number">4</span><span class="video__text">Transforming Data Pt. 11</span>
                   </p>
                </div>
            </div>
       </div>
       <hr class="separator"> 
       <div class="use-item-section">
           <div class="use__list__sec">
               <h3>Why you'll love using Kafka Streams!</h3>
               <ul class="use-feature-list">
                  <li>Elastic, highly scalable, fault-tolerant</li>
                  <li>Deploy to containers, VMs, bare metal, cloud</li>
                  <li>Equally viable for small, medium, &amp; large use cases</li>
                  <li>Fully integrated with Kafka security</li>
                  <li>Write standard Java applications</li>
                  <li>Exactly-once processing semantics</li>
                  <li>No separate processing cluster required</li>
                  <li>Develop on Mac, Linux, Windows</li>
                  
               </ul>
           </div>
           <div class="first__app__cta">
               <a href="/{{version}}/documentation/streams/tutorial" class="first__app__btn">Write your first app</a>
           </div>
       </div>
       <hr class="separator"> 
        <h3 class="stream__text">Streams API use cases</h3>
         <div class="customers__grid">
           <div class="customer__grid">
             <div class="customer__item streams_logo_grid streams__ny__grid">
               <a href="https://open.nytimes.com/publishing-with-apache-kafka-at-the-new-york-times-7f0e3b7d2077" target="_blank" class="grid__logo__link">
                 <span class="grid__item__logo" style="background-image: url('/images/powered-by/NYT.jpg');"></span>
               </a>
               <p class="grid__item__customer__description extra__space">
                 <a href="https://open.nytimes.com/publishing-with-apache-kafka-at-the-new-york-times-7f0e3b7d2077" target="_blank">The New York Times uses Apache Kafka </a>and the Kafka Streams API to store and distribute, in real-time, published content to the various applications and systems that make it available to the readers.
               </p>
             </div>
           </div>
           <div class="customer__grid">
             <div class="customer__item  streams_logo_grid streams__zalando__grid">
               <a href="https://www.confluent.io/blog/ranking-websites-real-time-apache-kafkas-streams-api/" target="_blank" class="grid__logo__link">
                 <span class="grid__item__logo" style="background-image: url('/images/powered-by/zalando.jpg');"></span>
               </a>
               <p class="grid__item__customer__description extra__space">As the leading online fashion retailer in Europe, Zalando uses Kafka as an ESB (Enterprise Service Bus), which helps us in transitioning from a monolithic to a micro services architecture. Using Kafka for processing
                 <a href="https://www.confluent.io/blog/ranking-websites-real-time-apache-kafkas-streams-api/" target='blank'> event streams</a> enables our technical team to do near-real time business intelligence.
               </p>
           </div>
           </div>  
           <div class="customer__grid">
             <div class="customer__item  streams_logo_grid streams__line__grid">
               <a href="https://engineering.linecorp.com/en/blog/detail/80" target="_blank" class="grid__logo__link">
                 <span class="grid__item__logo" style="background-image: url('/images/powered-by/line.svg');width:9rem"></span>
               </a>
                 <p class="grid__item__customer__description extra__space"><a href="https://engineering.linecorp.com/en/blog/detail/80" target="_blank">LINE uses Apache Kafka</a> as a central datahub for our services to communicate to one another. Hundreds of billions of messages are produced daily and are used to execute various business logic, threat detection, search indexing and data analysis. LINE leverages Kafka Streams to reliably transform and filter topics enabling sub topics consumers can efficiently consume, meanwhile retaining easy maintainability thanks to its sophisticated yet minimal code base.</p>
             </div>
           </div>
           <div class="customer__grid">
             <div class="customer__item streams_logo_grid streams__ny__grid">
               <a href="https://medium.com/@Pinterest_Engineering/using-kafka-streams-api-for-predictive-budgeting-9f58d206c996" target="_blank" class="grid__logo__link">
                 <span class="grid__item__logo" style="background-image: url('/images/powered-by/pinterest.png');"></span>
               </a>
               <p class="grid__item__customer__description">
                   <a href="https://medium.com/@Pinterest_Engineering/using-kafka-streams-api-for-predictive-budgeting-9f58d206c996" target="_blank">Pinterest uses Apache Kafka and the Kafka Streams API</a> at large scale to power the real-time, predictive budgeting system of their advertising infrastructure. With Kafka Streams, spend predictions are more accurate than ever.
               </p>
             </div>
           </div> 
           <div class="customer__grid">
             <div class="customer__item  streams_logo_grid streams__rabobank__grid">
               <a href="https://www.confluent.io/blog/real-time-financial-alerts-rabobank-apache-kafkas-streams-api/" target="_blank" class="grid__logo__link">
                 <span class="grid__item__logo" style="background-image: url('/images/powered-by/rabobank.jpg');"></span>
               </a>
                 <p class="grid__item__customer__description">Rabobank is one of the 3 largest banks in the Netherlands. Its digital nervous system, the Business Event Bus, is powered by Apache Kafka. It is used by an increasing amount of financial processes and services, one of which is Rabo Alerts. This service alerts customers in real-time upon financial events and is <a href="https://www.confluent.io/blog/real-time-financial-alerts-rabobank-apache-kafkas-streams-api/" target="_blank">built using Kafka Streams.</a></p>
             </div>
           </div>        
           <div class="customer__grid">
             <div class="customer__item streams_logo_grid streams__ny__grid">
               <a href="https://speakerdeck.com/xenji/kafka-and-debezium-at-trivago-code-dot-talks-2017-edition" target="_blank" class="grid__logo__link">
                 <span class="grid__item__logo" style="background-image: url('/images/powered-by/trivago.png');"></span>
               </a>
               <p class="grid__item__customer__description">
                   Trivago is a global hotel search platform. We are focused on reshaping the way travelers search for and compare hotels, while enabling hotel advertisers to grow their businesses by providing access to a broad audience of travelers via our websites and apps. As of 2017, we offer access to approximately 1.8 million hotels and other accommodations in over 190 countries. We use Kafka, Kafka Connect, and Kafka Streams to <a href="https://speakerdeck.com/xenji/kafka-and-debezium-at-trivago-code-dot-talks-2017-edition" target="_blank">enable our developers</a> to access data freely in the company. Kafka Streams powers parts of our analytics pipeline and delivers endless options to explore and operate on the data sources we have at hand.
               </p>
             </div>
           </div>  
         
       </div>
       <h3 style="margin-top: 5.3rem;">Hello Kafka Streams</h3>
       <p>The code example below implements a WordCount application that is elastic, highly scalable, fault-tolerant, stateful, and ready to run in production at large scale</p>
       
       <div class="code-example">
           <div class="btn-group">
               <a class="selected b-java-8" data-section="java-8">Java 8+</a>
               <a class="b-java-7" data-section="java-7">Java 7</a>
               <a class="b-scala" data-section="scala">Scala</a>
           </div>
       
           <div class="code-example__snippet b-java-8 selected">
               <pre class="line-numbers"><code class="language-java">                   import org.apache.kafka.common.serialization.Serdes;
                   import org.apache.kafka.common.utils.Bytes;
                   import org.apache.kafka.streams.KafkaStreams;
                   import org.apache.kafka.streams.StreamsBuilder;
                   import org.apache.kafka.streams.StreamsConfig;
                   import org.apache.kafka.streams.kstream.KStream;
                   import org.apache.kafka.streams.kstream.KTable;
                   import org.apache.kafka.streams.kstream.Materialized;
                   import org.apache.kafka.streams.kstream.Produced;
                   import org.apache.kafka.streams.state.KeyValueStore;

                   import java.util.Arrays;
                   import java.util.Properties;

                   public class WordCountApplication {

                       public static void main(final String[] args) throws Exception {
                           Properties config = new Properties();
                           config.put(StreamsConfig.APPLICATION_ID_CONFIG, "wordcount-application");
                           config.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, "kafka-broker1:9092");
                           config.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass());
                           config.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass());

                           StreamsBuilder builder = new StreamsBuilder();
                           KStream&lt;String, String&gt; textLines = builder.stream("TextLinesTopic");
                           KTable&lt;String, Long&gt; wordCounts = textLines
                               .flatMapValues(textLine -> Arrays.asList(textLine.toLowerCase().split("\\W+")))
                               .groupBy((key, word) -> word)
                               .count(Materialized.&lt;String, Long, KeyValueStore&lt;Bytes, byte[]&gt;&gt;as("counts-store"));
                           wordCounts.toStream().to("WordsWithCountsTopic", Produced.with(Serdes.String(), Serdes.Long()));

                           KafkaStreams streams = new KafkaStreams(builder.build(), config);
                           streams.start();
                       }

                   }
               </code></pre>
           </div>
       
           <div class="code-example__snippet b-java-7">
               <pre class="line-numbers"><code class="language-java">                   import org.apache.kafka.common.serialization.Serdes;
                   import org.apache.kafka.common.utils.Bytes;
                   import org.apache.kafka.streams.KafkaStreams;
                   import org.apache.kafka.streams.StreamsBuilder;
                   import org.apache.kafka.streams.StreamsConfig;
                   import org.apache.kafka.streams.kstream.KStream;
                   import org.apache.kafka.streams.kstream.KTable;
                   import org.apache.kafka.streams.kstream.ValueMapper;
                   import org.apache.kafka.streams.kstream.KeyValueMapper;
                   import org.apache.kafka.streams.kstream.Materialized;
                   import org.apache.kafka.streams.kstream.Produced;
                   import org.apache.kafka.streams.state.KeyValueStore;

                   import java.util.Arrays;
                   import java.util.Properties;
       
                   public class WordCountApplication {
       
                       public static void main(final String[] args) throws Exception {
                           Properties config = new Properties();
                           config.put(StreamsConfig.APPLICATION_ID_CONFIG, "wordcount-application");
                           config.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, "kafka-broker1:9092");
                           config.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass());
                           config.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass());
       
                           StreamsBuilder builder = new StreamsBuilder();
                           KStream&lt;String, String&gt; textLines = builder.stream("TextLinesTopic");
                           KTable&lt;String, Long&gt; wordCounts = textLines
                               .flatMapValues(new ValueMapper&lt;String, Iterable&lt;String&gt;&gt;() {
                                   @Override
                                   public Iterable&lt;String&gt; apply(String textLine) {
                                       return Arrays.asList(textLine.toLowerCase().split("\\W+"));
                                   }
                               })
                               .groupBy(new KeyValueMapper&lt;String, String, String&gt;() {
                                   @Override
                                   public String apply(String key, String word) {
                                       return word;
                                   }
                               })
                               .count(Materialized.&lt;String, Long, KeyValueStore&lt;Bytes, byte[]&gt;&gt;as("counts-store"));


                           wordCounts.toStream().to("WordsWithCountsTopic", Produced.with(Serdes.String(), Serdes.Long()));
       
                           KafkaStreams streams = new KafkaStreams(builder.build(), config);
                           streams.start();
                       }
       
                   }
               </code></pre>
           </div>
       
           <div class="code-example__snippet b-scala">
               <pre class="line-numbers"><code class="language-scala">                   import java.lang.Long
                   import java.util.Properties
                   import java.util.concurrent.TimeUnit

                   import org.apache.kafka.common.serialization._
                   import org.apache.kafka.common.utils.Bytes
                   import org.apache.kafka.streams._
                   import org.apache.kafka.streams.kstream.{KStream, KTable, Materialized, Produced}
                   import org.apache.kafka.streams.state.KeyValueStore

                   import scala.collection.JavaConverters.asJavaIterableConverter

                   object WordCountApplication {

                       def main(args: Array[String]) {
                           val config: Properties = {
                               val p = new Properties()
                               p.put(StreamsConfig.APPLICATION_ID_CONFIG, "wordcount-application")
                               p.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, "kafka-broker1:9092")
                               p.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass)
                               p.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass)
                               p
                           }

                           val builder: StreamsBuilder = new StreamsBuilder()
                           val textLines: KStream[String, String] = builder.stream("TextLinesTopic")
                           val wordCounts: KTable[String, Long] = textLines
                               .flatMapValues(textLine => textLine.toLowerCase.split("\\W+").toIterable.asJava)
                               .groupBy((_, word) => word)
                               .count(Materialized.as("counts-store").asInstanceOf[Materialized[String, Long, KeyValueStore[Bytes, Array[Byte]]]])
                           wordCounts.toStream().to("WordsWithCountsTopic", Produced.`with`(Serdes.String(), Serdes.Long()))

                           val streams: KafkaStreams = new KafkaStreams(builder.build(), config)
                           streams.start()

                           Runtime.getRuntime.addShutdownHook(new Thread(() => {
                               streams.close(10, TimeUnit.SECONDS)
                           }))
                       }

                   }
               </code></pre>
           </div>
       </div>
       
       <div class="pagination">
           <a href="/{{version}}/documentation" class="pagination__btn pagination__btn__prev">Previous</a>
           <a href="/{{version}}/documentation/streams/quickstart" class="pagination__btn pagination__btn__next">Next</a>
       </div>
     
</script>
<!--#include virtual="../../includes/_header.htm" -->
<!--#include virtual="../../includes/_top.htm" -->
<div class="content documentation documentation--current">
  <!--#include virtual="../../includes/_nav.htm" -->
  <div class="right">
    <!--#include virtual="../../includes/_docs_banner.htm" -->
    <ul class="breadcrumbs">
      <li><a href="/documentation">Documentation</a>
      </li>
    </ul>
    <div class="p-streams"></div>
  </div>
</div>
<!--#include virtual="../../includes/_footer.htm" -->
<script>
  $(function() {
         
         // Show selected style on nav item
         $('.b-nav__streams').addClass('selected');
    
         $('.video_list_1').click(function(){    
             $('.video_2').attr('src', $('.video_2').attr('src'));
             $('.video_3').attr('src', $('.video_3').attr('src'));
             $('.video_4').attr('src', $('.video_4').attr('src'));

           });

         $('.video_list_2').click(function(){    
               $('.video_1').attr('src', $('.video_1').attr('src'));
               $('.video_3').attr('src', $('.video_3').attr('src'));
               $('.video_4').attr('src', $('.video_4').attr('src'));

           });

         $('.video_list_3').click(function(){    
              $('.video_1').attr('src', $('.video_1').attr('src'));
              $('.video_2').attr('src', $('.video_2').attr('src'));
              $('.video_4').attr('src', $('.video_4').attr('src'));
           });

         $('.video_list_4').click(function(){    
              $('.video_1').attr('src', $('.video_1').attr('src'));
              $('.video_2').attr('src', $('.video_2').attr('src'));
              $('.video_3').attr('src', $('.video_3').attr('src'));
           });
           

          //sticky secondary nav
          var $navbar = $(".sub-nav-sticky"),
               y_pos = $navbar.offset().top,
               height = $navbar.height();
       
           $(window).scroll(function() {
               var scrollTop = $(window).scrollTop();
           
               if (scrollTop > y_pos - height) {
                   $navbar.addClass("navbar-fixed")
               } else if (scrollTop <= y_pos) {
                   $navbar.removeClass("navbar-fixed")
               }
           });
       
         // Display docs subnav items
         $('.b-nav__docs').parent().toggleClass('nav__item__with__subs--expanded');
         // Show selected code example
         $('.btn-group a').click(function(){
             var targetClass = '.b-' + $(this).data().section;
             $('.code-example__snippet, .btn-group a').removeClass('selected');
             $(targetClass).addClass('selected');
         });
       });
</script>